package com.ltgk.boat.service.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.ltgk.boat.config.websocket.WebSocketSessionMap;
import com.ltgk.boat.domain.entity.TrackSolrEntity;
import com.ltgk.boat.domain.vo.RadarWakeVo;
import com.ltgk.boat.service.ITrackWebsocketService;
import com.ltgk.common.common.SolrCommon;
import com.ltgk.common.constant.CacheConstants;
import com.ltgk.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 轨迹接续实现
 *
 * @author Qi ChengBin
 * @date 2025/10/27
 */
@Slf4j
@Service
public class TrackWebsocketServiceImpl implements ITrackWebsocketService {

    private final Map<String, WebSocketSession> webSocketSessionMap = new WebSocketSessionMap().sharedMap();

    @Override
    public void saveWebsocketSession(WebSocketSession session) {
        if (!this.webSocketSessionMap.containsKey(session.getId())) {
            // 将 session 存储起来，要不发送时，不知道给谁发
            this.webSocketSessionMap.put(session.getId(), session);
        }
        // 连接成功后直接给前端推送一次数据
        if (session.isOpen()) {
            // 组装告警数据和疑似三无船只数据用来推送给前端
            this.pushTrackData(session);
        }
    }

    @Override
    public void pushTrackData(WebSocketSession session) {
        Map<String, List<RadarWakeVo>> radarWakeVoMap = getTrackSolrMap();
        try {
            session.sendMessage(
                    new TextMessage(JSONUtil.toJsonStr(radarWakeVoMap)));
        } catch (IOException e) {
            log.error(">>>>>>轨迹接续 websocket 连接成功后推送数据失败！:::" + e.getMessage());
        }

    }

    /**
     * 从solr 中获取相关的数据
     *
     * @return java.util.Map<java.lang.String, java.util.List < com.ltgk.boat.domain.vo.RadarWakeVo>>
     * @author Qi ChengBin
     * @date 2025/10/27
     */
    private static Map<String, List<RadarWakeVo>> getTrackSolrMap() {
        // 使用当前时间查询轨迹数据
        String nowStr = DateUtil.formatDate(new Date());

        // 直接查询solr的轨迹数据   从solr 中查询2h内的轨迹数据
        Criteria criteria = new Criteria("track_id")
                .and("t_iso")
                // 查询24H内的数据
                .between(DateUtils.toDate(DateUtil.offsetMinute(new Date(), -1440).toString()), DateUtils.toDate(nowStr));
        SimpleQuery query = new SimpleQuery(criteria);
        query.addSort(Sort.by(Sort.Direction.DESC, "t_iso"));
        query.setRows(100000);
        Page page = SolrCommon.solrSearchByQuery(CacheConstants.track, query, TrackSolrEntity.class);

        // key 为 目标id   value 为 尾迹的数据
        List<RadarWakeVo> radarWakeVoList = new ArrayList<>();
        for (Object item : page.getContent()) {
            TrackSolrEntity trackSolrEntity = (TrackSolrEntity) item;
            RadarWakeVo radarWakeVo = new RadarWakeVo();
            radarWakeVo.setLatitude(trackSolrEntity.getLat())
                    .setLongitude(trackSolrEntity.getLon())
                    .setTime(trackSolrEntity.getT_iso())
                    .setTargetSourceId(trackSolrEntity.getTrack_id())
            ;
            radarWakeVoList.add(radarWakeVo);
        }


        // 将数据转换成Map 并且根据定位时间倒叙排列
        return radarWakeVoList.stream()
                .collect(Collectors.groupingBy(RadarWakeVo::getTargetSourceId));
    }

    // 定时推送轨迹接续数据
    @Scheduled(cron = "0/30 * * * * ?")
    public void sendTwinBoatDynamic() {
        Map<String, List<RadarWakeVo>> radarWakeVoMap = getTrackSolrMap();
        this.webSocketSessionMap.forEach((key, value) -> {
            if (value.isOpen()) {
                try {
                    value.sendMessage(
                            new TextMessage(JSONUtil.toJsonStr(radarWakeVoMap)));
                } catch (IOException e) {
                    log.error(">>>>>>轨迹接续图层数据及其尾迹数据 websocket 定时推送失败！:::" + e.getMessage());
                }
            }
        });
    }
}
