package com.imdroid.beidou.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.imdroid.secapi.client.RtcmClient;
import com.imdroid.secapi.dto.*;
import com.imdroid.secapi.utils.HexUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;

@Controller
public class APIController extends BasicController{
    SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
    @Autowired
    RtcmClient rtcmClient;
    @Autowired
    GnssDeviceMapper deviceMapper;
    @Autowired
    GnssGroupMapper groupMapper;
    @Autowired
    GnssGroupCalcMapper groupCalcMapper;
    @Autowired
    GnssMsgMapper msgMapper;
    @Autowired
    GnssStatusMapper gnssStatusMapper;
    @Autowired
    DeviceCacheCmdMapper cacheCmdMapper;

    /****** config ack *******/
    @PostMapping(value = "/api/config_ack")
    @ResponseBody
    public String onConfigAck(String deviceId, Integer tenantId, String configAck) {
        GnssDevice device = deviceMapper.queryByDeviceId(deviceId);
        if(device == null) return null;

        int msgType = Integer.parseInt(configAck.substring(0,4),16);
        // 配置是否成功
        if(msgType == 0xd311){
            //最后一个字节为1表示配置成功，0表示配置失败
            if(configAck.endsWith("01")){
                device.setSyn(true);
                deviceMapper.updateById(device);
            }
        }

        // 保存
        saveMsg(deviceId, tenantId,msgType, configAck, false);

        // 命令行显示
        String rxInfo = "RX "+ dateFormat.format(System.currentTimeMillis())+
                " "+deviceId+" ";
        if(msgType == 0xd31a){
            //转成字符串
            String dtuAck = configAck.substring(9*2);
            rxInfo += configAck+"("+HexUtil.HexString2String(dtuAck)+")";
        }
        else{
            rxInfo += configAck;
        }

        WebSocketServer.sendMessageToAll(rxInfo);
        return null;
    }

    /****** device active *******/
    @PostMapping(value = "/api/device_online")
    @ResponseBody
    public String onLine(String deviceId, Integer tenantId, LocalDateTime lastOnlineTime) {
        onDeviceActive(deviceId,tenantId);

        // 检查是否自动补传
        GnssDevice device = deviceMapper.queryByDeviceId(deviceId);
        if(device == null) return null;
        GnssGroupCalc groupCalc = groupCalcMapper.selectById(device.getCalc_group_id());
        if(groupCalc==null || !groupCalc.getAuto_upload()) return null;

        // 检查上次是否离线，如果是则启动补传
        LocalDateTime now = LocalDateTime.now();
        Short len = 15;
        String uploadCmd = "D312" + HexUtil.Short2HexString(len) +
                HexUtil.Int2HexString(Integer.parseInt(deviceId)) +
                "0F"
                + HexUtil.Byte2HexString((byte) (lastOnlineTime.getYear() - 2000))
                + HexUtil.Byte2HexString((byte) (lastOnlineTime.getMonthValue()))
                + HexUtil.Byte2HexString((byte) (lastOnlineTime.getDayOfMonth()))
                + HexUtil.Byte2HexString((byte) (lastOnlineTime.getHour()))
                + HexUtil.Byte2HexString((byte) (lastOnlineTime.getMinute()))
                + HexUtil.Byte2HexString((byte) (now.getYear() - 2000))
                + HexUtil.Byte2HexString((byte) (now.getMonthValue()))
                + HexUtil.Byte2HexString((byte) (now.getDayOfMonth()))
                + HexUtil.Byte2HexString((byte) (now.getHour()))
                + HexUtil.Byte2HexString((byte) (now.getMinute()));
        rtcmClient.config(deviceId, uploadCmd);
        // 保存
        saveMsg(deviceId, tenantId,0xD312, uploadCmd, true);

        return null;
    }

    /****** device active *******/
    @PostMapping(value = "/api/device_active")
    @ResponseBody
    public String onDeviceActive(String deviceId, Integer tenantId) {

        // 检查有没有待配置的参数
        GnssDevice device = deviceMapper.queryByDeviceId(deviceId);
        if(device!=null && !device.getSyn()){
            GnssGroup gnssGroup = groupMapper.selectById(device.getGroup_id());
            if(gnssGroup != null){
                String config = gnssGroup.getConfigCmd(device);
                if(config != null){
                    rtcmClient.config(deviceId, config);
                    // 保存
                    saveMsg(deviceId, tenantId,0xd311, config, true);
                }
            }
        }

        // 检查有没有待发送的指令
        QueryWrapper<DeviceCacheCmd> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deviceid",deviceId);
        queryWrapper.eq("syn",false);
        DeviceCacheCmd cacheCmd = cacheCmdMapper.selectOne(queryWrapper);
        if(cacheCmd != null){
            rtcmClient.config(deviceId, cacheCmd.getCmd());
            cacheCmd.setSyn(true);
            cacheCmd.setUpdatetime(LocalDateTime.now());
            cacheCmdMapper.updateById(cacheCmd);
            // 保存
            saveMsg(deviceId, tenantId,cacheCmd.getMsgtype(), cacheCmd.getCmd(), true);
        }

        return null;
    }

    /****** device stop *******/
    @PostMapping(value = "/api/device_stop")
    @ResponseBody
    public String onDeviceStop(String deviceId, Integer tenantId) {

        return null;
    }

    /****** gnss upload *******/
    @PostMapping(value = "/api/gnss_upload")
    @ResponseBody
    public String onGnssUpload(String deviceId, Integer tenantId,LocalDateTime uploadTime,String info) {
        saveMsg(deviceId, tenantId,0xd342,
                "gnss data upload from "+uploadTime+", "+info,false);
        return null;
    }

    @PostMapping(value = "/api/gnss_upload_pause")
    @ResponseBody
    public String onGnssUploadPause(String deviceId, Integer tenantId) {
        saveMsg(deviceId, tenantId,0xd342, "gnss data upload pause",false);
        return null;
    }

    @PostMapping(value = "/api/gnss_upload_complete")
    @ResponseBody
    public String onGnssUploadComplete(String deviceId, Integer tenantId, LocalDateTime uploadTime) {
        saveMsg(deviceId, tenantId,0xd342, "gnss data upload completely at "+uploadTime,false);
        return null;
    }

    void saveMsg(String deviceId, int tenantId, int msgType, String content,boolean isTx){
        GnssMsg gnssMsg = new GnssMsg();
        gnssMsg.setCreatetime(LocalDateTime.now());
        gnssMsg.setTenantid(tenantId);
        gnssMsg.setDeviceid(deviceId);
        gnssMsg.setMsgtype(msgType);
        gnssMsg.setTx(isTx);
        if(content==null) content="";
        gnssMsg.setMsglen(content.length()/2);
        int saveContentLen = content.length();
        if(saveContentLen<=128)
            gnssMsg.setContent(content);
        else
            gnssMsg.setContent(content.substring(0,128));
        msgMapper.insert(gnssMsg);
    }

}
