package com.zehong.system.task;

import com.zehong.system.domain.TEquipmentAlarmData;
import com.zehong.system.domain.TStoreyInfo;
import com.zehong.system.mapper.TStoreyInfoMapper;
import com.zehong.system.modbus.business.DeviceStatusReaderAndTimeSetter;
import com.zehong.system.modbus.handler.ModbusResultHandler;
import com.zehong.system.service.ITEquipmentAlarmDataService;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * @author lenovo
 * @date 2025/6/25
 * @description 上电以后 两分钟执行一次的逻辑
 */
@Component
public class DeviceCommunicationJob implements Job {
    private static final Logger log = LoggerFactory.getLogger(DeviceCommunicationJob.class);

    @Resource
    private ITEquipmentAlarmDataService alarmDataService;
    @Resource
    private DeviceStatusReaderAndTimeSetter deviceStatusReaderAndTimeSetter;
    @Resource
    private TStoreyInfoMapper tStoreyInfoMapper;

    @Autowired
    private ModbusResultHandler resultHandler;

    @Override
    public void execute(JobExecutionContext context) {
        // 1. 初始化所有变量，避免空指针
        JobDataMap data = null;
        String fStoreyIdStr = null;
        Long fStoreyId = null;
        TStoreyInfo tStoreyInfo = null;
        String ip = null;

        try {
            // 2. 提取参数（每一步都校验，避免空指针）
            data = context.getJobDetail().getJobDataMap();
            if (data == null) {
                log.error("JobDataMap为空，终止执行");
                return;
            }
            fStoreyIdStr = data.getString("fStoreyId");
            if (StringUtils.isBlank(fStoreyIdStr)) {
                log.error("fStoreyId参数为空，终止执行");
                return;
            }

            // 3. 转换参数（处理NumberFormatException）
            try {
                fStoreyId = Long.parseLong(fStoreyIdStr);
            } catch (NumberFormatException e) {
                log.error("fStoreyId格式错误：{}，终止执行", fStoreyIdStr);
                return;
            }

            // 4. 查询设备信息（校验DB查询结果）
            tStoreyInfo = tStoreyInfoMapper.selectTStoreyInfoById(fStoreyId);
            if (tStoreyInfo == null) {
                log.error("未查询到设备信息：fStoreyId={}，终止执行", fStoreyId);
                return;
            }
            ip = tStoreyInfo.getfIp();
            if (StringUtils.isBlank(ip)) {
                log.error("设备IP为空：fStoreyId={}，终止执行", fStoreyId);
                return;
            }

            // 5. 执行Modbus通信（业务逻辑，每个调用都加try-catch）
            List<Integer> offsets1 = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27);
            List<Integer> offsets2 = Arrays.asList(28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54);
            List<Integer> offsets3 = Arrays.asList(55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72);

            // 每个Modbus调用单独捕获异常，避免一个设备失败导致整个Job报错
            try {
                deviceStatusReaderAndTimeSetter.startMultiDeviceMonitoring(ip, 501, offsets1, resultHandler, ModbusResultHandler.createDefaultStopCondition());
                log.info("Modbus 501端口通信完成：fStoreyId={}", fStoreyId);
            } catch (Exception e) {
                log.error("Modbus 501端口通信异常：fStoreyId={}", fStoreyId, e);
                // 仅记录日志，不抛出异常
            }
            try {
                deviceStatusReaderAndTimeSetter.startMultiDeviceMonitoring(ip, 502, offsets2, resultHandler, ModbusResultHandler.createDefaultStopCondition());
                log.info("Modbus 502端口通信完成：fStoreyId={}", fStoreyId);
            } catch (Exception e) {
                log.error("Modbus 502端口通信异常：fStoreyId={}", fStoreyId, e);
            }
            try {
                deviceStatusReaderAndTimeSetter.startMultiDeviceMonitoring(ip, 503, offsets3, resultHandler, ModbusResultHandler.createDefaultStopCondition());
                log.info("Modbus 503端口通信完成：fStoreyId={}", fStoreyId);
            } catch (Exception e) {
                log.error("Modbus 503端口通信异常：fStoreyId={}", fStoreyId, e);
            }

            log.info("=== DeviceCommunicationJob 执行成功：fStoreyId={} ===", fStoreyId);

        } catch (Throwable e) {
            // 6. 捕获所有异常（包括Error，如NoClassDefFoundError）
            log.error("=== DeviceCommunicationJob 执行致命异常：fStoreyId={} ===", fStoreyIdStr, e);
            // 记录告警（内部异常也不抛出，确保Job不传播任何错误）
            try {
                if (tStoreyInfo != null && StringUtils.isNotBlank(tStoreyInfo.getfStoreyCode())) {
                    TEquipmentAlarmData alarm = new TEquipmentAlarmData();
                    alarm.setfAlarmType("03");
                    alarm.setfEquipmentCode(tStoreyInfo.getfStoreyCode());
                    alarm.setfAlarmData("通信任务异常：" + e.getMessage());
                    alarm.setfCreateTime(new Date());
                    alarmDataService.insertTEquipmentAlarmData(alarm);
                }
            } catch (Exception alarmEx) {
                log.error("=== 告警记录失败（不影响触发器） ===", alarmEx);
            }
            // 绝对禁止抛出任何异常！！！
        }
    }
}
