package org.nl.quartz.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.nl.acs.AcsConfig;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device_driver.basedriver.standard_inspect_site.StandardInspectSiteDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_ordinary_site.StandardOrdinarySiteDeviceDriver;
import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.service.InstructionService;
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.acs.task.service.dto.TaskDto;
import org.nl.config.SpringContextHolder;
import org.nl.system.service.param.ISysParamService;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 自动创建指令
 */
@Slf4j
@Component
public class AutoCreateInst {
    /**
     * 根据任务状态创建指令、生成下一条指令
     * 创建指令前需要判断是否条件具备：起始位置是否有货、目标位置是否有货
     */
    public synchronized void run() throws Exception {
        TaskService taskserver = SpringContextHolder.getBean(TaskService.class);
        InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class);
        RouteLineService routeLineService = SpringContextHolder.getBean(RouteLineService.class);
        ISysParamService  acsConfigService = SpringContextHolder.getBean(ISysParamService.class);
        List<TaskDto> list = taskserver.queryByStauts("0");
        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        for (int i = 0; i < list.size(); i++) {
            TaskDto acsTask = list.get(i);
            String taskid = acsTask.getTask_id();
            String taskcode = acsTask.getTask_code();
            String vehiclecode = acsTask.getVehicle_code();
            String priority = acsTask.getPriority();
            String start_point_code = acsTask.getStart_point_code();
            String start_device_code = acsTask.getStart_device_code();
            String route_plan_code = acsTask.getRoute_plan_code();
            String vehicleType = acsTask.getVehicle_type();
            //是否复合任务 =0非复合任务
            String compound_task = acsTask.getCompound_task();
            String compound_task_data = null;
            String next_point_code = acsTask.getNext_point_code();
            String next_device_code = acsTask.getNext_device_code();
            if (StrUtil.isEmpty(start_device_code)) {
                log.info("任务 [" + taskcode + "] 起点设备为空，无法生成指令。");
                acsTask.setRemark("任务 [" + taskcode + "] 起点设备为空，无法生成指令。");
                taskserver.updateByCodeFromCache(acsTask);
                continue;
            }
            if (StrUtil.isEmpty(next_device_code)) {
                log.info("任务 [" + taskcode + "] 终点设备为空，无法生成指令。");
                acsTask.setRemark("任务 [" + taskcode + "] 终点设备为空，无法生成指令。");
                taskserver.updateByCodeFromCache(acsTask);
                continue;
            }
            List<Instruction> instructions = instructionService.queryAll("instruction_status < 2");
            String maxInstnumber = acsConfigService.findByCode(AcsConfig.MAXINSTNUMBER).getValue();
            if (ObjectUtils.isNotEmpty(maxInstnumber)) {
                if (instructions.size() >= Integer.parseInt(maxInstnumber)) {
                    log.info("已达到系统参数配置的最大指令数 [" + maxInstnumber + "] ，无法生成指令。");
                    acsTask.setRemark("已达到系统参数配置的最大指令数 [" + maxInstnumber + "] ，无法生成指令。");
                    taskserver.updateByCodeFromCache(acsTask);
                    continue;
                }
            }


            /**
             * 开始平均分解校验
             */

//            if (StrUtil.isEmpty(this_device_code)) {
//                List<RouteLineDto> shortPathsList = routeLineService.getShortPathLines(start_device_code, acsTask.getNext_device_code(), route_plan_code);
//                RouteLineDto routeLineDto = shortPathsList.get(0);
//                String path = routeLineDto.getPath();
//                String type = routeLineDto.getType();
//                String[] str = path.split("->");
//                List<String> pathlist = Arrays.asList(str);
//                if (StrUtil.equals(acsTask.getTask_type(), "2")) {
//                    for (int j = 0; j < pathlist.size(); j++) {
//                        if (j == 0) {
//                            compound_task_data = pathlist.get(j).trim();
//                        } else {
//                            compound_task_data = compound_task_data + "->" + pathlist.get(j).trim();
//                        }
//                    }
//                    next_device_code = pathlist.get(pathlist.size() - 1);
//
//                } else {
//                    int index = 0;
//                    for (int m = 0; m < pathlist.size(); m++) {
//                        if (pathlist.get(m).equals(start_device_code)) {
//                            index = m + 1;
//                            break;
//                        }
//                    }
//                    next_device_code = pathlist.get(index);
//                }
//            } else {
            //  next_device_code = this_device_code;
            //  }
            //校验路由关系
            // List<RouteLineDto> shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code);
            //  if (ObjectUtils.isEmpty(shortPathsList)) {
            //  log.info("任务 [" + taskcode + "] 路由不通无法生成指令。");
            //  acsTask.setRemark("任务 [" + taskcode + "] 路由不通无法生成指令。");
            // taskserver.updateByCodeFromCache(acsTask);
            // continue;
            //  }

            //            if (!StrUtil.equals(shortPathsList.get(0).getType(), "1")) {
            //                continue;
            //            }
            Device startdevice = appService.findDeviceByCode(start_device_code);
            Device nextdevice = appService.findDeviceByCode(acsTask.getNext_device_code());
            if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) {
                next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z();
            } else {
                next_point_code = next_device_code;
            }
            if (ObjectUtils.isEmpty(startdevice)) {
                log.info("任务 [" + taskcode + "] 起点设备编码 [" + start_device_code + "] 对应设备未找到，无法生成指令。");
                continue;
            }
            if (ObjectUtils.isEmpty(nextdevice)) {
                log.info("任务 [" + taskcode + "] 终点设备编码 [" + next_device_code + "] 对应设备未找到，无法生成指令。");
                continue;
            }
            //普通站点
            StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
            StandardInspectSiteDeviceDriver standardInspectSiteDeviceDriver;
            String createTaskCheck = acsConfigService.findByCode(AcsConfig.CREATETASKCHECK).getValue();
            if (StrUtil.equals(createTaskCheck, "1")) {
                if (startdevice.getDeviceDriver() instanceof StandardInspectSiteDeviceDriver) {
                    standardInspectSiteDeviceDriver = (StandardInspectSiteDeviceDriver) startdevice.getDeviceDriver();
                    if (standardInspectSiteDeviceDriver.getMode() != 2) {
                        log.info("起点设备:" + startdevice.getDevice_code() + "设备未待机,任务号：" + taskcode);
                        acsTask.setRemark("起点设备:" + startdevice.getDevice_code() + "设备未待机,任务号：" + taskcode);
                        taskserver.updateByCodeFromCache(acsTask);
                        //this.execute_log.setResource(startdevice.getDevice_code(), startdevice.getDevice_code());
                        //this.execute_log.log("起点设备:" + startdevice.getDevice_code() + "设备未待机,任务号：" + taskcode);
                        continue;
                    }
                }
                //校验 是否同任务是否存在相同终点、未完成的指令
                int sameqty = instructionService.querySameDestinationInst(next_point_code);
                if (sameqty > 0) {
                    log.info("存在相同终点的指令,任务号：" + taskcode);
                    acsTask.setRemark("存在相同终点的指令,任务号：" + taskcode);
                    taskserver.updateByCodeFromCache(acsTask);
                    continue;
                }
            }
            Instruction instdto = new Instruction();
            instdto.setInstruction_type(acsTask.getTask_type());
            instdto.setInstruction_id(IdUtil.simpleUUID());
            instdto.setRoute_plan_code(route_plan_code);
            instdto.setRemark(acsTask.getRemark());
            instdto.setMaterial(acsTask.getMaterial());
            instdto.setQuantity(acsTask.getQuantity());
            instdto.setTask_id(taskid);
            instdto.setTask_code(taskcode);
            instdto.setVehicle_code(vehiclecode);
            String now = DateUtil.now();
            instdto.setCreate_time(now);
            instdto.setCreate_by("auto");
            instdto.setStart_device_code(start_device_code);
            instdto.setNext_device_code(next_device_code);
            instdto.setStart_point_code(start_point_code);
            instdto.setNext_point_code(next_point_code);
            instdto.setCompound_inst_data(compound_task_data);
            instdto.setPriority(priority);
            instdto.setInstruction_status("0");
            instdto.setExecute_device_code(start_point_code);
            instdto.setVehicle_type(vehicleType);
            try {
                instructionService.create(instdto);
            } catch (Exception e) {
                if (e.getMessage() == null) {
                    acsTask.setRemark("自动创建指令失败，失败原因:连接失败！");
                } else {
                    acsTask.setRemark("自动创建指令失败，失败原因:" + e.getMessage());
                }
                taskserver.updateByCodeFromCache(acsTask);
                continue;
            }
            log.info("任务 [" + taskcode + "] 指令成功生成！");
            //创建指令后修改任务状态
            acsTask.setTask_status("1");
            taskserver.update(acsTask);

        }
    }
}
