package com.dcs.hnyz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dcs.common.enums.GeneralStatus;
import com.dcs.common.exception.CustomException;
import com.dcs.equipment.task.ModbusTcpTask;
import com.dcs.hnyz.domain.Equipment;
import com.dcs.hnyz.domain.EquipmentParam;
import com.dcs.hnyz.domain.vo.EquipmentParamFormVO;
import com.dcs.hnyz.enums.DeviceTypeEnum;
import com.dcs.hnyz.enums.RegisterTypeEnum;
import com.dcs.hnyz.mapper.EquipmentParamMapper;
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.framework.datasource.DynamicDataSourceContextHolder.log;

/**
 * 设备参数管理Service业务层处理
 *
 * @author hmy
 * @date 2025-04-23
 */
@Service
public class EquipmentParamServiceImpl implements IEquipmentParamService {
    @Resource
    private EquipmentParamMapper equipmentParamMapper;

    @Resource
    private IEquipmentService equipmentService;

    //设备id-->寄存器唯一code，用于配置
//    private Map<Integer,String> registerCodeMap = new HashMap<>();

    /**
     * 查询设备参数管理
     *
     * @param registerId 设备参数管理主键
     * @return 设备参数管理
     */
    @Override
    public EquipmentParam selectEquipmentParamByRegisterId(Long registerId) {
        return equipmentParamMapper.selectById(registerId);
    }

    /**
     * 查询设备参数管理列表
     *
     * @param equipmentParam 设备参数管理
     * @return 设备参数管理
     */
    @Override
    public List<EquipmentParam> selectEquipmentParamList(EquipmentParam equipmentParam) {
        return equipmentParamMapper.selectEquipmentParamList(equipmentParam);
    }

