package com.zehong.system.modbus.service;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.zehong.system.domain.RobotArmCommand;
import com.zehong.system.mapper.RobotArmCommandMapper;
import com.zehong.system.service.IRobotArmCommandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.springframework.stereotype.Service;

/**
 * @author lenovo
 * @date 2025/8/6
 * @description TODO
 */

@Service
public class ConveyorBeltMonitor {
    @Value("${modbus.ip:192.168.2.11}")
    private String modbusIp;

    @Value("${modbus.port:502}")
    private int modbusPort;

    @Value("${modbus.deviceId:1}")
    private int deviceId;

    @Resource
    private IRobotArmCommandService commandService;

    @Resource
    private RobotArmCommandMapper commandMapper;

    private ModbusMaster modbusMaster;
    private boolean lastConveyorState = false;

    // 存储已检测到但未处理的托盘
    private final ConcurrentMap<String, Long> detectedTrays = new ConcurrentHashMap<>();

    @PostConstruct
    public void init() throws ModbusInitException {
        modbusMaster = getMaster(modbusIp, modbusPort);
    }

    //@Scheduled(fixedRate = 5000) // 每5秒执行一次
    public void monitorConveyorBelt() {
        try {
            // 读取Modbus离散输入
            boolean[] inputs = readDiscreteInputs(modbusMaster, deviceId, 0, 2);

            // inputs[1] 表示传送带上是否有托盘
            boolean currentState = inputs.length > 1 && inputs[1];

            // 检测到新托盘（状态从false变为true）
            if (currentState && !lastConveyorState) {
                handleNewTrayDetected();
            }

            lastConveyorState = currentState;
        } catch (Exception e) {
            e.printStackTrace();
            // 处理异常，如重新初始化Modbus连接
            try {
                modbusMaster = getMaster(modbusIp, modbusPort);
            } catch (ModbusInitException ex) {
                ex.printStackTrace();
            }
        }
    }

    private void handleNewTrayDetected() {
        // 检查是否有待处理的托盘指令
        if (detectedTrays.isEmpty()) {
            // 查找最近扫码但未处理的托盘
            RobotArmCommand pendingCommand = commandMapper.selectLatestPendingTray();
            if (pendingCommand != null) {
                detectedTrays.put(pendingCommand.getTrayCode(), System.currentTimeMillis());
                createLoadingCommand(pendingCommand.getTrayCode());
            } else {
                System.out.println("检测到传送带上有托盘，但未找到扫码记录的托盘编号");
                // 可以添加报警逻辑
            }
        }
    }

    public void createLoadingCommand(String trayCode) {
        // 检查是否已存在相同托盘的待执行指令
        RobotArmCommand existingCommand = commandMapper.findByTrayAndStatus(trayCode, "0");
        if (existingCommand != null) {
            System.out.println("托盘 " + trayCode + " 的指令已存在，跳过创建");
            return;
        }

        // 创建新指令
        RobotArmCommand command = new RobotArmCommand();
        command.setTrayCode(trayCode);
        command.setType("0"); // 待上料
        command.setStatus("0"); // 待执行
        command.setCreateTime(new Date());

        commandMapper.insertRobotArmCommand(command);
        System.out.println("已为托盘 " + trayCode + " 创建上料指令");

        // 通知指令更新
        commandService.processPendingCommands();
    }

    // 当指令执行完成时调用
    public void onCommandCompleted(String trayCode) {
        detectedTrays.remove(trayCode);
    }

    // 工具方法
    private boolean[] readDiscreteInputs(ModbusMaster master, int deviceId, int startAddress, int length)
            throws ModbusTransportException {
        // 实现您的离散输入读取逻辑
        // 这里简化为返回示例数据
        return new boolean[]{false, true}; // 示例数据
    }

    private ModbusMaster getMaster(String ip, int port) throws ModbusInitException {
        // 实现您的Modbus Master创建逻辑
        return null; // 实际实现
    }
}
