package com.wms_main.service.quartz_job.job_executor;

import java.time.LocalDateTime;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.constant.enums.wms.OrderStatusEnum;
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wms.WmsTaskTypeEnums;
import com.wms_main.dao.ITAppOrderInService;
import com.wms_main.dao.ITAppTaskService;
import com.wms_main.model.po.TAppLocation;
import com.wms_main.model.po.TAppOrderIn;
import com.wms_main.model.po.TAppTask;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.business.IStackerTaskService;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@PersistJobDataAfterExecution
// 以下注解用于实现fixed_delay
@DisallowConcurrentExecution
@RequiredArgsConstructor
public class MyInExecutor implements Job {
    private final ITAppOrderInService appOrderInService;
    private final IStackerTaskService stackerTaskService;
    private final ITAppTaskService appWmsTaskService;

    private static String ORIGIN = "R1";

    @Override
    public void execute(JobExecutionContext context) {
        processInOrders();
    }

    private void processInOrders() {
        List<TAppOrderIn> orders = appOrderInService.list(
                new LambdaQueryWrapper<TAppOrderIn>()
                        .eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode()));
        orders.forEach(this::processSingleOrder);
    }

    private void processSingleOrder(TAppOrderIn orderIn) {
        if (orderIn == null) {
            return;
        }
        /* 查找可用库位 */
        TAppLocation useLocation = stackerTaskService.requestOneLocation(null, orderIn.getVehicleNo());
        if (useLocation == null) {
            log.error("暂没有可以直接使用的库位，因为存在互锁的库位，请等待当前任务都执行完成后再试");
            return;
        }
        TAppTask newInTask = appWmsTaskService.getOne(new LambdaQueryWrapper<TAppTask>()
                .eq(TAppTask::getVehicleId, orderIn.getVehicleNo())
                .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode()));
        if (newInTask != null) {
            newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode());
            newInTask.setDestination(useLocation.getLocationId());
            newInTask.setTaskGroup(orderIn.getOrderId());
            if (!appWmsTaskService.updateById(newInTask)) {
                log.error("生成任务失败，无法插入新的入库任务");
                return;
            }
        } else {
            newInTask = new TAppTask();
            newInTask.setTaskId(UUIDUtils.getNewUUID());
            newInTask.setTaskGroup(orderIn.getOrderId());
            newInTask.setTaskType(WmsTaskTypeEnums.IN.getCode());
            newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode());
            newInTask.setOrigin(ORIGIN);
            newInTask.setDestination(useLocation.getLocationId());
            newInTask.setCreateTime(LocalDateTime.now());
            newInTask.setOpUser("wcs");
            newInTask.setVehicleId(orderIn.getVehicleNo());
            newInTask.setTaskPriority(1);

            if (!appWmsTaskService.save(newInTask)) {
                log.error("生成任务失败，无法插入新的入库任务");
                return;
            }
        }
        appOrderInService.update(
                new LambdaUpdateWrapper<TAppOrderIn>()
                        .eq(TAppOrderIn::getRecordId, orderIn.getRecordId())
                        .set(TAppOrderIn::getOrderStatus, OrderStatusEnum.RUNNING.getCode())
                        .set(TAppOrderIn::getUpdateTime, LocalDateTime.now()));
        return;
    }
}
