package org.nl.acs.device_driver.basedriver.agv.ndctwo;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.agv.server.NDCAgvService;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.service.DeviceService;
import org.nl.acs.device_driver.DeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_ordinary_site.StandardOrdinarySiteDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_storage.StandardStorageDeviceDriver;
import org.nl.acs.device_driver.driver.AbstractDeviceDriver;
import org.nl.acs.ext.wms.service.AcsToWmsService;
import org.nl.acs.ext.wms.service.impl.AcsToWmsServiceImpl;
import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.instruction.service.impl.InstructionServiceImpl;
import org.nl.acs.log.LokiLog;
import org.nl.acs.log.LokiLogType;
import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.opc.DeviceAppService;
import org.nl.system.service.param.ISysParamService;
import org.nl.config.SpringContextHolder;


/**
 * NDC双工位AGV
 */
@Slf4j
@Data
@RequiredArgsConstructor
public class AgvNdcTwoDeviceDriver extends AbstractDeviceDriver implements DeviceDriver {

    ISysParamService ISysParamService = SpringContextHolder.getBean(ISysParamService.class);
    InstructionService instructionService = SpringContextHolder.getBean(InstructionServiceImpl.class);
    AcsToWmsService acsToWmsService = SpringContextHolder.getBean(AcsToWmsServiceImpl.class);
    NDCAgvService ndcAgvService = SpringContextHolder.getBean(NDCAgvService.class);
    DeviceExecuteLogService logServer = SpringContextHolder.getBean(DeviceExecuteLogService.class);
    DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class);
    DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class);
    int agvaddr = 0;
    int agvaddr_copy = 0;
    int weight = 0;
    int agv_power = 0;
    String device_code = "";
    int phase = 0;
    int region = 0;

    @LokiLog(type = LokiLogType.ACS_TO_LMS)
    public synchronized void processSocket(int[] arr) throws Exception {
        device_code = this.getDeviceCode();
        byte[] data = null;
        phase = arr[16] * 256 + arr[17];
        // agv任务号
        int index = arr[12] * 256 + arr[13];
        //任务号
        int ikey = arr[26] * 256 + arr[27];
        //站点号
        agvaddr = arr[18] * 256 + arr[19];
        //车号
        int carno = arr[20];
        Instruction inst = null;
        Device agv_device = null;
        if (carno != 0) {
            agv_device = deviceAppService.findDeviceByCode(String.valueOf(carno));
        }
        if (ikey != 0) {
            inst = instructionService.findByCodeFromCache(String.valueOf(ikey));
        }


        Device device = null;
        String old_device_code = null;
        String emptyNum = null;
        String device_code = null;

        if (agvaddr != 0) {
            old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
            if (StrUtil.contains(old_device_code, "-")) {
                String[] point = old_device_code.split("-");
                device_code = point[0];
            } else if (StrUtil.contains(old_device_code, ".")) {
                String[] point = old_device_code.split("\\.");
                device_code = point[0];
                emptyNum = point[1];
            } else {
                device_code = old_device_code;
            }
        }
        device = deviceAppService.findDeviceByCode(device_code);

        //普通站点
        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        //货架
        StandardStorageDeviceDriver standardStorageDeviceDriver;

        if (phase == 0x02) {
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            inst.setCarno(String.valueOf(carno));
            instructionService.update(inst);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase：" + "反馈:" + data);
        }
        //到达取货点
        //(Itype=1/2/3,需要WCS反馈Phase)
        else if (phase == 0x03) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }

            device = deviceAppService.findDeviceByCode(device_code);
            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                logServer.deviceExecuteLog(this.device_code, "", "", agvaddr + "对应设备号为空");
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
        }
        // 取货完毕
        //(Itype=1/2/3,需要WCS反馈Phase)
        else if (phase == 0x05) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }
            device = deviceAppService.findDeviceByCode(device_code);

            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                logServer.deviceExecuteLog(this.device_code, "", "", "对应设备号为空" + device_code);
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
        }
        //到达取货点(Itype=1、3，需要WCS反馈)
        else if (phase == 0x08) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }
            device = deviceAppService.findDeviceByCode(device_code);
            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            String agv_inst_type = inst.getAgv_inst_type();
            if (StrUtil.equals(agv_inst_type, "1") || StrUtil.equals(agv_inst_type, "3")) {
                data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
                logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
            }
        }
        // 取货完毕
        //(Itype=1、3,需要WCS反馈)
        else if (phase == 0x0A) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }

            device = deviceAppService.findDeviceByCode(device_code);
            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            String agv_inst_type = inst.getAgv_inst_type();
            if (StrUtil.equals(agv_inst_type, "1") || StrUtil.equals(agv_inst_type, "3")) {
                data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
                logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
            }

        }
        //（Itype=1,上传称重数据）
        else if (phase == 0x64) {
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            String instruction_type = inst.getInstruction_type();
            //上传称重数据
            if (StrUtil.equals(instruction_type, "1")) {
                weight = agvaddr;
//                inst.setWeight(String.valueOf(weight));
//                instructionService.update(inst);
                data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
                logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
            }
        }
        // 到达放货点
        //（Itype=1/2/3,需要WCS反馈）
        else if (phase == 0x0C) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }

            device = deviceAppService.findDeviceByCode(device_code);
            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
        }
        //放货完成
        //(Itype=1/2/3,需要WCS反馈)
        else if (phase == 0x0E) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }

            device = deviceAppService.findDeviceByCode(device_code);
            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
        }
        //到达放货点
        //（Itype=1、3,需要WCS反馈）
        else if (phase == 0x10) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }

            device = deviceAppService.findDeviceByCode(device_code);
            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            String agv_inst_type = inst.getAgv_inst_type();
            if (StrUtil.equals(agv_inst_type, "1") || StrUtil.equals(agv_inst_type, "3")) {
                data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
                logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
            }
        }
        //放货完成
        //（Itype=1、3,需要WCS反馈）
        else if (phase == 0x12) {
            if (agvaddr == 0) {
                agvaddr = agvaddr_copy;
            }
            if (agvaddr < 1) {
                logServer.deviceExecuteLog(this.device_code, "", "", "agv地址参数有误,phase:" + phase);
                return;
            }
            if (agvaddr != 0) {
                old_device_code = deviceService.queryDeviceCodeByAddress(agvaddr);
                if (StrUtil.contains(old_device_code, "-")) {
                    String[] point = old_device_code.split("-");
                    device_code = point[0];
                } else if (StrUtil.contains(old_device_code, ".")) {
                    String[] point = old_device_code.split("\\.");
                    device_code = point[0];
                    emptyNum = point[1];
                } else {
                    device_code = old_device_code;
                }
            }

            device = deviceAppService.findDeviceByCode(device_code);
            if (ObjectUtil.isEmpty(device_code)) {
                log.info(agvaddr + "对应设备号为空!");
                return;
            }
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            String agv_inst_type = inst.getAgv_inst_type();
            if (StrUtil.equals(agv_inst_type, "1") || StrUtil.equals(agv_inst_type, "3")) {
                data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
                logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
            }
        }
        //上传AGV电量
        else if (phase == 0x73) {
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            agv_power = ikey;
            data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);

        }  //进入区域（phase值）
        else if (phase == 0x50) {
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            region = agvaddr;
            data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);

        }
        //离开区域（phase值）
        else if (phase == 0x51) {
            if (ObjectUtil.isEmpty(inst)) {
                log.info("未找到指令号{}对应的指令", ikey);
                return;
            }
            region = agvaddr;
            data = ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);

        }
        //上报异常信息
        //（不需要WCS反馈）
        else if (phase == 0x67) {
            //故障信息
            if (agvaddr == 0) {

            }
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
        }
        if (!ObjectUtil.isEmpty(data)) {
            logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
//            if (StrUtil.equals(inst.getAgv_system_type(), "2")) {
//                TwoNDCSocketConnectionAutoRun.write(data);
//            } else if (StrUtil.equals(inst.getAgv_system_type(), "3")) {
//                TwoNDC2SocketConnectionAutoRun.write(data);
//            }
        }
    }

}
