package org.nl.acs.device_driver.tianneng.baoshijian;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.RouteableDeviceDriver;
import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver;
import org.nl.acs.device_driver.driver.ExecutableDeviceDriver;
import org.nl.acs.ext.wms.data.BaseRequest;
import org.nl.acs.ext.wms.service.AcsToWmsService;
import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.monitor.DeviceStageMonitor;
import org.nl.acs.route.service.RouteLineService;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.task.service.mapper.TaskMapper;
import org.nl.config.SpringContextHolder;
import org.openscada.opc.lib.da.Server;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 检测站点驱动
 */
@Slf4j
@Data
@RequiredArgsConstructor
public class BaoshijianSiteDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor {
    protected ItemProtocol itemProtocol = new ItemProtocol(this);

    InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl");

    DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl");

    RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl");

    TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl");

    TaskMapper taskMapper;

    AcsToWmsService acsToWmsService = SpringContextHolder.getBean("acsToWmsServiceImpl");

    String container;
    String container_type_desc;
    String last_container_type_desc;
    String last_container;
    //放货准备锁
    String putReadyLock = null;
    //有货标记
    protected boolean has_goods_tag = false;

    private Date time = new Date();

    int mode = 0;
    int error = 0;
    int move = 0;
    int task = 0;
    int action = 0;
    int last_mode = 0;
    int last_error = 0;
    int last_move = 0;
    int last_task = 0;
    Boolean isonline = true;
    int hasGoods = 0;
    String message = null;
    Boolean iserror = false;

    int io_action = 0;
    int last_io_action = 0;
    int material_type = 0;
    int last_material_type = 0;
    int barcode = 0;
    int last_barcode = 0;


    boolean hasVehicle = false;
    boolean isReady = false;
    protected int instruction_num = 0;
    protected int instruction_num_truth = 0;
    boolean isFold = false;
    private String assemble_check_tag;

    protected String current_stage_instruction_message;
    protected String last_stage_instruction_message;
    Integer heartbeat_tag;
    private Date instruction_require_time = new Date();
    private Date instruction_finished_time = new Date();

    private int instruction_require_time_out=1000;
    boolean in = false;
    boolean out =false;

    private int instruction_finished_time_out;

    int branchProtocol = 0;
    //备注
    String remark;
    //数量
    String qty;
    //物料
    String material;
    //批次
    String batch;
    //当前指令
    Instruction inst = null;
    //上次指令
    Instruction last_inst = null;

    //触摸屏手动触发任务
    private Boolean is_has_task = false;

    //满盅入库请求标记
    boolean Sucess = false;

    //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域
    int flag;

    String device_code;

    int x0 = 0;
    int last_x0 = 0;
    int x1 = 0;
    int last_x1 = 0;
    int x2 = 0;
    int last_x2 = 0;
    int x3 = 0;
    int last_x3 = 0;
    int x4 = 0;
    int last_x4 = 0;
    int x5 = 0;
    int last_x5 = 0;
    int x6 = 0;
    int last_x6 = 0;
    int x7 = 0;
    int last_x7 = 0;
    int x8 = 0;
    int last_x8 = 0;
    int x9 = 0;
    int last_x9 = 0;
    int x10 = 0;
    int last_x10 = 0;
    int x35 = 0;
    int last_x35 = 0;
    int x36 = 0;
    int last_x36 = 0;
    int x37 = 0;
    int last_x37 = 0;


    @Override
    public Device getDevice() {
        return this.device;
    }


