package org.wcs.quartzJob;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.wcs.business.stock.intf.IStockSingleTaskExecuteEvent;
import org.wcs.constant.enums.database.StockSingleTaskStatusEnum;
import org.wcs.constant.enums.database.StockSingleTaskTypeEnum;
import org.wcs.helper.PlcTaskIdHelper;
import org.wcs.mapper.intf.AppStockSingleTaskService;
import org.wcs.mapper.intf.AppTrayConveyLocationService;
import org.wcs.model.bo.tuple.Tuple2;
import org.wcs.model.po.app.AppStockSingleTask;
import org.wcs.model.po.app.AppTrayConveyLocation;
import org.wcs.plugin.plc.PlcCommunicationFactory;
import org.wcs.plugin.plc.model.TaskConveyStatus;
import org.wcs.plugin.plc.model.TaskConveyTask;
import org.wcs.utils.AppStringUtils;

import java.util.List;

/**
 * 托盘线定时任务
 */
@Slf4j
@DisallowConcurrentExecution
@RequiredArgsConstructor
public class TrayConveyJob implements Job {

    private final AppStockSingleTaskService stockSingleTaskService;
    private final AppTrayConveyLocationService trayConveyLocationService;
    private final IStockSingleTaskExecuteEvent stockSingleTaskExecuteEvent; // 独立任务执行 事件


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        executeTrayConveyTask(); // 执行托盘线任务
        checkCount(); // 检查托盘线过账
    }


    /**
     * 执行托盘线任务
     */
    private void executeTrayConveyTask() {
        List<AppStockSingleTask> stockSingleTasks = stockSingleTaskService.queryTask(StockSingleTaskTypeEnum.getAllConveyTaskType(), StockSingleTaskStatusEnum.CREATE.getCode());
        if(stockSingleTasks == null || stockSingleTasks.isEmpty()) {
            return;
        }
        for (AppStockSingleTask stockSingleTask : stockSingleTasks) {
            List<AppTrayConveyLocation> originLocationInfoList = trayConveyLocationService.getDataByLocationId(stockSingleTask.getOrigin());
            if(originLocationInfoList == null || originLocationInfoList.isEmpty()) {
                continue;
            }
            List<AppTrayConveyLocation> destinationLocationList = trayConveyLocationService.getDataByLocationId(stockSingleTask.getDestination());
            if(destinationLocationList == null || destinationLocationList.isEmpty()) {
                continue;
            }
            AppTrayConveyLocation originLocationInfo = originLocationInfoList.getFirst();
            AppTrayConveyLocation destinationLocationInfo = destinationLocationList.getFirst();
            Tuple2<String, TaskConveyStatus> originLocationStatusTuple = PlcCommunicationFactory.getPlcCommunicationByPlcId(originLocationInfo.getPlcId()).readTaskConveyStatus(originLocationInfo.getLocationId());
            if(originLocationStatusTuple == null || AppStringUtils.isNotEmpty(originLocationStatusTuple.item1) || originLocationStatusTuple.item2 == null) {
                log.warn("托盘线：{} 获取位置：{} 状态失败", originLocationInfo.getLocationId(), originLocationInfo.getLocationId());
                continue;
            }
            TaskConveyStatus originLocationStatus = originLocationStatusTuple.item2;
            if(originLocationStatus.getPlcTaskId() != 0 || originLocationStatus.getDeviceStatus() != 5 || originLocationStatus.getErrCode() != 0) {
                // 起点设备状态不满足
                continue;
            }
            Tuple2<String, TaskConveyStatus> destinationLocationStatusTuple = PlcCommunicationFactory.getPlcCommunicationByPlcId(destinationLocationInfo.getPlcId()).readTaskConveyStatus(destinationLocationInfo.getLocationId());
            if(destinationLocationStatusTuple == null || AppStringUtils.isNotEmpty(destinationLocationStatusTuple.item1) || destinationLocationStatusTuple.item2 == null) {
                log.warn("托盘线：{} 获取位置：{} 状态失败", destinationLocationInfo.getLocationId(), destinationLocationInfo.getLocationId());
                continue;
            }
            TaskConveyStatus destinationLocationStatus = destinationLocationStatusTuple.item2;
            if(destinationLocationStatus.getErrCode() != 0 || destinationLocationStatus.getDeviceStatus() != 5) {
                // 终点设备状态不满足
                continue;
            }
            // 构造并写入任务
            TaskConveyTask taskConveyTask = new TaskConveyTask();
            taskConveyTask.setPlcTaskId(stockSingleTask.getPlcTaskId());
            taskConveyTask.setTaskType(StockSingleTaskTypeEnum.conveyTaskTypeToPlc(stockSingleTask.getTaskType()));
            taskConveyTask.setOrigin(AppStringUtils.forceToShort(originLocationInfo.getLocationId()));
            taskConveyTask.setDestination(AppStringUtils.forceToShort(destinationLocationInfo.getLocationId()));
            taskConveyTask.setVehicleSize(stockSingleTask.getVehicleSize().shortValue());
            taskConveyTask.setWeight(stockSingleTask.getWeight().intValue());
            taskConveyTask.setVehicleNo(stockSingleTask.getVehicleNo());
            String writeTaskResult = PlcCommunicationFactory.getPlcCommunicationByPlcId(originLocationInfo.getPlcId()).writeTaskConveyTask(originLocationInfo.getLocationId(), taskConveyTask);
            if(AppStringUtils.isNotEmpty(writeTaskResult)) {
                log.warn("托盘线：{} 写入任务失败，载具号：{}。原因：{}", stockSingleTask.getTaskId(), stockSingleTask.getVehicleNo(), writeTaskResult);
                continue;
            }
            // 写入成功
            stockSingleTaskExecuteEvent.taskStart(stockSingleTask, "任务开始执行");
            // TODO LED 屏显示

        }
    }

    /**
     * 托盘线过账 ---- 检查终点位置托盘号
     */
    private void checkCount() {
        List<AppStockSingleTask> stockSingleTasks = stockSingleTaskService.queryTask(StockSingleTaskTypeEnum.getAllConveyTaskType(), StockSingleTaskStatusEnum.EXECUTING.getCode());
        if(stockSingleTasks == null || stockSingleTasks.isEmpty()) {
            return;
        }
        for (AppStockSingleTask stockSingleTask : stockSingleTasks) {
            List<AppTrayConveyLocation> destinationLocationList = trayConveyLocationService.getDataByLocationId(stockSingleTask.getDestination());
            if(destinationLocationList == null || destinationLocationList.isEmpty()) {
                continue;
            }
            AppTrayConveyLocation destinationLocationInfo = destinationLocationList.getFirst();
            Tuple2<String, TaskConveyStatus> destinationLocationStatusTuple = PlcCommunicationFactory.getPlcCommunicationByPlcId(destinationLocationInfo.getPlcId()).readTaskConveyStatus(destinationLocationInfo.getLocationId());
            if(destinationLocationStatusTuple == null || AppStringUtils.isNotEmpty(destinationLocationStatusTuple.item1) || destinationLocationStatusTuple.item2 == null) {
                log.warn("托盘线：{} 获取位置：{} 状态失败", destinationLocationInfo.getLocationId(), destinationLocationInfo.getLocationId());
                continue;
            }
            TaskConveyStatus destinationLocationStatus = destinationLocationStatusTuple.item2;
            Integer plcTaskId = destinationLocationStatus.getPlcTaskId();
            if(plcTaskId == 0) {
                // 终点设备任务号为0
                continue;
            }
            List<AppStockSingleTask> completeTaskList = stockSingleTaskService.queryByPlcTaskId(plcTaskId);
            if(completeTaskList == null || completeTaskList.isEmpty()) {
                continue;
            }
            for (AppStockSingleTask completeTask : completeTaskList) {
                // 正常这里应该只有一个
                stockSingleTaskExecuteEvent.taskFinish(completeTask, "任务完成");
                // TODO LED 屏显示
            }
        }
    }
}
