package com.zehong.system.task;

import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.zehong.common.utils.StringUtils;
import com.zehong.system.domain.RobotArmCommand;
import com.zehong.system.domain.TEquipmentAlarmData;
import com.zehong.system.domain.TStoreyInfo;
import com.zehong.system.mapper.RobotArmCommandMapper;
import com.zehong.system.mapper.TStoreyInfoMapper;
import com.zehong.system.modbus.util.Modbus4jUtils;
import com.zehong.system.service.ITEquipmentAlarmDataService;
import com.zehong.system.service.ITStoreyInfoService;
import com.zehong.system.service.websocket.RobotArmWebSocketHandler;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author lenovo
 * @date 2025/6/25
 * @description TODO
 */
@Component
public class FinalExecutionJob implements Job {
    private static final Logger log = LoggerFactory.getLogger(FinalExecutionJob.class);

    @Resource
    private RobotArmWebSocketHandler robotArmWebSocketHandler;
    @Resource
    private ITEquipmentAlarmDataService alarmDataService;
    @Resource
    private ITStoreyInfoService tStoreyInfoService;

    @Resource
    private TStoreyInfoMapper tStoreyInfoMapper;
    @Resource
    private Scheduler scheduler;

    @Resource
    private RobotArmCommandMapper robotArmCommandMapper;
    @Override
    public void execute(JobExecutionContext context) {
        JobDataMap data = context.getJobDetail().getJobDataMap();

        String fStoreyId = data.getString("fStoreyId");
        String fPowerOutageIp = data.getString("fPowerOutageIp");
        String fPowerOutagePort = data.getString("fPowerOutagePort");

        TStoreyInfo tStoreyInfo = tStoreyInfoMapper.selectTStoreyInfoById(Long.parseLong(fStoreyId));
        if(tStoreyInfo == null || StringUtils.isBlank(fPowerOutagePort) || StringUtils.isBlank(fPowerOutageIp)) {
            // 记录异常
            TEquipmentAlarmData alarmData = new TEquipmentAlarmData();
            alarmData.setfAlarmType("03"); // 老化层
            alarmData.setfEquipmentCode(fStoreyId);
            alarmData.setfAlarmData("71小时到老化层业务逻辑时数据丢失");
            alarmDataService.insertTEquipmentAlarmData(alarmData);
        } else{
            try {
                log.info("设备[{}]开始执行最终业务逻辑", tStoreyInfo.getfStoreyCode());

                // 1. 执行业务逻辑
                String s = tStoreyInfo.getfStoreyCode().split("-")[1];
                int i = Integer.parseInt(s);
                executeBusinessLogic(fPowerOutageIp,Integer.parseInt(fPowerOutagePort),(i - 1));

                // 2. 更新任务状态
                tStoreyInfo.setfStatus("0");
                tStoreyInfo.setfAgingStartTime(null);
                tStoreyInfoService.updateTStoreyInfo(tStoreyInfo);

                // 3. 清理相关任务
                cleanUpJobs(fStoreyId,context);

                // 4. 发送 下料指令
                createRoboticArm(tStoreyInfo.getfTrayCode(),tStoreyInfo.getfStoreyCode(),tStoreyInfo.getBlankingCommand());

                log.info("设备[{}]最终业务逻辑执行完成", fStoreyId);
            } catch (Exception e) {
                // 记录异常
                TEquipmentAlarmData alarmData = new TEquipmentAlarmData();
                alarmData.setfAlarmType("03"); // 老化层
                alarmData.setfEquipmentCode(tStoreyInfo.getfStoreyCode());
                alarmData.setfAlarmData("老化层清除任务时失败");
                alarmDataService.insertTEquipmentAlarmData(alarmData);
            }
        }
    }

    private void createRoboticArm(String trayCode,String storeyCode,String command) {
        // 创建机械臂任务
        RobotArmCommand robotArmCommand = new RobotArmCommand();
        robotArmCommand.setType("1");
        robotArmCommand.setStatus("1");
        robotArmCommand.setTrayCode(trayCode);
        robotArmCommand.setStoreyCode(storeyCode);
        robotArmCommand.setCreateTime(new Date());
        robotArmCommand.setCommand(command);
        robotArmCommandMapper.insertRobotArmCommand(robotArmCommand);
        notifyCommandsUpdate();
    }

    private void cleanUpJobs(String deviceId,JobExecutionContext context) throws SchedulerException {
        // 删除通信任务
        scheduler.deleteJob(new JobKey("COMM_" + deviceId, "DEVICE_TASKS"));

        // 删除自身任务
        scheduler.deleteJob(context.getJobDetail().getKey());
    }

    // ... 业务逻辑方法
    private void executeBusinessLogic(String fPowerOutageIp, int fPowerOutagePort,int registerOffsets) {

        // 10 层
        ModbusMaster master;
        try {
            master = Modbus4jUtils.getMaster(fPowerOutageIp, fPowerOutagePort);
            Boolean aBoolean = Modbus4jUtils.writeCoil(master, 1,registerOffsets,false );
        } catch (ModbusInitException | ModbusTransportException e) {
            throw new RuntimeException(e);
        }
    }
    private void notifyCommandsUpdate() {
        robotArmWebSocketHandler.broadcastCommandUpdate();
    }
}
