package org.nl.acs.device_driver.basedriver.box_palletizing_manipulator;

import cn.hutool.core.util.StrUtil;
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.service.AcsToWmsService;
import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.log.service.DeviceExecuteLogService;
import org.nl.acs.monitor.DeviceStageMonitor;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceAppServiceImpl;
import org.nl.acs.route.service.RouteLineService;
import org.nl.acs.task.service.TaskService;
import org.nl.config.SpringContextHolder;
import org.openscada.opc.lib.da.Server;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 木箱码垛-行架机械手
 */
@Slf4j
@Data
@RequiredArgsConstructor
public class BoxPalletizingManipulatorDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor {
    protected ItemProtocol itemProtocol = new ItemProtocol(this);
    @Autowired
    InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl");
    @Autowired
    DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl");
    @Autowired
    RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl");
    @Autowired
    TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl");
    @Autowired
    DeviceExecuteLogService logServer = SpringContextHolder.getBean("deviceExecuteLogServiceImpl");
    @Autowired
    AcsToWmsService acsToWmsService = SpringContextHolder.getBean("acsToWmsServiceImpl");
    @Autowired
    DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);

    //工作模式
    int mode = 0;
    int last_mode = 0;
    //光电信号
    int move = 0;
    int last_move = 0;
    //动作信号
    int action = 0;
    int last_action = 0;
    //行走列
    int walk_y = 0;
    int last_walk_y = 0;
    //报警信号
    int error = 0;
    int last_error = 0;
    //任务号
    int task = 0;
    int last_task = 0;


    Boolean isonline = true;
    int hasGoods = 0;
    String message = null;
    Boolean iserror = false;

    Integer heartbeat_tag;
    private Date instruction_require_time = new Date();

    private int instruction_require_time_out;
    //行架机械手申请任务成功标识
    boolean requireSucess = false;

    private int instruction_finished_time_out;

    int branchProtocol = 0;


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

    String device_code;


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


    @Override
    public void execute() {
        String message = null;
        try {
            device_code = this.getDeviceCode();
            mode = this.itemProtocol.getMode();
            move = this.itemProtocol.getMove();
            action = this.itemProtocol.getAction();
            walk_y = this.itemProtocol.getWalk_y();
            error = this.itemProtocol.getError();
            task = this.itemProtocol.getTask();
            if (mode != last_mode) {
                logServer.deviceItemValue(this.device_code, "mode", String.valueOf(mode));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号mode：" + last_mode + "->" + mode);
            }
            if (move != last_move) {
                logServer.deviceItemValue(this.device_code, "move", String.valueOf(move));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号move：" + last_move + "->" + move);
            }
            if (action != last_action) {
                logServer.deviceItemValue(this.device_code, "action", String.valueOf(action));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号action：" + last_action + "->" + action);
            }
            if (error != last_error) {
                logServer.deviceItemValue(this.device_code, "error", String.valueOf(error));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号error：" + last_error + "->" + error);
            }
            if (walk_y != last_walk_y) {
                logServer.deviceItemValue(this.device_code, "walk_y", String.valueOf(walk_y));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号walk_y：" + last_walk_y + "->" + walk_y);
            }
            if (task != last_task) {
                logServer.deviceItemValue(this.device_code, "task", String.valueOf(task));
                logServer.deviceExecuteLog(this.device_code, "", "", "信号task：" + last_task + "->" + task);
            }

        } catch (Exception var17) {
            return;
        }

        if (!this.itemProtocol.getIsonline()) {
            this.setIsonline(false);
            this.setIserror(true);
            message = "信号量同步异常";
            //未联机
        } else if (mode == 0) {
            this.setIsonline(false);
            this.setIserror(true);
            message = "未联机";
            //有报警
        } else if (error != 0) {
            this.setIsonline(false);
            this.setIserror(true);
            message = "有报警";
            //无报警
        } else {
            this.setIsonline(true);
            this.setIserror(false);
            message = "";
            Instruction instruction = null;
            List toInstructions;

        }
        last_mode = mode;
        last_move = move;
        last_action = action;
        last_walk_y = walk_y;
        last_error = error;
        last_task = task;
    }



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

    public boolean exe_business() {
        return true;
    }

    public synchronized boolean finish_instruction(Instruction inst) throws Exception {
        instructionService.finish(inst);
        return true;
    }

    public void writing(String param, String value) {

        String to_param = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code()
                + "." + param;
        //String opcservcerid = this.getDevice().getOpc_server_id();
//Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();

        itemMap.put(to_param, value);
//            itemMap.put(to_param, Integer.parseInt(value));
        this.control(itemMap);
    }

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

    public void writing(int command) {

        //String opcservcerid = this.getDevice().getOpc_server_id();
//Server server = ReadUtil.getServer(opcservcerid);
        Map<String, Object> itemMap = new HashMap<String, Object>();
        this.control(itemMap);

    }

    //将扩展表中的字符串数据转换成集合
    public List<String> getExtraDeviceCodes(String extraName) {
        String extraValue = (String) this.getDevice().getExtraValue().get(extraName);
        if (StrUtil.isEmpty(extraValue)){
            return new ArrayList<>();
        }
        String devicesString = extraValue.substring(1, extraValue.length() - 1);
        List<String> devicesList = new ArrayList<>();
        String[] devices = devicesString.split(",");
        for (int i = 0; i < devices.length; i++) {
            String s = devices[i].replace("\"", "").replace("\"", "");
            devicesList.add(s);
        }
        return devicesList;
    }


    @Override
    public JSONObject getDeviceStatusName() {
        JSONObject jo = new JSONObject();
        String mode = "";
        String move = "";
        String action = "";
        String walk_y = "";
        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 = "无货";
        } else if (this.getMove() == 1) {
            move = "有货";
        }

        if (this.getAction() == 1) {
            action = "取货中";
        } else if (this.getAction() == 2) {
            action = "取货完成";
        } else if (this.getAction() == 3) {
            action = "放货中";
        } else if (this.getAction() == 4) {
            action = "放货完成";
        }

        jo.put("device_name", this.getDevice().getDevice_name());
        jo.put("mode", mode);
        jo.put("move", move);
        jo.put("action", action);
        jo.put("task", task);
        jo.put("walk_y", walk_y);
        jo.put("isOnline", this.getIsonline());
        jo.put("error", this.getError());
        jo.put("isError", this.getIserror());
        jo.put("message", this.getMessage());
        return jo;
    }

    @Override
    public void setDeviceStatus(JSONObject data) {

    }
}
