package com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.ws.xlw;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cico.nest.lcdp.boot.core.qxsd.domain.gateway.VehicleGateway;
import com.cico.nest.lcdp.boot.core.qxsd.domain.vehicle.TunnelRealTimeVehicle;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.constatnt.XlwConstants;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.result.XlwResultData;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.convertor.VehicleConvertor;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.http.xlw.XlwAuthMapper;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.ws.xlw.dto.XlwRealTimeVehicleDTO;
import jakarta.annotation.Resource;
import jakarta.websocket.WebSocketContainer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.tomcat.websocket.WsWebSocketContainer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.net.URI;
import java.util.List;

/**
 * 对接 信路威 车辆实时信息 websocket 客户端
 * @author zws
 * @date 2024/8/8
 */
@Component
@Slf4j
public class RealTimeVehicleWsClient  {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private XlwAuthMapper xlwAuthMapper;
    @Resource
    private VehicleGateway vehicleGateway;

    public void connectAndHandleMessage(String url,String tunnelId,String direction,int startMilestone) throws Exception {
        WebSocketContainer container = new WsWebSocketContainer();
        // 设置二进制消息缓冲区大小（以字节为单位）
        container.setDefaultMaxBinaryMessageBufferSize(5120000);
        // 设置文本消息缓冲区大小（以字节为单位）
        container.setDefaultMaxTextMessageBufferSize(5120000);
        // 设置会话空闲超时时间（以毫秒为单位）
        container.setDefaultMaxSessionIdleTimeout(2 * 60000L);


        StandardWebSocketClient client = new StandardWebSocketClient(container);

        TextWebSocketHandler handler = new TextWebSocketHandler() {
            @Override
            public void handleTextMessage(WebSocketSession session, TextMessage message) {
                try{
                    //处理从服务器接收到的消息
//                    log.info("detailTunnelId:{},接收到的车辆实时数据：{}" ,tunnelId, message.getPayload());
                    if(StrUtil.isBlank(message.getPayload())){
                        return;
                    }
                    XlwResultData<JSONObject> xlwResultData = JSONObject.parseObject(message.getPayload(), XlwResultData.class);
                    XlwRealTimeVehicleDTO xlwRealTimeVehicleDTO = JSONObject.parseObject(xlwResultData.getData().toString(), XlwRealTimeVehicleDTO.class);
                    /*********************************************************************************/
                    //todo 测试事件和车辆交集 从redis中获取key的值，往List<CarInfo>中添加数据 让车辆一直保留在隧道中
                    String redisKey = "VehicleWs:addCarInfo";
                    String vehicleJson = stringRedisTemplate.opsForValue().get(redisKey);
                    List<XlwRealTimeVehicleDTO.CarInfo> carInfoList = JSONArray.parseArray(vehicleJson, XlwRealTimeVehicleDTO.CarInfo.class);
                    if(CollectionUtils.isNotEmpty(carInfoList)){
                        log.info("测试事件和车辆交集,原:{}条",xlwRealTimeVehicleDTO.getCarInfo().size());
                        log.info("从redis中获取:{},的值，往List<CarInfo>中添加数据 让车辆一直保留在隧道中,插入{}条数据",redisKey,carInfoList.size());
                        xlwRealTimeVehicleDTO.getCarInfo().addAll(carInfoList);
                        log.info("测试事件和车辆交集,操作后:{}条",xlwRealTimeVehicleDTO.getCarInfo().size());
                    }
                    /*********************************************************************************/
                    TunnelRealTimeVehicle tunnelRealTimeVehicle = VehicleConvertor.convert2TunnelRTV(xlwRealTimeVehicleDTO,tunnelId,direction,startMilestone);
                    vehicleGateway.pushRealTimeVehicleData(tunnelRealTimeVehicle,tunnelId);
                }catch (Exception e){
                    log.error("处理实时数据失败:",e);
                }
            }

            @Override
            public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
                log.error("WebSocket session closed with error: {}", status.getReason());
                //重连
                connectAndHandleMessage(url,tunnelId,direction,startMilestone);
            }

            @Override
            public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
                log.error("websocket出现错误：",exception);
            }

        };
        WebSocketHttpHeaders webSocketHttpHeaders = new WebSocketHttpHeaders();
        webSocketHttpHeaders.add(XlwConstants.AUTH_HEADER,xlwAuthMapper.getXlwLoginToken());
        client.execute(handler, webSocketHttpHeaders, new URI(url));
    }
}