    /**
     * 新增设备参数管理
     *
     * @param equipmentParam 设备参数管理
     * @return 结果
     */
    @Override
    public int insertEquipmentParam(EquipmentParam equipmentParam) {
        LambdaQueryWrapper<EquipmentParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EquipmentParam::getCode, equipmentParam.getCode());
        EquipmentParam ep = equipmentParamMapper.selectOne(wrapper);
        if (ep != null) {
            throw new CustomException("该寄存器标识已存在");
        }
        return equipmentParamMapper.insert(equipmentParam);
    }

    /**
     * 修改设备参数管理
     *
     * @param equipmentParam 设备参数管理
     * @return 结果
     */
    @Override
    public int updateEquipmentParam(EquipmentParam equipmentParam) {
        LambdaQueryWrapper<EquipmentParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EquipmentParam::getCode, equipmentParam.getCode());
        wrapper.ne(EquipmentParam::getEquipmentId, equipmentParam.getEquipmentId());
        EquipmentParam ep = equipmentParamMapper.selectOne(wrapper);
        if (ep != null) {
            throw new CustomException("该寄存器标识已存在");
        }
        return equipmentParamMapper.updateById(equipmentParam);
    }

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

    /**
     * 删除设备参数管理信息
     *
     * @param registerId 设备参数管理主键
     * @return 结果
     */
    @Override
    public int deleteEquipmentParamByRegisterId(Long registerId) {
        return equipmentParamMapper.deleteById(registerId);
    }

    @Override
    public List<EquipmentParamFormVO> selectEquipmentParamForm(EquipmentParam equipmentParam) {
        return equipmentParamMapper.selectEquipmentParamForm(equipmentParam);
    }

    // TODO 改ID获取为识别码获取 保存到缓存 equipmentParamList变更才更新缓存
    @Override
    public Map<Integer, Integer> getEquipmentIndexList() {
        Map<Integer, Integer> swappedMap = new HashMap<>();
        List<EquipmentParam> equipmentFormVoList = ModbusTcpTask.equipmentParamList;
        for (int i = 0; i < equipmentFormVoList.size(); i++) {
            swappedMap.put(Math.toIntExact(equipmentFormVoList.get(i).getRegisterId()), i);
        }
        return swappedMap;
    }

    // TODO 根据设备id获取对应的主数据所在寄存器的唯一code（暂时只处理了传感器和阀门相关）
    @Override
    public String getCodeByParentId(Long parentId) {
        if(parentId == null) {
            log.warn("parentId is null");
            return null;
        }
        Equipment e = equipmentService.selectEquipmentByEquipmentId(parentId);
        if (e == null) {
            log.warn("根据 parentId:{} 没有查询到设备信息", parentId);
            return null;
        }
        DeviceTypeEnum type = DeviceTypeEnum.fromCode(e.getEquipmentType());
        LambdaQueryWrapper<EquipmentParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EquipmentParam::getRelationId, parentId);
        switch (type) {
            case SENSOR:
            case VALVE_WITH_FEEDBACK:
                // 处理有反馈阀门逻辑
                // 处理传感器逻辑
                wrapper.eq(EquipmentParam::getParamType, RegisterTypeEnum.MASTER_DATA.getCode());
                break;
            case VALVE_NO_FEEDBACK:
                // 处理无反馈阀门逻辑(用控制信号来代替反馈信号)
                wrapper.eq(EquipmentParam::getParamType, RegisterTypeEnum.MASTER_SET.getCode());
                break;
            case PUMP:
                // 处理泵逻辑
                return null;
            default:
                // 其他类型
                return null;
        }
        EquipmentParam ep = equipmentParamMapper.selectOne(wrapper);
        if (ep == null) {
            log.warn("根据 parentId:{} 查询不到设备参数1", parentId);
            return null;
        }
        return ep.getCode();
    }

    @Override
    public Integer getSetCodeByParentId(Long parentId) {
        if(parentId == null) {
            log.warn("parentId is null");
            return null;
        }
        Equipment e = equipmentService.selectEquipmentByEquipmentId(parentId);
        if (e == null) {
            log.warn("根据 parentId:{} 没有查询到设备信息", parentId);
            return null;
        }
        DeviceTypeEnum type = DeviceTypeEnum.fromCode(e.getEquipmentType());
        LambdaQueryWrapper<EquipmentParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EquipmentParam::getRelationId, parentId);
        switch (type) {
            case SENSOR:
            case VALVE_WITH_FEEDBACK:
            case VALVE_NO_FEEDBACK:
                // 处理传感器,阀门逻辑
                wrapper.eq(EquipmentParam::getParamType, RegisterTypeEnum.MASTER_SET.getCode());
                break;
            case PUMP:
                // 处理泵逻辑
                return null;
            default:
                // 其他类型
                return null;
        }
        EquipmentParam ep = equipmentParamMapper.selectOne(wrapper);
        if (ep == null) {
            log.warn("根据 parentId:{} 查询不到设备参数2", parentId);
            return null;
        }
        return ep.getAddress();
    }

    @Override
    public List<String> getCodesByParentId(Long parentId) {
        if (parentId == null) {
            log.warn("parentId is null");
            return Collections.emptyList();
        }

        Equipment equipment = equipmentService.selectEquipmentByEquipmentId(parentId);
        if (equipment == null) {
            log.warn("根据 parentId:{} 没有查询到设备信息", parentId);
            return Collections.emptyList();
        }

        DeviceTypeEnum type = DeviceTypeEnum.fromCode(equipment.getEquipmentType());
        if (type == null) {
            log.warn("未知设备类型: {}", equipment.getEquipmentType());
            return Collections.emptyList();
        }

        // 初始化查询 wrapper
        LambdaQueryWrapper<EquipmentParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EquipmentParam::getRelationId, parentId);

        List<String> paramTypes = new ArrayList<>();

        // 根据设备类型确定查询的寄存器类型
        switch (type) {
            case SENSOR://传感器
                paramTypes.add(RegisterTypeEnum.MASTER_DATA.getCode());
                break;
            case VALVE_WITH_FEEDBACK://有反馈阀门
                paramTypes.add(RegisterTypeEnum.MASTER_DATA.getCode());
                paramTypes.add(RegisterTypeEnum.SLAVE_DATA.getCode());
                paramTypes.add(RegisterTypeEnum.MASTER_SET.getCode());
                break;
            case VALVE_NO_FEEDBACK://无反馈阀门
                paramTypes.add(RegisterTypeEnum.MASTER_SET.getCode());
                break;
            case PUMP://泵
                paramTypes.add(RegisterTypeEnum.MASTER_DATA.getCode());//状态
                paramTypes.add(RegisterTypeEnum.SLAVE_DATA.getCode());//频率
                break;
            default:
                return Collections.emptyList();
        }

        // 查询所有符合条件的寄存器
        wrapper.in(EquipmentParam::getParamType, paramTypes);
        List<EquipmentParam> paramList = equipmentParamMapper.selectList(wrapper);
        // 根据 paramTypes 顺序排序
        paramList.sort(Comparator.comparingInt(p -> paramTypes.indexOf(p.getParamType())));
        if (CollectionUtils.isEmpty(paramList)) {
            log.warn("根据 parentId:{} 没有查询到对应类型的寄存器", parentId);
            return Collections.emptyList();
        }

        // 提取 code 并返回
        return paramList.stream()
                .map(EquipmentParam::getCode)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    @Override
    public List<EquipmentParam> selectEquipmentParamListByDataType(List<String> dataTypes) {
        LambdaQueryWrapper<EquipmentParam> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(EquipmentParam::getDataType, dataTypes);
        wrapper.in(EquipmentParam::getParamType, RegisterTypeEnum.MASTER_DATA.getCode(), RegisterTypeEnum.SLAVE_DATA.getCode());
        wrapper.eq(EquipmentParam::getStatus,GeneralStatus.ENABLE.getCode());
        return equipmentParamMapper.selectList(wrapper);
    }

}
