package com.dcs.hnyz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dcs.common.enums.GeneralStatus;
import com.dcs.common.exception.CustomException;
import com.dcs.hnyz.domain.Equipment;
import com.dcs.hnyz.domain.EquipmentParam;
import com.dcs.hnyz.domain.vo.EquipmentFormVO;
import com.dcs.hnyz.enums.DeviceTypeEnum;
import com.dcs.hnyz.mapper.EquipmentMapper;
import com.dcs.hnyz.service.IEquipmentParamService;
import com.dcs.hnyz.service.IEquipmentService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.dcs.equipment.constants.ModbusConstants.*;

/**
 * 设备管理Service业务层处理
 * 
 * @author hmy
 * @date 2025-04-22
 */
@Service
public class EquipmentServiceImpl implements IEquipmentService 
{
    @Resource
    private EquipmentMapper equipmentMapper;

    @Resource
    private FlowServiceImpl flowService;

    @Resource
    private CommunicationProtocolServiceImpl communicationProtocolService;

    @Resource
    private PlcInfoServiceImpl plcInfoService;

    @Resource
    private IEquipmentParamService equipmentParamService;

    /**
     * 查询设备管理
     * 
     * @param equipmentId 设备管理主键
     * @return 设备管理
     */
    @Override
    public Equipment selectEquipmentByEquipmentId(Long equipmentId)
    {
        return equipmentMapper.selectById(equipmentId);
    }

    /**
     * 查询设备管理列表
     * 
     * @param equipment 设备管理
     * @return 设备管理
     */
    @Override
    public List<Equipment> selectEquipmentList(Equipment equipment)
    {
        return equipmentMapper.selectEquipmentList(equipment);
    }

    @Override
    public List<EquipmentFormVO> selectEquipmentForm(Equipment equipment) {
        List<EquipmentFormVO> list = equipmentMapper.selectEquipmentForm(equipment);

        for (EquipmentFormVO equipmentFormVo : list) {
            //获取plc名称
            if (equipmentFormVo.getPlcId() != null) {
                equipmentFormVo.setPlcName(plcInfoService.selectPlcNameByPlcId(equipmentFormVo.getPlcId()));
            }
            //获取通信协议名称
            if (equipmentFormVo.getProtocolId() != null) {
                equipmentFormVo.setProtocolName(communicationProtocolService.selectProtocolNameByProtocolId(equipmentFormVo.getProtocolId()));
            }
            //处理flowName数据
            String flowIdStr = equipmentFormVo.getFlowIds(); // "1,2"
            if (flowIdStr != null && !flowIdStr.isEmpty()) {
                String[] flowIds = flowIdStr.split(","); // ["1", "2"]
                List<String> flowNames = new ArrayList<>();
                for (String flowId : flowIds) {
                    //通过flowId获取flowName
                    flowNames.add(flowService.selectFlowNameByFlowId(Long.valueOf(flowId)));
                }
                // 设备名拼接
                equipmentFormVo.setFlowName(String.join(",", flowNames));
            }
        }
        return list;
    }

    /**
     * 新增设备管理
     * 
     * @param equipment 设备管理
     * @return 结果
     */
    @Override
    public int insertEquipment(Equipment equipment)
    {
        LambdaQueryWrapper<Equipment> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Equipment::getCode,equipment.getCode());
        Equipment d= equipmentMapper.selectOne(wrapper);
        if(d!=null){
            throw new CustomException("设备标识已存在");
        }
        return equipmentMapper.insert(equipment);
    }

    /**
     * 修改设备管理
     * 
     * @param equipment 设备管理
     * @return 结果
     */
    @Override
    public int updateEquipment(Equipment equipment)
    {
        LambdaQueryWrapper<Equipment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Equipment::getCode,equipment.getCode());
        wrapper.ne(Equipment::getEquipmentId,equipment.getEquipmentId());
        Equipment d = equipmentMapper.selectOne(wrapper);
        if(d!=null){
            throw new CustomException("设备标识已存在");
        }
