package com.uavps.framework.websocket;

import com.uavps.common.utils.spring.SpringUtils;
import com.uavps.common.utils.uuid.IdUtils;
import com.uavps.framework.udp.UdpClientService;
import com.uavps.framework.udp.UdpServerService;
import com.uavps.framework.udp.utils.UdpDataUtils;
import com.uavps.system.domain.UavpsAircraft;
import com.uavps.system.domain.UavpsAlgorithmParameter;
import com.uavps.system.service.IUavpsAircraftService;
import com.uavps.system.service.IUavpsAlgorithmParameterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * websocket 消息处理
 *
 * @author ruoyi
 */
@Component
@ServerEndpoint("/websocket/message")
public class WebSocketServer {
    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);

    UdpServerService udpServerService = new UdpServerService();

    UdpClientService udpClientService = new UdpClientService();

    private IUavpsAircraftService uavpsAircraftService = SpringUtils.getBean(IUavpsAircraftService.class);

    private IUavpsAlgorithmParameterService algorithmParameterService = SpringUtils.getBean(IUavpsAlgorithmParameterService.class);

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) throws Exception {
        log.info("\nWebSocket建立连接 - {}", session);
        closeUdpServer();

        //启动服务，接收算法返回的数据
        CompletableFuture.runAsync(() -> {
            udpServerService.receive(session);
        });

        //发送初始化参数给算法
        //String str = "BB 14 03 01 00 01 01 00 D2 57 05 08 B4 18 6D 2F 64 00 0A 00 14 00 0A 00 15 CD 5B 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 44 1B";
        //udpClientService.send(str);
    }

    /**
     * 连接关闭时处理
     */
    @OnClose
    public void onClose(Session session) {
        log.info("\nWebSocket关闭连接 - {}", session);
        closeUdpServer();
    }

    /**
     * 抛出异常时处理
     */
    @OnError
    public void onError(Session session, Throwable exception) throws Exception {
        log.info("\nWebSocket连接异常信息 - {}", exception);
        closeUdpServer();
    }

    /**
     * 服务器接收到客户端消息时调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        if (session != null) {
            try {
                if (message.startsWith("REPLAY:")) {
                    //重放，获取数据库轨迹数据
                    String bizId = message.substring(7);
                    List<UavpsAircraft> dataList = uavpsAircraftService.selectUavpsAircraftByBizId(bizId);
                    if (!CollectionUtils.isEmpty(dataList)) {
                        for (UavpsAircraft data : dataList) {
                            session.getBasicRemote().sendText(data.getAircraftData());
                            Thread.sleep(20);
                        }
                    }
                } else if (message.startsWith("RUN:")) {
                    String paramId = message.substring(4);
                    UavpsAlgorithmParameter param = algorithmParameterService.selectUavpsAlgorithmParameterById(Long.parseLong(paramId));
                    String parameter = UdpDataUtils.initAlgorithmParams(param);
                    System.out.println("parameter:====" + parameter);
                    System.out.println("param.toString():====" + param);
                    udpClientService.send(parameter);
                    /*String str = "BB14030101010100B6EA5F459C96C9172B0001000200030015CD5B070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A01B";
                    udpClientService.send(str);*/
                    UdpDataUtils.bizId = IdUtils.simpleUUID();
                } else if (message.startsWith("TRANSFORMATION:")) {
                    closeUdpServer();

                    String param = message.substring(15);
                    String[] paramAry = param.split(",");
                    UavpsAlgorithmParameter parameter = algorithmParameterService.selectUavpsAlgorithmParameterById(Long.parseLong(paramAry[0]));
                    if(!"null".equals(paramAry[1])){
                        parameter.setLongitude(new BigDecimal(paramAry[1]));
                    }
                    if(!"null".equals(paramAry[2])){
                        parameter.setLatitude(new BigDecimal(paramAry[2]));
                    }
                    if(!"null".equals(paramAry[3])){
                        parameter.setAltitude(Long.parseLong(paramAry[3]));
                    }
                    String transParam = UdpDataUtils.initAlgorithmParams(parameter);
                    System.out.println("transParam:====" + transParam);
                    System.out.println("param.toString():====" + parameter);
                    udpClientService.send(transParam);
                    this.onOpen(session);
                    //String str = "BB14030101010100B6EA5F459C96C9172B0001000200030015CD5B070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A01B";
                } else {
                    session.getBasicRemote().sendText(message);
                }
            } catch (IOException | InterruptedException e) {
                log.error("\nWebSocket发送消息异常: ", e);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            log.info("\n用户未登录！");
        }
    }

    private void closeUdpServer() {
        try {
            DatagramSocket socket = new DatagramSocket();
            //封装数据
            byte[] data = "EXIT".getBytes();
            DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 9099);

            //发送数据
            socket.send(packet);
            UdpDataUtils.bizId = "";
            UdpDataUtils.time = 0;
        } catch (IOException e) {
            log.error("\n关闭UDP服务异常: ", e);
        }
    }
}