    @Override
    public void execute() {
        String message = null;
        try {
            device_code = this.getDeviceCode();
            x0 = this.itemProtocol.getX0();
            x1 = this.itemProtocol.getX1();
            x2 = this.itemProtocol.getX2();
            x3 = this.itemProtocol.getX3();
            x4 = this.itemProtocol.getX4();
            x5 = this.itemProtocol.getX5();
            x6 = this.itemProtocol.getX6();
            x7 = this.itemProtocol.getX7();
            x8 = this.itemProtocol.getX8();
            x9 = this.itemProtocol.getX9();
            x10 = this.itemProtocol.getX10();
            x35 = this.itemProtocol.getX35();
            x36 = this.itemProtocol.getX36();
            x37 = this.itemProtocol.getX37();

            Date date = new Date();
            if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) {
                log.trace("触发时间因为小于{}毫秒，而被无视", this.instruction_require_time_out);
                return;
            }

            if (x1 != last_x1 && x1 == 0) {
                log.info("设备{}反馈收片任务完成", this.device_code);
                this.writing("x6", 0);
                this.writing("x8", 0);
            } else if (x1 != last_x1 && x1 == 1 &&!in && x6==0 && x8==0) {
                in = false;
                JSONObject jsonObject = new JSONObject();
                String device_code = this.device_code + "DJW01";
                jsonObject.put("device_code", device_code);
                jsonObject.put("requestDate", new Date());
                jsonObject.put("requestNo", IdUtil.simpleUUID());
                jsonObject.put("request_method_code", "TBXMLTask");
                String result=acsToWmsService.applyTaskToWms(jsonObject);
                JSONObject res_jo = JSONObject.parseObject(result);
                if (res_jo.getString("status").equals("200")){
                    this.writing("x6", 1);
                    in=true;
                }
            }

            if (x2 != last_x2 && x2 == 0) {
                log.info("设备{}反馈上空架完成", this.device_code);
                this.writing("x5", 0);
                this.writing("x7", 0);
            } else if (x2 != last_x2 && x2 == 1 && !out && x5==0 && x7==0) {
                out = false;
                JSONObject jsonObject = new JSONObject();
                String device_code = this.device_code + "DJW02";
                jsonObject.put("device_code", device_code);
                jsonObject.put("requestDate", new Date());
                jsonObject.put("vehicle_type",2);
                jsonObject.put("requestNo", IdUtil.simpleUUID());
                jsonObject.put("request_method_code", "TBXQKTask");
                String result=acsToWmsService.applyTaskToWms(jsonObject);
                JSONObject res_jo = JSONObject.parseObject(result);
                if (res_jo.getString("status").equals("200")){
                    this.writing("x5", 1);
                    out = true;
                }
            }

        } catch (Exception var17) {
            return;
        }

        last_x0 = x0;
        last_x1 = x1;
        last_x2 = x2;
        last_x3 = x3;
        last_x4 = x4;
        last_x5 = x5;
        last_x6 = x6;
        last_x7 = x7;
        last_x8 = x8;
        last_x9 = x9;
        last_x10 = x10;
        last_x35 = x35;
        last_x36 = x36;
        last_x37 = x37;

    }


    public boolean exe_error() {
        if (this.error == 0) {
            return true;
        } else {
            log.debug("设备报警");
            return false;
        }
    }


    public void executing(Server server, Map<String, Object> itemMap) {
        this.control(itemMap);
    }


    public void writing(String param, int command) {
        String to_command = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
                + "." + param;
        Map<String, Object> itemMap = new HashMap<>();
        itemMap.put(to_command, command);
        this.control(itemMap);
    }

    @Override
    public JSONObject getDeviceStatusName() {
        JSONObject jo = new JSONObject();
        String mode = "";
        String action = "";
        String move = "";
        if (this.getMode() == 0) {
            mode = "未联机";
        } else if (this.getMode() == 1) {
            mode = "单机";
        } else if (this.getMode() == 2) {
            mode = "联机";
        } else if (this.getMode() == 3) {
            mode = "运行中";
        }

        if (this.getMove() == 0) {
            move = "无货";
            jo.put("hasGoods", false);
        } else if (this.getMove() == 1) {
            move = "有货";
            jo.put("hasGoods", true);
        } else if (this.getMove() == 2) {
            move = "有托盘有货";
            jo.put("hasGoods", true);
        }
        jo.put("device_name", this.getDevice().getDevice_name());
        jo.put("mode", mode);
        jo.put("move", move);
        jo.put("action", action);
        jo.put("isOnline", this.getIsonline());
        jo.put("error", this.getError());
        jo.put("isError", this.getIserror());
        jo.put("task", this.getTask());
        return jo;
    }

    @Override
    public void setDeviceStatus(JSONObject data) {

    }


}
