package com.dcs.equipment.task;

import com.alibaba.fastjson2.JSON;
import com.dcs.dcs.domain.vo.DcsEquipmentFormVo;
import com.dcs.dcs.service.IDcsEquipmentService;
import com.dcs.equipment.domain.ModbusRequest;
import com.dcs.equipment.domain.ModbusResponse;
import com.dcs.equipment.server.EquipmentListWebSocketServer;
import com.dcs.equipment.server.EquipmentTreeWebSocketServer;
import com.dcs.equipment.service.InfluxDBService;
import com.dcs.equipment.service.ModbusTcpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;

import static com.dcs.equipment.constants.ModbusConstants.*;
import static com.dcs.equipment.domain.ModbusTcpEnum.DATA_ADDRESS_LENGTH_MAP;
import static com.dcs.equipment.utils.ModbusUtil.getValues;

/**
 * @author: wangpx
 * @date: 2025-03-06 16:45
 */
@Component("ModbusTcpTask")
public class ModbusTcpTask {
    @Resource
    private EquipmentListWebSocketServer equipmentListWebSocketServer;
    @Resource
    private EquipmentTreeWebSocketServer equipmentTreeWebSocketServer;
    @Autowired
    private IDcsEquipmentService dcsEquipmentService;
    @Autowired
    private ModbusTcpService modbusTcpService;
    @Autowired
    private InfluxDBService influxDBService;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private ScheduledExecutorService scheduledExecutorService;

    // 保存modbus请求信息
    public static List<ModbusRequest> modbusRequestList;
    // 保存设备寄存器信息和数据地址
    public static List<DcsEquipmentFormVo> equipmentFormVoList;

    @PostConstruct
    private void init() {
        modbusTcpService.updateEquipmentCodes();
    }
    // 广播的设备消息数据
    private static List<DcsEquipmentFormVo> broadCastEquipmentFormVoList = new ArrayList<>();

    public static List<DcsEquipmentFormVo> getBroadCastEquipmentFormVoList() {
        return broadCastEquipmentFormVoList;
    }

    // 保存数据到influxdb
    private void saveDataToInfluxdb(List<DcsEquipmentFormVo> equipmentFormVoList) {
        System.out.println("save shanghai_dcs_bucket");
        CompletableFuture.runAsync(() -> {
            influxDBService.saveDataToInfluxDB("shanghai_dcs_bucket", equipmentFormVoList);
//            influxDBService.saveDataToInfluxDB("mybucket", equipmentFormVoList);
        }, scheduledExecutorService);
    }

    private void updateDataToEquipmentFormVoList() {
        // modbus请求次数
        int requestNum = modbusRequestList.size();
        // 保存modbus响应信息
        Map<String, List<ModbusResponse>> modbusResponseMap = new HashMap<>();
        modbusResponseMap.put(COIL_FUNCTION_CODE, new ArrayList<>());
        modbusResponseMap.put(INPUT_FUNCTION_CODE, new ArrayList<>());
        modbusResponseMap.put(HOLDING_FUNCTION_CODE, new ArrayList<>());
        CompletableFuture<Void>[] futures = new CompletableFuture[requestNum];
        for (int i = 0; i < requestNum; i++) {
            int finalI = i;
            try {
                futures[finalI] = CompletableFuture.runAsync(() -> {
                    ModbusRequest modbusRequest = modbusRequestList.get(finalI);
                    List<Object> list = new ArrayList<>();
                    // 响应数据
                    ModbusResponse response = new ModbusResponse();
                    response.setSlaveId(modbusRequest.getSlaveId());
                    response.setFunctionCode(modbusRequest.getFunctionCode());
                    response.setDataType(modbusRequest.getDataType());
                    response.setStartAddress(modbusRequest.getStartAddress());
                    response.setQuantity(modbusRequest.getQuantity());
                    try {
                        list = getValues(modbusRequest);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    response.setData(list);
                    modbusResponseMap.get(modbusRequest.getFunctionCode()).add(response);
                }, scheduledExecutorService);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            CompletableFuture.allOf(futures).get();  // 等待所有任务完成
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 拷贝设备信息
        List<DcsEquipmentFormVo> deepCopyEquipmentFormVoList = new ArrayList<>();
        for (DcsEquipmentFormVo equipmentFormVo : equipmentFormVoList) {
            deepCopyEquipmentFormVoList.add(equipmentFormVo.clone());
        }
        // 装填设备数据
        for (DcsEquipmentFormVo equipmentFormVo : deepCopyEquipmentFormVoList) {
            String registerCode = equipmentFormVo.getRegisterCode();
            Integer address = equipmentFormVo.getAddress();
            if (registerCode == null) continue; // 跳过没有功能码的设备
            for (ModbusResponse modbusResponse : modbusResponseMap.get(registerCode)) {
                // 跳过不匹配的数据类型
                if (!equipmentFormVo.getDataType().equals(modbusResponse.getDataType())) continue;
                int startAddress = modbusResponse.getStartAddress();
                int quantity = modbusResponse.getQuantity();
                int dataLength = DATA_ADDRESS_LENGTH_MAP.get(modbusResponse.getDataType());
                // 跳过不在当前地址范围内的响应数据
                if (address < startAddress || address > startAddress + (quantity * dataLength)) continue;
                int index = (address - startAddress) / dataLength;
//                List<Object> data = modbusResponse.getData();
                Object o = modbusResponse.getData().get(index);
                equipmentFormVo.setValue(o);
                break;
            }
        }
        broadCastEquipmentFormVoList = deepCopyEquipmentFormVoList;
        saveDataToInfluxdb(deepCopyEquipmentFormVoList);
    }

//    private List<EquipmentFormVo> getEquipmentFormVoTree(List<EquipmentFormVo> equipmentFormVoList) {
//        return dcsEquipmentService.buildTree(equipmentFormVoList);
//    }

    // 保存并广播设备数据消息
    public void saveAndBroadcastEquipmentData() {
//        long startTime = System.nanoTime();
//        updateDataToEquipmentFormVoList();
        // 广播列表设备数据
        equipmentListWebSocketServer.broadCastInfo(JSON.toJSONString(broadCastEquipmentFormVoList));
//        long endTime = System.nanoTime();
//        long duration = endTime - startTime; // 纳秒
//        System.out.println("运行时间: " + duration + " 纳秒");
    }

    public void broacastEquipmentTree() {
//        long startTime = System.nanoTime();
        // 拷贝设备信息
        List<DcsEquipmentFormVo> deepCopyEquipmentFormVoList = new ArrayList<>();
        for (DcsEquipmentFormVo equipmentFormVo : broadCastEquipmentFormVoList) {
            deepCopyEquipmentFormVoList.add(equipmentFormVo.clone());
        }
        List<DcsEquipmentFormVo> equipmentFormVoTree = dcsEquipmentService.buildTree(deepCopyEquipmentFormVoList);
        equipmentTreeWebSocketServer.broadCastInfo(JSON.toJSONString(equipmentFormVoTree));
//        long endTime = System.nanoTime();
//        long duration = endTime - startTime; // 纳秒
//        System.out.println("运行时间: " + duration + " 纳秒");

    }


}
