package com.dcs.equipment.service.impl;

import com.dcs.equipment.constants.EquipmentConstants;
import com.dcs.equipment.task.ModbusTcpTask;
import com.dcs.equipment.utils.ModbusUtil;
import com.dcs.hnyz.domain.EquipmentParam;
import com.dcs.hnyz.service.IEquipmentParamService;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dcs.equipment.service.M2FlowService;

import java.util.List;
import java.util.Map;

/**
 * @author: wangpx
 * @date: 2025-05-12 11:33
 */
@Service
public class M2FlowServiceImpl implements M2FlowService {

    private static final Logger logger = LoggerFactory.getLogger("M2Flow");

    @Autowired
    private IEquipmentParamService equipmentParamService;

    /**
     * 水解罐出料
     * @param tankCode 水解罐编码
     */
    @Override
    public boolean hydrolysisDischargeToM2(String tankCode) {
        List<EquipmentParam> equipmentParamList = ModbusTcpTask.equipmentParamList;
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        // TODO 根据tankCode获取对应设备的地址和参数
        try {
            // S1压力到达指定值
            EquipmentParam S1PressureParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.S1_PRESSURE));
            float S1Pressure;
            do {
                S1Pressure = ModbusUtil.getHoldingRegisterFloatValue(1, S1PressureParam.getAddress());
            } while (S1Pressure > 0.25f);
            // 打开 N22(S1出料阀) N23(S2出料阀) N24(S3出料阀)
            EquipmentParam N22Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N22));
            ModbusUtil.setCoilValue(1, N22Param.getAddress(), true);
            // 打开N12 M2进料阀
            EquipmentParam N12Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N12));
            ModbusUtil.setCoilValue(1, N12Param.getAddress(), true);
            // 打开N15 M2排堵出气阀1
            EquipmentParam N15Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N15));
            ModbusUtil.setCoilValue(1, N15Param.getAddress(), true);
            // 打开N16 M2排堵进气阀2
            EquipmentParam N16Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N16));
            ModbusUtil.setCoilValue(1, N16Param.getAddress(), true);
            // 打开N17 M2排堵出气阀2
            EquipmentParam N17Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N17));
            ModbusUtil.setCoilValue(1, N17Param.getAddress(), true);
            // 等待3s打开 LB7 J2换热进液泵
            Thread.sleep(3000);
            EquipmentParam LB7StateSettingParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.LB7_STATE_SETTING));
            EquipmentParam LB7StateParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.LB7_STATE));
            boolean isLB7On;
            do {
                ModbusUtil.setRegisterValue(1, LB7StateSettingParam.getAddress(), EquipmentConstants.INVERTER_SETTING_FORWARD);
                int LB7State = ModbusUtil.getHoldingRegisterIntegerValue(1, LB7StateParam.getAddress());
                isLB7On = EquipmentConstants.INVERTER_STATUS_FORWARD.equals(LB7State);
                if (!isLB7On) Thread.sleep(1000); // 未启动等待1s
            } while (!isLB7On);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException | InterruptedException e) {
            logger.error("水解罐" + tankCode + "向M2注料流程错误", e);
            return false;
        }
        return true;
    }

    /**
     * M2-J2-M1 换热
     * @return
     */
    @Override
    public boolean J2TransferHeatToM2() {
        List<EquipmentParam> equipmentParamList = ModbusTcpTask.equipmentParamList;
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        // 先关闭D1、D2、N2，再打开D3、D4、N3，经过J2到P1
        try {
            // 关闭D1 J1换热进液阀
            EquipmentParam D1Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D1));
            EquipmentParam D1OffParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D1_OFF));
            // 关闭D2 J1蒸汽进气阀
            EquipmentParam D2Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D2));
            EquipmentParam D2OffParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D2_OFF));
            boolean isD1AndD2Off;
            do {
                ModbusUtil.setCoilValue(1, D1Param.getAddress(), false);
                ModbusUtil.setCoilValue(1, D2Param.getAddress(), false);
                boolean D1OffState = ModbusUtil.getCoilValue(1, D1OffParam.getAddress());
                boolean D2OffState = ModbusUtil.getCoilValue(1, D2OffParam.getAddress());
                isD1AndD2Off = D1OffState && D2OffState;
                if (!isD1AndD2Off) Thread.sleep(1000); // 未关闭等待1s
            } while (!isD1AndD2Off); // 等待D1、D2关闭
            // 打开N2 J2换热阀
            EquipmentParam N2Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N2));
            ModbusUtil.setCoilValue(1, N2Param.getAddress(), false);
            // 打开D3 J2换热进液阀
            EquipmentParam D3Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D3));
            EquipmentParam D3OnParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D3_ON));
            // 打开D4 J2进液换热阀
            EquipmentParam D4Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D4));
            EquipmentParam D4OnParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D4_ON));
            boolean isD3AndD4On;
            do {
                ModbusUtil.setCoilValue(1, D3Param.getAddress(), true);
                ModbusUtil.setCoilValue(1, D4Param.getAddress(), true);
                boolean D3OnState = ModbusUtil.getCoilValue(1, D3OnParam.getAddress());
                boolean D4OnState = ModbusUtil.getCoilValue(1, D4OnParam.getAddress());
                isD3AndD4On = D3OnState && D4OnState;
                if (!isD3AndD4On) Thread.sleep(1000); // 未打开等待1s
            } while (!isD3AndD4On); // 等待D3、D4打开
            // 打开N3 J1换热阀
            EquipmentParam N3Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N3));
            ModbusUtil.setCoilValue(1, N3Param.getAddress(), true);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException | InterruptedException e) {
            logger.error("M2-J2-M1换热流程错误", e);
            return false;
        }
        return true;
    }

    /**
     * 水解罐停止出料
     * @param tankCode 水解罐编码
     */
    @Override
    public boolean hydrolysisStopDischargeToM2(String tankCode) {
        List<EquipmentParam> equipmentParamList = ModbusTcpTask.equipmentParamList;
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        // TODO 根据tankCode获取对应设备的地址和参数
        try {
            // 关闭 N22(S1） N23(S2) N24(S3)
            EquipmentParam N22Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N22));
            ModbusUtil.setCoilValue(1, N22Param.getAddress(), false);
            // 3s 后再关闭 LB6 M2进料泵
            Thread.sleep(3000);
            EquipmentParam LB6StateSettingParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.LB6_STATE_SETTING));
            ModbusUtil.setRegisterValue(1, LB6StateSettingParam.getAddress(), EquipmentConstants.INVERTER_SETTING_STOP);
            // 关闭 N12 N15 N16 N17
            // 关闭N12 M2进料阀
            EquipmentParam N12Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N12));
            ModbusUtil.setCoilValue(1, N12Param.getAddress(), false);
            // 关闭N15 M2排堵出气阀1
            EquipmentParam N15Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N15));
            ModbusUtil.setCoilValue(1, N15Param.getAddress(), false);
            // 关闭N16 M2排堵进气阀2
            EquipmentParam N16Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N16));
            ModbusUtil.setCoilValue(1, N16Param.getAddress(), false);
            // 关闭N17 M2排堵出气阀2
            EquipmentParam N17Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N17));
            ModbusUtil.setCoilValue(1, N17Param.getAddress(), false);
            // 等待3s 后再关闭 LB7 J2换热进液泵
            Thread.sleep(3000);
            EquipmentParam LB7StateSettingParam = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.LB7_STATE_SETTING));
            ModbusUtil.setRegisterValue(1, LB7StateSettingParam.getAddress(), EquipmentConstants.INVERTER_SETTING_STOP);
            // TODO 是否需要等待泵关闭？
            // 打开D1 D2 N2
            // 打开D1 J1换热进液阀
            EquipmentParam D1Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D1));
            ModbusUtil.setCoilValue(1, D1Param.getAddress(), true);
            // 打开D2 J1蒸汽进气阀
            EquipmentParam D2Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D2));
            ModbusUtil.setCoilValue(1, D2Param.getAddress(), true);
            // 打开N2 J2换热阀
            EquipmentParam N2Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N2));
            ModbusUtil.setCoilValue(1, N2Param.getAddress(), true);
            // 关闭 D3 D4 N3
            // 关闭D3 J2换热进液阀
            EquipmentParam D3Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D3));
            ModbusUtil.setCoilValue(1, D3Param.getAddress(), false);
            // 关闭D4 J2进液换热阀
            EquipmentParam D4Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.D4));
            ModbusUtil.setCoilValue(1, D4Param.getAddress(), false);
            // 关闭N3 J1换热阀
            EquipmentParam N3Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N3));
            ModbusUtil.setCoilValue(1, N3Param.getAddress(), false);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException | InterruptedException e) {
            logger.error("水解罐" + tankCode + "停止出料流程错误", e);
            return false;
        }
        return true;
    }

    /**
     * M2除渣
     */
    @Override
    public boolean M2RemoveSlag() {
        List<EquipmentParam> equipmentParamList = ModbusTcpTask.equipmentParamList;
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        try {
            // 打开N19
            EquipmentParam N19Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N19));
            ModbusUtil.setCoilValue(1, N19Param.getAddress(), true);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException e) {
            logger.error("M2除渣流程错误", e);
            return false;
        }
        return true;
    }

    /**
     * M2停止除渣
     */
    @Override
    public boolean M2StopRemoveSlag() {
        List<EquipmentParam> equipmentParamList = ModbusTcpTask.equipmentParamList;
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        try {
            // 关闭N19
            EquipmentParam N19Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N19));
            ModbusUtil.setCoilValue(1, N19Param.getAddress(), false);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException e) {
            logger.error("M2停止除渣流程错误", e);
            return false;
        }
        return true;
    }

    /**
     * M2负压排堵
     */
    @Override
    public boolean negativePressureUnblock() {
        List<EquipmentParam> equipmentParamList = ModbusTcpTask.equipmentParamList;
        Map<Integer, Integer> equipmentIndexList = equipmentParamService.getEquipmentIndexList();
        try{
            // 开启N18
            EquipmentParam N18Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N18));
            ModbusUtil.setCoilValue(1, N18Param.getAddress(), true);
            // 5次开关N16 每秒一次
            for (int i = 0; i < 5; i++) {
                // 打开N16 M2排堵进气阀2
                EquipmentParam N16Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N16));
                ModbusUtil.setCoilValue(1, N16Param.getAddress(), true);
                // 等待1s
                Thread.sleep(1000);
                // 关闭N16 M2排堵进气阀2
                ModbusUtil.setCoilValue(1, N16Param.getAddress(), false);
                // 等待1s
                Thread.sleep(1000);
            }
            // 打开N20 等待5s
            EquipmentParam N20Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N20));
            ModbusUtil.setCoilValue(1, N20Param.getAddress(), true);
            Thread.sleep(5000);
            // 关闭N20
            ModbusUtil.setCoilValue(1, N20Param.getAddress(), false);
            // 5次开关N17 每秒一次
            for (int i = 0; i < 5; i++) {
                // 打开N17 M2排堵出气阀2
                EquipmentParam N17Param = equipmentParamList.get(equipmentIndexList.get(EquipmentConstants.N17));
                ModbusUtil.setCoilValue(1, N17Param.getAddress(), true);
                // 等待1s
                Thread.sleep(1000);
                // 关闭N17 M2排堵出气阀2
                ModbusUtil.setCoilValue(1, N17Param.getAddress(), false);
                // 等待1s
                Thread.sleep(1000);
            }
            // 打开N20 等待5s
            ModbusUtil.setCoilValue(1, N20Param.getAddress(), true);
            Thread.sleep(5000);
            // 关闭N20
            ModbusUtil.setCoilValue(1, N20Param.getAddress(), false);
        } catch (ModbusProtocolException | ModbusNumberException | ModbusIOException | InterruptedException e) {
            logger.error("M2负压排堵流程错误", e);
            return false;
        }
        return false;
    }

}