//        return equipmentMapper.updateEquipment(equipment);
        return equipmentMapper.updateById(equipment);
    }

    @Override
    public int updateEquipmentByPlcId(Long plcId){
        return equipmentMapper.updateEquipmentByPlcId(plcId);
    }

    /**
     * 批量删除设备管理
     * 
     * @param equipmentIds 需要删除的设备管理主键
     * @return 结果
     */
    @Override
    public int deleteEquipmentByEquipmentIds(Long[] equipmentIds)
    {
        return equipmentMapper.deleteBatchIds(Arrays.asList(equipmentIds));
    }

    /**
     * 删除设备管理信息
     * 
     * @param equipmentId 设备管理主键
     * @return 结果
     */
    @Override
    public int deleteEquipmentByEquipmentId(Long equipmentId)
    {
        return equipmentMapper.deleteById(equipmentId);
    }

    @Override
    public List<Map<String, Object>> getEquipmentNameList(String dataType) {
        List<String> dataTypes = new ArrayList<>();//数据类型
        switch (dataType) {
            case "bool"://布尔型
                dataTypes.add(COIL_DATA_TYPE);
                break;
            case "data"://浮点型和整型
                dataTypes= Arrays.asList(INT_DATA_TYPE,FLOAT_DATA_TYPE);
                break;
            default:
                throw new CustomException("该数据类型暂无处理");
        }
        List<EquipmentParam> paramList=equipmentParamService.selectEquipmentParamListByDataType(dataTypes);
        //获取设备列表
        LambdaQueryWrapper<Equipment> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Equipment::getStatus, GeneralStatus.ENABLE.getCode());
        List<Equipment> equipmentList = equipmentMapper.selectList(wrapper);
//        System.out.println("树状list"+buildRegisterTree(paramList, equipmentList));
        return buildRegisterTree(paramList, equipmentList);
    }

    @Override
    public List<Map<String, Object>> getEquipmentSensorTree() {
        List<String> dataTypes = Arrays.asList(INT_DATA_TYPE,FLOAT_DATA_TYPE);//浮点型和整型
        List<EquipmentParam> paramList=equipmentParamService.selectEquipmentParamListByDataType(dataTypes);
        //获取设备列表
        LambdaQueryWrapper<Equipment> wrapper=new LambdaQueryWrapper<>();
        wrapper.in(Equipment::getEquipmentType, DeviceTypeEnum.SENSOR.getCode(),DeviceTypeEnum.TANK.getCode());
        wrapper.eq(Equipment::getStatus, GeneralStatus.ENABLE.getCode());
        List<Equipment> equipmentList = equipmentMapper.selectList(wrapper);
        return buildRegisterTree(paramList, equipmentList);
    }

    /**
     * 构建设备名树状list
     * @param paramList
     * @param equipmentList
     * @return
     */
    public List<Map<String, Object>> buildRegisterTree(List<EquipmentParam> paramList, List<Equipment> equipmentList) {
        // 1. 构建设备 id -> 设备 映射
        Map<Long, Equipment> equipmentMap = equipmentList.stream()
                .collect(Collectors.toMap(Equipment::getEquipmentId, e -> e));

        // 2. 创建每个寄存器节点
        List<Map<String, Object>> leafNodes = new ArrayList<>();
        for (EquipmentParam param : paramList) {
            Map<String, Object> leaf = new LinkedHashMap<>();
            leaf.put("label", param.getRegisterName());
            leaf.put("value", param.getCode());

            Long equipmentId = param.getEquipmentId(); // 顶层设备
            Long relationId = param.getRelationId();   // 上级设备

            // 3. 构建一条从寄存器向上的链条
            Map<String, Object> child = leaf;
            if (relationId != null && !relationId.equals(equipmentId)) {
                Equipment mid = equipmentMap.get(relationId);
                if (mid != null) {
                    Map<String, Object> midNode = new LinkedHashMap<>();
                    midNode.put("label", mid.getEquipmentName());
                    midNode.put("value", mid.getCode());
                    midNode.put("children", Collections.singletonList(child));
                    child = midNode;
                }
            }

            Equipment top = equipmentMap.get(equipmentId);
            if (top != null) {
                Map<String, Object> topNode = new LinkedHashMap<>();
                topNode.put("label", top.getEquipmentName());
                topNode.put("value", top.getCode());
                topNode.put("children", Collections.singletonList(child));
                leafNodes.add(topNode);
            }
        }

        // 4. 合并同一个 top 节点
        return mergeTree(leafNodes);
    }

    public List<Map<String, Object>> mergeTree(List<Map<String, Object>> nodes) {
        Map<String, Map<String, Object>> map = new LinkedHashMap<>();

        for (Map<String, Object> node : nodes) {
            String key = (String) node.get("value");
            if (map.containsKey(key)) {
                // 合并 children
                List<Map<String, Object>> existingChildren = new ArrayList<>(
                        (List<Map<String, Object>>) map.get(key).get("children")
                );
                List<Map<String, Object>> newChildren = (List<Map<String, Object>>) node.get("children");

                existingChildren.addAll(newChildren);

                map.get(key).put("children", mergeTree(existingChildren));

            } else {
                map.put(key, node);
            }
        }

        return new ArrayList<>(map.values());
    }


}
