package com.wms_main.service.quartz_job.job_executor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wms.OrderStatusEnum;
import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wms.WmsStockStatusEnums;
import com.wms_main.constant.enums.wms.WmsTaskTypeEnums;
import com.wms_main.dao.ITAppOrderOutService;
import com.wms_main.dao.ITAppStockService;
import com.wms_main.dao.ITAppTaskService;
import com.wms_main.dao.ITAppWcsTaskService;
import com.wms_main.model.po.*;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.quartz_job.IOutsExecutorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 定时任务定义类---出库单解析类
 */
@Slf4j
@PersistJobDataAfterExecution
// 以下注解用于实现fixed_delay
@DisallowConcurrentExecution
@RequiredArgsConstructor
public class OutsExecutor implements Job {

    private final ITAppOrderOutService orderOutService;
    private final ITAppStockService stockService;
    private final ITAppTaskService taskService;
    private final ITAppWcsTaskService wcsTaskService;

    /**
     * 运行定时任务
     *
     * @param jobExecutionContext 定时任务执行的环境（上下文）
     */
    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        // 处理出库单
        try {
            executeOrderOut();
        } catch (Exception e) {
            log.error("处理出库单失败{}", StringUtils.objectToString(e));
        }
    }

    /**
     * 解析出库单
     */
    private void executeOrderOut() {
        List<TAppOrderOut> orderOutsList = orderOutService.getWithStatus(OrderStatusEnum.CREATE.getCode());
        if(orderOutsList == null || orderOutsList.isEmpty()) {
            return;
        }
        for(TAppOrderOut orderOut : orderOutsList) {
            Double needQuantity = orderOut.getQuantity();
            if(needQuantity == null || needQuantity < 1 ) {
                continue;
            }
            TAppStock stock = new TAppStock();
            stock.setGoodsId(orderOut.getGoodsId());
            stock.setSled(orderOut.getSpecification());
            List<TAppStock> stockList = stockService.getWithEntity(stock);
            // 提取所有相关库存的载具号
            List<String> vehicleIds = stockList.stream().map(TAppStock::getVehicleId).distinct().toList();
            List<TAppStock> outStockList = new ArrayList<TAppStock>();
            if(vehicleIds.isEmpty()) {
                log.warn("缺少库存, goodsId is {}, batch is {}, specification is {}", orderOut.getGoodsId(), orderOut.getBatch(), orderOut.getSpecification());
                continue;
            }
            for (String vehicleId : vehicleIds) {
                List<TAppStock> stockListToOut = stockService.list(new LambdaQueryWrapper<TAppStock>().eq(TAppStock::getVehicleId, vehicleId));
                for (TAppStock stockItem : stockListToOut) {
                    if (needQuantity <= 0) break;
                    if (stockItem == null) {
                        continue;
                    }
                    if (stockItem.getGoodsId().equals(orderOut.getGoodsId()) && stockItem.getStockStatus().equals(WmsStockStatusEnums.OK.getCode())) {
                        needQuantity -= stockItem.getTotalNum();
                    }
                    stockItem.setStockStatus(WmsStockStatusEnums.OUTING.getCode());
                    outStockList.add(stockItem);
                }
            }

//            List<TAppTask> appTaskList = new ArrayList<>();
//            for (TAppStock stockItem : outStockList) {
//                TAppTask appTask = new TAppTask();
//                appTask.setTaskId(UUIDUtils.getNewUUID());
//                appTask.setTaskType(WmsTaskTypeEnums.OUT.getCode());
//                appTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode());
//                appTask.setTaskPriority(1);
//                appTask.setVehicleId(stockItem.getVehicleId());
//                appTask.setOrigin(stockItem.getLocationId());
//                appTask.setDestination(stockItem.getBarCode());
//                appTask.setGoodsId(stockItem.getGoodsId());
//                appTask.setBatch(stockItem.getBatch());
//                appTask.setCreateTime(LocalDateTime.now());
//                appTask.setOpNum(stockItem.getRealNum());
//                appTask.setStockNum(0);
//                appTask.setOpUser("wms_order_out");
//                appTask.setBatch(orderOut.getBatch());
//                appTask.setCallStand(stockItem.getBarCode());
//                appTaskList.add(appTask);
//            }
            List<TAppWcsTask> wcsTasks = new ArrayList<>();
            Map<String, List<TAppStock>> vehicleIdToStockMap = outStockList.stream()
                    .filter(stockMap -> Objects.equals(stockMap.getStockStatus(), WmsStockStatusEnums.OUTING.getCode()))
                    .collect(Collectors.groupingBy(TAppStock::getVehicleId));

            for (String vehicleId : vehicleIdToStockMap.keySet()) {
                List<TAppStock> stocks = vehicleIdToStockMap.get(vehicleId);
                TAppWcsTask wcsTask = new TAppWcsTask();
                wcsTask.setWcsTaskId(UUIDUtils.getNewUUID());
                wcsTask.setWcsTaskType(WmsTaskTypeEnums.OUT.getCode());
                wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.INIT.getCode());
                wcsTask.setTaskPriority(1);
                wcsTask.setVehicleId(stocks.getFirst().getVehicleId());
                wcsTask.setOrderId(orderOut.getOrderId());
                wcsTask.setCreateTime(LocalDateTime.now());
                wcsTask.setOrigin(stocks.getFirst().getLocationId());
                wcsTask.setDestination(stocks.getFirst().getBarCode());
                wcsTasks.add(wcsTask);
            }

            orderOut.setOrderStatus(OrderStatusEnum.RUNNING.getCode());
            orderOutService.updateById(orderOut);
            wcsTaskService.saveBatch(wcsTasks);
            stockService.updateBatchById(outStockList);
        }
    }
}
