package com.wms.service.business.serviceImplements;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms.constants.enums.*;
import com.wms.entity.app.dto.extend.StockDetailInfo;
import com.wms.entity.app.dto.extend.TaskDetailInfo;
import com.wms.entity.app.request.GoodsInRequest;
import com.wms.entity.app.request.TaskInRequest;
import com.wms.entity.app.request.TaskOutRequest;
import com.wms.entity.table.*;
import com.wms.service.*;
import com.wms.service.business.IWmsTaskService;
import com.wms.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.wms.constants.WmsConstants.MYSQL_JSON_CI;
import static com.wms.utils.StringUtils.convertJsonString;
import static com.wms.utils.WmsUtils.generateId;

/**
 * WMS任务服务实现
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WmsTaskServiceImplements implements IWmsTaskService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志
    private final VehicleService vehicleService;// 载具服务
    private final TaskService taskService;// 任务服务
    private final LocationService locationService;// 库位服务
    private final StockService stockService;// 库存服务
    private final GoodsService goodsService;// 物料服务
    private final OutsideVehiclesService outsideVehiclesService;// 流转中的箱子服务
    private final PickTaskService pickTaskService;// 拣选任务服务
    private final StandService standService;// 站台服务


    /**
     * 添加空入库任务
     *
     * @param taskInRequest 入库请求
     * @return 添加结果
     */
    @Override
    public String genEmptyInTask(TaskInRequest taskInRequest) {
        String result = "";
        Task tempInTask = new Task();
        tempInTask.setTaskId(generateId("RK_"));
        tempInTask.setTaskType(TaskType.IN.getCode());
        tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode());
        tempInTask.setTaskGroup(generateId(""));
        tempInTask.setTaskPriority(1);
        tempInTask.setVehicleId(taskInRequest.getVehicleId());
        tempInTask.setVehicleSize(1);
        tempInTask.setWeight(taskInRequest.getTotalWeight());
        tempInTask.setCreateTime(LocalDateTime.now());
        tempInTask.setUserName(taskInRequest.getUserName());
        try {
            if (!taskService.save(tempInTask)) {
                result = "添加空入库任务失败";
            }
        } catch (Exception e) {
            logger.error("添加空入库任务异常：{}", convertJsonString(e));
            result = "添加空入库任务失败";
        }
        return result;
    }

    /**
     * 添加入库任务
     *
     * @param taskInRequest 入库请求
     * @param sameVehicleTask 相同载具任务
     * @return 添加结果
     */
    @Override
    public String genGoodsInTask(TaskInRequest taskInRequest, Task sameVehicleTask) {
        String result = "";
        String taskGroupId = sameVehicleTask != null ? sameVehicleTask.getTaskGroup() : generateId("");
        List<Task> tempTasks = new ArrayList<>();
        for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) {
            Task tempInTask = new Task();
            tempInTask.setTaskId(generateId("RK_"));
            tempInTask.setTaskType(TaskType.IN.getCode());
            tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode());
            tempInTask.setTaskGroup(taskGroupId);
            tempInTask.setTaskPriority(1);
            tempInTask.setVehicleId(taskInRequest.getVehicleId());
            tempInTask.setVehicleSize(1);
            tempInTask.setWeight(taskInRequest.getTotalWeight());
            tempInTask.setCreateTime(LocalDateTime.now());
            tempInTask.setUserName(taskInRequest.getUserName());
            // 物料相关信息
            TaskDetailInfo goodsRelatedInfo = new TaskDetailInfo();
            // 查询物料信息
            Goods goods = goodsService.getOne(new LambdaQueryWrapper<Goods>().eq(Goods::getGoodsId, goodsInRequest.getGoodsId()));
            // TODO 物料信息需要完善
            goodsRelatedInfo.setGoodsId(goods.getGoodsId());
            goodsRelatedInfo.setGoodsName(goods.getGoodsName());
            goodsRelatedInfo.setOpNum(goodsInRequest.getGoodsNum());
            goodsRelatedInfo.setOriginNum(BigDecimal.ZERO);
            tempInTask.setGoodsRelated(goodsRelatedInfo);

            tempTasks.add(tempInTask);
        }

        try {
            if (!taskService.saveBatch(tempTasks)) {
                return "添加入库任务失败";
            }
        } catch (Exception e) {
            logger.error("添加入库任务异常：{}", convertJsonString(e));
            return "添加入库任务失败";
        }
        return result;
    }

    /**
     * 生成载具或库位出库任务
     *
     * @param taskOutRequest 出库请求
     * @return 结果
     */
    @Override
    public String genVehicleLocationOutTask(TaskOutRequest taskOutRequest) {
        // 查询对应载具
        if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) {
            Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
            // 创建空出库任务
            Task vehicleOutTask = new Task();
            vehicleOutTask.setTaskId(generateId("CK_"));
            vehicleOutTask.setTaskType(TaskType.OUT.getCode());
            vehicleOutTask.setTaskGroup(generateId(""));
            vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
            vehicleOutTask.setTaskPriority(1);
            vehicleOutTask.setVehicleId(taskOutRequest.getVehicleId());
            vehicleOutTask.setUserName(taskOutRequest.getUserName());
            vehicleOutTask.setOrigin(currentVehicle.getCurrentLocation());
            vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
            vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
            vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
            vehicleOutTask.setCreateTime(LocalDateTime.now());
            taskService.save(vehicleOutTask);
            // 对应载具所有库存上锁
            stockService.update(new LambdaUpdateWrapper<Stock>()
                    .set(Stock::getStockStatus, StockStatus.OUT.getCode())
                    .eq(Stock::getVehicleId, taskOutRequest.getVehicleId()));
            // 对应载具状态设置
            vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                    .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
                    .eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()));
        } else {
            // 查找对应库位
            Location currentLocation = locationService.getOne(new LambdaQueryWrapper<Location>().eq(Location::getLocationId, taskOutRequest.getOriginPoint()));
            // 创建空出库任务
            Task vehicleOutTask = new Task();
            vehicleOutTask.setTaskId(generateId("CK_"));
            vehicleOutTask.setTaskType(TaskType.OUT.getCode());
            vehicleOutTask.setTaskGroup(generateId(""));
            vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
            vehicleOutTask.setTaskPriority(1);
            vehicleOutTask.setVehicleId(currentLocation.getVehicleId());
            vehicleOutTask.setUserName(taskOutRequest.getUserName());
            vehicleOutTask.setOrigin(currentLocation.getLocationId());
            vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
            vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
            vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
            vehicleOutTask.setCreateTime(LocalDateTime.now());
            taskService.save(vehicleOutTask);
            // 对应库位所有库存上锁
            stockService.update(new LambdaUpdateWrapper<Stock>()
                    .set(Stock::getStockStatus, StockStatus.OUT.getCode())
                    .eq(Stock::getLocationId, taskOutRequest.getOriginPoint()));
            // 对应库位状态设置
            vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                    .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
                    .eq(Vehicle::getCurrentLocation, taskOutRequest.getOriginPoint()));
        }
        return "";
    }
    /**
     * 生成物料出库任务
     *
     * @param taskOutRequest 出库请求
     * @return 结果
     */
    @Override
    public String genGoodsOutTask(TaskOutRequest taskOutRequest) {
        // 查询库存
        LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<Stock>()
                .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, taskOutRequest.getGoodsId())
                .apply("goods_related ->> '$.remainNum' > 0")
                .eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId())
                .eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint());
        List<Stock> stocks = stockService.list(stockQueryWrapper);
        List<Task> goodsOutTasks = new ArrayList<>();
        BigDecimal needNum = taskOutRequest.getGoodsNum();
        for (Stock stock : stocks) {
            if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {// 库存状态正常的情况
                // 悲观锁，锁定库存状态---同一载具下的库存
                boolean lockStocksFlag = stockService.update(new LambdaUpdateWrapper<Stock>()
                        .set(Stock::getStockStatus, StockStatus.OUT.getCode())
                        .eq(Stock::getVehicleId, stock.getVehicleId())
                        .eq(Stock::getStockStatus, StockStatus.OK.getCode()));

                // 锁定载具状态
                boolean lockVehicleFlag = vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                        .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
                        .eq(Vehicle::getVehicleId, stock.getVehicleId())
                        .eq(Vehicle::getVehicleStatus, VehicleStatus.ON));
                if (!lockStocksFlag || !lockVehicleFlag) {
                    // 释放锁
                    stockService.update(new LambdaUpdateWrapper<Stock>()
                            .set(Stock::getStockStatus, StockStatus.OK.getCode())
                            .eq(Stock::getVehicleId, stock.getVehicleId())
                            .eq(Stock::getStockStatus, StockStatus.OK.getCode()));
                    vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                            .set(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())
                            .eq(Vehicle::getVehicleId, stock.getVehicleId()));
                    continue;
                }
                // 创建出库任务
                Task vehicleOutTask = new Task();
                vehicleOutTask.setTaskId(generateId("CK_"));
                vehicleOutTask.setTaskType(TaskType.OUT.getCode());
                vehicleOutTask.setTaskGroup(generateId(""));
                vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
                vehicleOutTask.setTaskPriority(1);
                vehicleOutTask.setVehicleId(stock.getVehicleId());
                vehicleOutTask.setUserName(taskOutRequest.getUserName());
                vehicleOutTask.setOrigin(stock.getLocationId());
                vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
                vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
                vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
                vehicleOutTask.setCreateTime(LocalDateTime.now());
                // TODO 设定物料相关信息 需要完善
                TaskDetailInfo taskDetailInfo = new TaskDetailInfo();
                taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId());
                taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName());
                taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum);
                taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum());
                vehicleOutTask.setGoodsRelated(taskDetailInfo);
                goodsOutTasks.add(vehicleOutTask);
                needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum());
            } else if (Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) {
                // 查询到当前当前载具对应的任务，并同步
                Task sameVehicleTask = taskService.getOne(new LambdaQueryWrapper<Task>()
                        .eq(Task::getVehicleId, stock.getVehicleId())
                        .last("limit 1"));
                // 创建出库任务
                Task vehicleOutTask = new Task();
                vehicleOutTask.setTaskId(generateId("CK_"));
                vehicleOutTask.setTaskType(TaskType.OUT.getCode());
                if (sameVehicleTask != null) {
                    vehicleOutTask.setTaskGroup(sameVehicleTask.getTaskGroup());
                    vehicleOutTask.setTaskStatus(sameVehicleTask.getTaskStatus());
                    vehicleOutTask.setTaskPriority(sameVehicleTask.getTaskPriority());
                    vehicleOutTask.setPreTask(sameVehicleTask.getPreTask());
                } else {
                    vehicleOutTask.setTaskGroup(generateId(""));
                    vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
                    vehicleOutTask.setTaskPriority(1);
                }
                vehicleOutTask.setVehicleId(stock.getVehicleId());
                vehicleOutTask.setUserName(taskOutRequest.getUserName());
                vehicleOutTask.setOrigin(stock.getLocationId());
                vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint());
                vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking());
                vehicleOutTask.setPickStand(taskOutRequest.getPickStand());
                vehicleOutTask.setCreateTime(LocalDateTime.now());
                // TODO 设定物料相关信息 需要完善
                TaskDetailInfo taskDetailInfo = new TaskDetailInfo();
                taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId());
                taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName());
                taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum);
                taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum());
                vehicleOutTask.setGoodsRelated(taskDetailInfo);
                goodsOutTasks.add(vehicleOutTask);
                needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum());
            }
            // 盘点,移库,锁定状态不可使用
            if (needNum.compareTo(BigDecimal.ZERO) <= 0) {
                // 库存足够，跳出循环
                break;
            }
        }
        // 添加任务记录表
        taskService.saveBatch(goodsOutTasks);
        return "";
    }

    @Override
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public BigDecimal callGoods(String goodsId, BigDecimal needNum, String workStation) {
        BigDecimal originNum = needNum;// 原始数量
        try {
            // 判断当前物料是否在流转中
            List<OutsideVehicles> outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
                    .eq(OutsideVehicles::getGoodsId, goodsId)
                    .gt(OutsideVehicles::getRemainNum, 0)
                    .ne(OutsideVehicles::getOutStatus, 2));
            List<OutsideVehicles> usedOutsideVehiclesList = new ArrayList<>();
            if (outsideVehiclesList != null && !outsideVehiclesList.isEmpty()) {
                // 存在流转中的料箱
                for (OutsideVehicles outsideVehicle : outsideVehiclesList) {
                    if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0
                        break;
                    }
                    // 查询当前料箱当前物料的库存
                    Stock stock = stockService.getOne(new LambdaQueryWrapper<Stock>()
                            .eq(Stock::getVehicleId, outsideVehicle.getVehicleId())
                            .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId)
                            .apply("goods_related ->> '$.remainNum' > 0")
                            .last("limit 1"));
                    if (stock == null) {
                        // 没有库存
                        outsideVehiclesService.removeById(outsideVehicle);
                    } else {
                        // 库存状态为正常
                        if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {
                            outsideVehiclesService.removeById(outsideVehicle);
                            continue;
                        }
                        if (outsideVehicle.getRemainNum().compareTo(needNum) > 0) {
                            // 当前箱子剩余物料数量多于需求数量
                            needNum = BigDecimal.ZERO;
                            outsideVehicle.setRemainNum(outsideVehicle.getRemainNum().subtract(needNum));
                            usedOutsideVehiclesList.add(outsideVehicle);
                            break;
                        } else {
                            // 当前箱子物料剩余数量少于需求数量
                            needNum = needNum.subtract(outsideVehicle.getRemainNum());
                            outsideVehicle.setRemainNum(BigDecimal.ZERO);
                            usedOutsideVehiclesList.add(outsideVehicle);
                        }
                    }
                }
                // 更新流转箱表
                outsideVehiclesService.updateBatchById(usedOutsideVehiclesList);
                // 生成拣选任务
                List<String> vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).distinct().toList();
                createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.NEW.getCode());
            }
            return needNum;
        } catch (Exception e) {
            logger.error("呼叫物料时发生异常：{}", convertJsonString(e));
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return originNum;
        }

    }

    @Override
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation) {
        BigDecimal originNum = needNum;// 原始数量
        try {
            // 判断当前这个料是否已经有outsideVehicles
            List<OutsideVehicles> outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
                    .eq(OutsideVehicles::getGoodsId, goodsId)
                    .ne(OutsideVehicles::getOutStatus, 2));
            if (!outsideVehiclesList.isEmpty()) {
                boolean canCallStock = true;
                // 判断这些outsideVehicles对应的库存是不是都是0
                for (OutsideVehicles outsideVehicle : outsideVehiclesList) {
                    Stock stock = stockService.getOne(new LambdaQueryWrapper<Stock>()
                            .eq(Stock::getVehicleId, outsideVehicle.getVehicleId())
                            .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId)
                            .apply("goods_related ->> '$.remainNum' > 0")
                            .last("limit 1"));
                    if (stock != null) {
                        canCallStock = false;
                        break;
                    }
                }
                // 不能呼叫库存
                if (!canCallStock) {
                    return needNum;
                }
            }
            // 查询库存，判断数量是否充足
            List<Stock> stockList = stockService.list(new LambdaQueryWrapper<Stock>()
                    .eq(Stock::getStockStatus, StockStatus.OK.getCode())
                    .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId)
                    .apply("goods_related ->> '$.remainNum' > 0")
                    .orderByAsc(Stock::getCreateTime));
            if (stockList != null && !stockList.isEmpty()) {
                List<Stock> waitForOutStockList = new ArrayList<>();
                // 尝试生成出库任务
                for (Stock tempStock : stockList) {
                    if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0
                        break;
                    }
                    if (tempStock.getGoodsRelated().getRemainNum().compareTo(needNum) > 0) {
                        // 当前箱子剩余物料数量多于需求数量
                        needNum = BigDecimal.ZERO;
                        // 设置剩余数量
                        StockDetailInfo goodsRelated = tempStock.getGoodsRelated();
                        goodsRelated.setRemainNum(goodsRelated.getRemainNum().subtract(needNum));
                        tempStock.setGoodsRelated(goodsRelated);
                    } else {
                        // 当前箱子物料剩余数量少于需求数量
                        needNum = needNum.subtract(tempStock.getGoodsRelated().getRemainNum());
                        // 设置剩余数量
                        StockDetailInfo goodsRelated = tempStock.getGoodsRelated();
                        goodsRelated.setRemainNum(BigDecimal.ZERO);
                        tempStock.setGoodsRelated(goodsRelated);
                    }
                    waitForOutStockList.add(tempStock);
                    break;
                }
                createVehicleOutTaskAndPickTask(waitForOutStockList, workStation);
            }
            return needNum;
        } catch (Exception ex) {
            logger.error("呼叫库存时发生异常：{}", convertJsonString(ex));
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return originNum;
        }
    }

    /**
     * 生成出库任务，同时生成拣选任务
     *
     * @param waitForOutStocks 待出库库存
     */
    private void createVehicleOutTaskAndPickTask(List<Stock> waitForOutStocks, String workStation) {
        // 出库任务列表
        List<Task> outTasks = new ArrayList<>();
        // 流转载具列表
        List<OutsideVehicles> outsideVehicles = new ArrayList<>();
        // 载具列表
        List<String> vehicleIds = new ArrayList<>();
        for (Stock tempStock : waitForOutStocks) {
            if (vehicleIds.contains(tempStock.getVehicleId())) {
                continue;
            }
            // 创建出库任务
            Task tempOutTask = new Task();
            tempOutTask.setTaskId(generateId("CK_"));
            tempOutTask.setTaskType(TaskType.OUT.getCode());
            tempOutTask.setTaskGroup(generateId(""));
            tempOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
            tempOutTask.setTaskPriority(1);
            tempOutTask.setVehicleId(tempStock.getVehicleId());
            tempOutTask.setUserName("WMS_AUTO");
            tempOutTask.setOrigin(tempStock.getLocationId());
            tempOutTask.setDestination("");
            tempOutTask.setCreateTime(LocalDateTime.now());
            tempOutTask.setIsPicking(1);
            tempOutTask.setPickStand(workStation);
            outTasks.add(tempOutTask);
            // 添加载具列表
            vehicleIds.add(tempStock.getVehicleId());
            // 添加流转箱数据
            OutsideVehicles outsideVehicle = new OutsideVehicles();
            outsideVehicle.setOutsideId(generateId("OUTSIDE_"));
            outsideVehicle.setVehicleId(tempStock.getVehicleId());
            outsideVehicle.setGoodsId(tempStock.getGoodsRelated().getGoodsId());
            outsideVehicle.setRemainNum(tempStock.getGoodsRelated().getRemainNum());
            outsideVehicle.setOutStatus(0);
            outsideVehicles.add(outsideVehicle);
        }
        for (String vehicleId : vehicleIds) {
            // 查询到对应的库存信息
            List<Stock> vehicleStocks = stockService.list(new LambdaQueryWrapper<Stock>()
                    .eq(Stock::getVehicleId, vehicleId)
                    .eq(Stock::getStockStatus, 0));
            for (Stock vehicleStock : vehicleStocks) {
                if (outsideVehicles.stream().anyMatch(outsideVehicle -> outsideVehicle.getVehicleId().equals(vehicleStock.getVehicleId()) && outsideVehicle.getGoodsId().equals(vehicleStock.getGoodsRelated().getGoodsId()))) {
                    // 已经生成过
                    continue;
                }
                // 添加流转箱数据
                OutsideVehicles outsideVehicle = new OutsideVehicles();
                outsideVehicle.setOutsideId(generateId("OUTSIDE_"));
                outsideVehicle.setVehicleId(vehicleStock.getVehicleId());
                outsideVehicle.setGoodsId(vehicleStock.getGoodsRelated().getGoodsId());
                outsideVehicle.setRemainNum(vehicleStock.getGoodsRelated().getRemainNum());
                outsideVehicle.setOutStatus(0);
                outsideVehicles.add(outsideVehicle);
            }
        }
        // 保存出库任务至任务表
        taskService.saveBatch(outTasks);
        // 更新载具信息
        vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
                .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
                .in(Vehicle::getVehicleId, vehicleIds)
                .eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode()));
        // 更新库存信息
        stockService.update(new LambdaUpdateWrapper<Stock>()
                .set(Stock::getStockStatus, StockStatus.OUT.getCode())
                .in(Stock::getVehicleId, vehicleIds)
                .eq(Stock::getStockStatus, StockStatus.OK.getCode()));
        // 保存流转箱信息
        outsideVehiclesService.saveBatch(outsideVehicles);
        // 保存拣选任务至拣选任务表
        createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.TEMP.getCode());
    }

    /**
     * 生成拣选任务
     *
     * @param vehicleIds  载具列表
     * @param workStation 工作站台
     * @param pickStatus  任务状态：只接受-1、0。-1：暂存不发送，0：可发送
     */
    public void createPickTasks(List<String> vehicleIds, String workStation, Integer pickStatus) {
        if (!Objects.equals(pickStatus, PickTaskStatusEnum.TEMP.getCode()) && !Objects.equals(pickStatus, PickTaskStatusEnum.NEW.getCode())) {
            return;
        }
        // 这里查询所有拣选任务
        List<PickTask> allPickTasks = pickTaskService.list();
        // 所有的暂存箱子
        List<String> tempPickVehicles = allPickTasks.stream().filter(pickTask -> Objects.equals(pickTask.getPickStatus(), PickTaskStatusEnum.TEMP.getCode())).map(PickTask::getVehicleId).distinct().toList();
        // 之前下发过的当前站台的任务
        Map<String, PickTask> currentStandPickTasksMap = allPickTasks.stream().filter(pickTask -> pickTask.getStandId().equals(workStation)).collect(Collectors.toMap(pickTask -> pickTask.getVehicleId() + "_" + pickTask.getStandId(), pickTask -> pickTask));
        // 拣选任务暂存列表
        Map<String, PickTask> pickTaskMap = new HashMap<>();
        // 查询出这些箱子
        List<OutsideVehicles> outsideVehicles = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
                .in(OutsideVehicles::getVehicleId, vehicleIds));
        // 增加的拣选任务数量
        int addNum = 0;
        for (String vehicleId : vehicleIds) {
            String key = vehicleId + "_" + workStation;
            // 之前已经下发过同一箱子同一站台的任务，不再下发
            if (currentStandPickTasksMap.containsKey(key)) {
                continue;
            }
            // 此次新建的保存过
            if (pickTaskMap.containsKey(key)) {
                continue;
            }
            // 暂存拣选任务
            PickTask tempPickTask = new PickTask();
            tempPickTask.setPickTaskId(key);
            tempPickTask.setVehicleId(vehicleId);
            tempPickTask.setStandId(workStation);
            if (tempPickVehicles.contains(vehicleId)) {
                tempPickTask.setPickStatus(PickTaskStatusEnum.TEMP.getCode());
            } else {
                tempPickTask.setPickStatus(pickStatus);
            }
            tempPickTask.setLastUpdateTime(LocalDateTime.now());
            pickTaskMap.put(key, tempPickTask);
            if (!Objects.equals(tempPickTask.getPickStatus(), PickTaskStatusEnum.TEMP.getCode())) {
                addNum++;
            } else {
                List<OutsideVehicles> currentOutsideVehicles = outsideVehicles.stream().filter(outsideVehicle ->
                        outsideVehicle.getVehicleId().equals(vehicleId) && outsideVehicle.getOutStatus().equals(1)).toList();
                if (!currentOutsideVehicles.isEmpty()) {
                    // 已经下发出库任务，计数+1
                    addNum++;
                }
            }
        }
        // 添加数据库
        if (!pickTaskMap.isEmpty()) {
            pickTaskService.saveOrUpdateBatch(pickTaskMap.values());
            // 更新站台的拣选数量
            standService.update(new LambdaUpdateWrapper<Stand>()
                    .setSql("pick_vehicle_count = pick_vehicle_count + " + addNum)
                    .eq(Stand::getStandId, workStation));
        }
    }
}
