package com.wms_main.service.business.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.app.AppCommon;
import com.wms_main.constant.enums.wms.AppConfigKeyEnums;
import com.wms_main.dao.ITAppStockService;
import com.wms_main.dao.ITAppStockUpdateService;
import com.wms_main.dao.ITAppVehicleService;
import com.wms_main.model.bo.wms.StockConfirmEntity;
import com.wms_main.model.po.TAppGoods;
import com.wms_main.model.po.TAppStock;
import com.wms_main.model.po.TAppStockUpdate;
import com.wms_main.model.po.TAppVehicle;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.business.IStockDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 库存数据服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class StockDataServiceImpl implements IStockDataService {
    private final ITAppStockService appStockService;// 库存服务
    private final ITAppVehicleService appVehicleService;// 载具服务
    private final AppCommon appCommon;// app通用数据
    private final ITAppStockUpdateService appStockUpdateService;// 库存更新服务

    /**
     * 更新库存信息 实现
     * @param stockConfirm 库存确认信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStockInfo(StockConfirmEntity stockConfirm, String standId, String userName, String reason, String inventoryId) {
        if (stockConfirm == null || StringUtils.isEmpty(stockConfirm.getVehicleId()) || StringUtils.isEmpty(stockConfirm.getGoodsId())
                || stockConfirm.getRealRemainQty() == null) {
            return;
        }
        // 查询对应的库存信息
        List<TAppStock> stockList = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                .eq(TAppStock::getVehicleId, stockConfirm.getVehicleId())
                .eq(TAppStock::getGoodsId, stockConfirm.getGoodsId())
                .orderByDesc(TAppStock::getFirstInTime)
        );
        // 更新列表
        List<TAppStock> removeStocks = new ArrayList<>();
        List<TAppStock> updateStocks = new ArrayList<>();
        // 库存更新记录列表
        List<TAppStockUpdate> stockUpdateList = new ArrayList<>();
        // 剩余数量
        int remainQty = stockConfirm.getRealRemainQty();
        for (int i = 0; i < stockList.size(); i++) {
            TAppStock stock = stockList.get(i);
            if (StringUtils.isNotEmpty(inventoryId)) {
                stock.setLastInventoryId(inventoryId);
                stock.setLastInventoryTime(LocalDateTime.now());
            }
            if (remainQty <= 0) {
                // 需要移除的库存
                removeStocks.add(stock);
                // 增加库存更新记录
                TAppStockUpdate stockUpdate = new TAppStockUpdate(
                        UUIDUtils.getNewUUID(),
                        stock.getVehicleId(),
                        stock.getGoodsId(),
                        stock.getFirstInTime(),
                        stock.getRealNum(),
                        0,
                        standId + "：" + reason,
                        LocalDateTime.now(),
                        userName
                );
                stockUpdateList.add(stockUpdate);
                continue;
            }
            if ((i == stockList.size() - 1) || stock.getRealNum() > remainQty) {
                // 最先进的库存，剩余数量全部分配给他
                TAppStockUpdate stockUpdate = new TAppStockUpdate(
                        UUIDUtils.getNewUUID(),
                        stock.getVehicleId(),
                        stock.getGoodsId(),
                        stock.getFirstInTime(),
                        stock.getRealNum(),
                        remainQty,
                        standId + "：" + reason,
                        LocalDateTime.now(),
                        userName
                );
                stockUpdateList.add(stockUpdate);
                stock.setRealNum(remainQty);
                stock.setLastUpdateTime(LocalDateTime.now());
                remainQty = 0;
                // 添加更新库存列表
                updateStocks.add(stock);
            } else {
                // 库存不变
                remainQty -= stock.getRealNum();
            }
        }
        // 删除库存
        if (!removeStocks.isEmpty()) {
            appStockService.removeBatchByIds(removeStocks.stream().map(TAppStock::getStockId).toList());
        }
        // 更新库存数量
        if (!updateStocks.isEmpty()) {
            appStockService.updateBatchById(updateStocks);
        }
        // 增加库存更新记录
        if (!stockUpdateList.isEmpty()) {
            appStockUpdateService.saveBatch(stockUpdateList);
        }
    }

    /**
     * 获得库存预警值---实现
     * @return 库存预警值
     */
    @Override
    public int getWarningQty() {
        int warningQty = 5;
        try {
            // 获取配置数据
            warningQty = Integer.parseInt(appCommon.getConfigByKey(AppConfigKeyEnums.STOCK_WARNING_QTY.getKey()));
        } catch (Exception e) {
            log.warn("获取库存预警值失败，使用默认值5。");
        }
        return warningQty;
    }

    /**
     * 判断当前载具是否是空载具
     * @param vehicleId 载具号
     * @return true：空载具；false：非空载具
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean isEmptyVehicle(String vehicleId) {
        // 查询这个载具的所有库存数据
        List<TAppStock> thisVehicleStocks = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                .eq(TAppStock::getVehicleId, vehicleId)
                .gt(TAppStock::getRealNum, 0)
        );
        boolean isEmpty = thisVehicleStocks == null || thisVehicleStocks.isEmpty();
        if (isEmpty) {
            // 更新载具数据
            appVehicleService.update(new LambdaUpdateWrapper<TAppVehicle>()
                    .set(TAppVehicle::getIsEmpty, 1)
                    .eq(TAppVehicle::getVehicleId, vehicleId)
                    .ne(TAppVehicle::getIsEmpty, 1));
        }
        return isEmpty;
    }

    /**
     * 找到目标料号最先入库的库存，剩余可用数量大于0---实现
     * @param goodsId 目标
     * @param allStocks 所有库存
     * @return 库存编号
     */
    @Override
    public String getFirstInStock(String goodsId, List<TAppStock> allStocks) {
        if (allStocks == null || allStocks.isEmpty()) {
            return "";
        }
        // 筛选此料号下的库存, 按照入库时间正序排序
        List<TAppStock> thisGoodsStocks = allStocks.stream()
                .filter(stock -> stock.getGoodsId().equals(goodsId) && stock.getRemainNum() > 0)
                .sorted(Comparator.comparing(TAppStock::getFirstInTime))
                .toList();
        if (thisGoodsStocks.isEmpty()) {
            return "";
        }
        return thisGoodsStocks.getFirst().getStockId();
    }

    /**
     * 获取可以继续放料的map---实现
     * @param goodsIds 物料列表
     * @return 结果map
     */
    @Override
    public Map<String, Map<String, Integer>> getCanPutGoodsMap(List<String> goodsIds) {
        // 筛选出料号，查询库存
        if (goodsIds == null || goodsIds.isEmpty()) {
            return new HashMap<>();
        }
        // 先去重
        List<String> distinctGoodsIds = goodsIds.stream().distinct().toList();
        List<TAppStock> stocksOfThisGoodsIds = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                .in(TAppStock::getGoodsId, distinctGoodsIds)
                .orderByAsc(TAppStock::getFirstInTime));
        // 根据载具号合并数量----因为这个项目默认一箱一料
        Map<String, Map<String, Integer>> goodsQtyMap = new HashMap<>();
        for (TAppStock stock : stocksOfThisGoodsIds) {
            if (goodsQtyMap.containsKey(stock.getGoodsId())) {
                Map<String, Integer> qtyByVehicleMap = goodsQtyMap.get(stock.getGoodsId());
                if (qtyByVehicleMap.containsKey(stock.getVehicleId())) {
                    qtyByVehicleMap.replace(stock.getVehicleId(), qtyByVehicleMap.get(stock.getVehicleId()) + stock.getRemainNum());
                } else {
                    qtyByVehicleMap.put(stock.getVehicleId(), stock.getRemainNum());
                }
                goodsQtyMap.replace(stock.getGoodsId(), qtyByVehicleMap);
            } else {
                Map<String, Integer> qtyByVehicleMap = new HashMap<>();
                qtyByVehicleMap.put(stock.getVehicleId(), stock.getRemainNum());
                goodsQtyMap.put(stock.getGoodsId(), qtyByVehicleMap);
            }
        }
        // 去除数量过多的
        List<String> stockGoodsIds = new ArrayList<>(goodsQtyMap.keySet());
        for (String goodsId : stockGoodsIds) {
            // 当前的物料信息
            TAppGoods thisGoods = appCommon.getInstantGoodsByGoodsId(goodsId);
            if (thisGoods == null || thisGoods.getBoxQty() == null || thisGoods.getMaxBoxNum() == null) {
                continue;
            }
            // 根据数量过滤
            Map<String, Integer> qtyByVehicleMap = goodsQtyMap.get(goodsId);
            List<String> vehicleIdsOfThisGoods = new ArrayList<>(qtyByVehicleMap.keySet());
            for (String vehicleId : vehicleIdsOfThisGoods) {
                if (qtyByVehicleMap.get(vehicleId) > (thisGoods.getMaxBoxNum() - 1) * thisGoods.getBoxQty()) {
                    qtyByVehicleMap.remove(vehicleId);
                }
            }
            // 去除不可用的料号
            if (qtyByVehicleMap.isEmpty()) {
                goodsQtyMap.remove(goodsId);
            } else {
                goodsQtyMap.replace(goodsId, qtyByVehicleMap);
            }
        }
        return goodsQtyMap;
    }
}
