package com.junmp.jyzb.websocket;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.junmp.iot.server.ws.WebSocketServerListener;
import com.junmp.iot.server.ws.impl.DefaultWebSocketServerMessage;
import com.junmp.iot.server.ws.impl.DefaultWebSocketServerProtocol;
import com.junmp.jyzb.api.util.WsCabinetReq;
import com.junmp.jyzb.cache.OnlineRedisCache;
import com.junmp.jyzb.entity.Cabinet;
import com.junmp.jyzb.entity.CabinetBox;
import com.junmp.jyzb.entity.Temp.OnlineState;
import com.junmp.jyzb.service.CabinetBoxService;
import com.junmp.jyzb.service.CabinetService;
import com.junmp.jyzb.service.impl.CabinetServiceImpl;
import com.junmp.jyzb.utils.DateTimeUtil;
import com.junmp.v2.ws.api.enums.ClientMsgType;
import com.junmp.v2.ws.api.enums.ServerMsgType;
import com.junmp.v2.ws.api.enums.SysMsgTypeEnum;
import com.junmp.v2.ws.api.message.WsCallbackApi;
import com.junmp.v2.ws.api.session.bean.WsSession;
import com.junmp.v2.ws.bean.WsMsgDto;
import com.junmp.v2.ws.channel.WsSessionContainer;
import com.junmp.v2.ws.message.WsMessageHandle;
import com.junmp.v2.ws.session.WsSessionHandle;
import io.jsonwebtoken.JwtException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Component
@Slf4j
public class CabinetWebSocketServer implements WebSocketServerListener {
     @Resource
     public CabinetService cabinetService;
     @Resource
     public CabinetBoxService cabinetBoxService;
    @Override
    public String uri() {
        return "/cabinet/ws";
    }

    @SneakyThrows
    @Override
    public void onText(DefaultWebSocketServerProtocol protocol) {
        try {


        String text = protocol.readText();
        ObjectMapper objectMapper = new ObjectMapper();
        WsCabinetReq boxData = objectMapper.readValue(text, WsCabinetReq.class);

        String channel=  protocol.requestMessage().getChannelId();
        Cabinet cabinet=cabinetService.getOne(new LambdaQueryWrapper<Cabinet>()
                .eq(Cabinet::getCabinetNum, boxData.getSerialNum()));
        List<WsCabinetReq.Box> boxStateList=boxData.getBoxList();
        List<CabinetBox> boxlist=cabinetBoxService.list(new LambdaQueryWrapper<CabinetBox>()
                        .eq(CabinetBox::getCabinetId, cabinet.getId()));

        // 将 boxlist 转换为 Map，以 boxNum 为键
        Map<Integer, CabinetBox> boxMap = boxlist.stream()
                .collect(Collectors.toMap(CabinetBox::getNum, box -> box));
        List<CabinetBox> updateBoxlist=new ArrayList<>();
        // 比较并修改
        for (WsCabinetReq.Box boxState : boxStateList) {
            Integer boxNum = Integer.valueOf(boxState.getBoxNum());
            CabinetBox cabinetBox = boxMap.get(boxNum);

            if (cabinetBox != null) {
                // 根据 boxState 中的 state 字段修改 cabinetBox 中的状态
                cabinetBox.setState(boxState.getState());
                cabinetBox.setErrorMsg(boxState.getErrorMsg());
                updateBoxlist.add(cabinetBox);
                // 可以选择更新其他字段
                // cabinetBox.setOtherField(...);
            }
        }

        cabinet.setOnlineState(1);
        cabinet.setUpdateTime(DateTimeUtil.getCurrentDateTime());
        cabinet.setChannelId(channel);
        cabinetService.updateById(cabinet);
        cabinetBoxService.updateBatchById(updateBoxlist);
        protocol.response("true");
        }
        catch (Exception e)
        {
            protocol.response("false");
        }
    }

    @Override
    public void onClose(DefaultWebSocketServerProtocol protocol) {

       String channel= protocol.requestMessage().getChannelId();
        Cabinet cabinet=cabinetService.getOne(new LambdaQueryWrapper<Cabinet>()
                .eq(Cabinet::getChannelId, channel));
        cabinet.setOnlineState(0);
        cabinet.setChannelId("");
        cabinet.setUpdateTime(DateTimeUtil.getCurrentDateTime());
        cabinetService.updateById(cabinet);
        WebSocketServerListener.super.onClose(protocol);
    }

    @Override
    public void onBinary(DefaultWebSocketServerProtocol protocol) {
        WebSocketServerListener.super.onBinary(protocol);
    }
}