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.WcsConveyTaskTypeEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
import com.wms_main.constant.enums.wms.OrderStatusEnum;
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.TAppOrderOut;
import com.wms_main.model.po.TAppStock;
import com.wms_main.model.po.TAppWcsTask;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;

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 YcOutExecutor 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) {
            String strId = orderOut.getGoodsId();
            if (strId != null && strId.length() <= 3) {
                _resolveGoodsId(orderOut);
            } else if (strId != null) {
                _resolveVehicleId(orderOut);
            }
        }
    }

    private void _resolveGoodsId(TAppOrderOut orderOut) {
        Double needQuantity = orderOut.getQuantity();
        if (needQuantity == null || needQuantity < 1) {
            return;
        }
        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());
            return;
        }
        List<TAppWcsTask> compWcsTasks = wcsTaskService.list(
                new LambdaQueryWrapper<TAppWcsTask>()
                        .eq(TAppWcsTask::getWcsTaskType, WmsTaskTypeEnums.OUT.getCode())
        );
        List<String> compVehicleIds = compWcsTasks.stream().map(TAppWcsTask::getVehicleId).distinct().toList();
        for (String vehicleId : vehicleIds) {
            if (compVehicleIds.contains(vehicleId)) {
                continue;
            }
            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<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(WcsStackerTaskTypeEnums.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());
            wcsTask.setRemark(orderOut.getRemark());
            wcsTasks.add(wcsTask);
        }

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

    private void _resolveVehicleId(TAppOrderOut orderOut) {
        String vehicleId = orderOut.getGoodsId();
        List<TAppStock> stocks = stockService.list(new LambdaQueryWrapper<TAppStock>().eq(TAppStock::getVehicleId, vehicleId));
        if (stocks == null) {
            log.warn("数据库连接异常");
            return;
        } else if (stocks.isEmpty()) {
            log.warn("载具{} 无库存", vehicleId);
            return;
        }
        TAppWcsTask wcsTask = new TAppWcsTask();
        wcsTask.setWcsTaskId(UUIDUtils.getNewUUID());
        wcsTask.setWcsTaskType(WcsStackerTaskTypeEnums.OUT.getCode());
        wcsTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.INIT.getCode());
        wcsTask.setTaskPriority(1);
        wcsTask.setVehicleId(vehicleId);
        wcsTask.setOrderId(orderOut.getOrderId());
        wcsTask.setCreateTime(LocalDateTime.now());
        wcsTask.setOrigin(stocks.getFirst().getLocationId());
        wcsTask.setDestination(stocks.getFirst().getBarCode());
        wcsTask.setRemark(orderOut.getRemark());

        orderOut.setOrderStatus(OrderStatusEnum.RUNNING.getCode());
        orderOutService.updateById(orderOut);
        wcsTaskService.save(wcsTask);
        stockService.update(
                new LambdaUpdateWrapper<TAppStock>()
                        .eq(TAppStock::getVehicleId, vehicleId)
                        .set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTING.getCode()));
    }
}
