package com.wms_main.service.business.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms_main.constant.enums.wms.WmsStockStatusEnums;
import com.wms_main.dao.ITAppLocationService;
import com.wms_main.dao.ITAppStockService;
import com.wms_main.model.bo.wms.DepthStrategyResult;
import com.wms_main.model.po.TAppLocation;
import com.wms_main.model.po.TAppOrderOut;
import com.wms_main.model.po.TAppStock;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.service.business.IDepthStrategyService;
import com.wms_main.service.business.IStackerTaskService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 简化后的深度策略服务实现
 * 核心逻辑：基于载具号查询库存，检测深度策略
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DepthStrategyServiceImpl implements IDepthStrategyService {

    private final ITAppStockService appStockService;
    private final ITAppLocationService appLocationService;
    private final IStackerTaskService stackerTaskService;

    /**
     * 基于载具号分析深度策略（新核心方法）
     */
    @Override
    public DepthStrategyResult analyzeDepthStrategyByVehicle(String vehicleNo) {
        if (StringUtils.isEmpty(vehicleNo)) {
            log.warn("载具号为空");
            return DepthStrategyResult.createError("载具号不能为空");
        }

        TAppStock stock = appStockService.getOne(
                new LambdaQueryWrapper<TAppStock>()
                        .eq(TAppStock::getVehicleId, vehicleNo)
                        .eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode())
        );

        if (stock == null) {
            log.warn("载具号{}对应的库存不存在", vehicleNo);
            return DepthStrategyResult.createError("载具库存不存在");
        }

        Integer depth = getLocationDepth(stock.getLocationId());
        if (depth == null) {
            log.warn("无法解析库存位置深度: {}", stock.getLocationId());
            return DepthStrategyResult.createError("库位深度解析失败");
        }

        if (depth == 1) {
            return DepthStrategyResult.createDirectOut("深度1，直接出库");
        } else if (depth == 2) {
            return handleDepth2Stock(stock);
        } else {
            log.warn("不支持的库存深度: {}", depth);
            return DepthStrategyResult.createError("仅支持1-2深度库存");
        }
    }

    /**
     * 处理深度2的库存策略
     */
    private DepthStrategyResult handleDepth2Stock(TAppStock stock) {
        // 检查深度1是否有阻挡
        List<TAppStock> blockingStocks = getBlockingStocks(stock.getLocationId(), 1);

        if (blockingStocks.isEmpty()) {
            return DepthStrategyResult.createDirectOut("深度2无阻挡，直接出库");
        } else {
            // 检查阻挡货物是否可移库
            for (TAppStock blockingStock : blockingStocks) {
                if (!canFindAlternativeLocation(blockingStock)) {
                    log.warn("深度2库存{}被阻挡，且无法移走阻挡货物{}",
                            stock.getStockId(), blockingStock.getStockId());
                    return DepthStrategyResult.createError("无法移走阻挡货物");
                }
            }
            return DepthStrategyResult.createSingleTransfer("深度2有阻挡，需要移库后出库");
        }
    }

    /**
     * 获取库位深度
     */
    @Override
    public Integer getLocationDepth(String locationId) {
        if (StringUtils.isEmpty(locationId)) return null;

        try {
            String[] parts = locationId.split("-");
            if (parts.length >= 4) {
                return Integer.parseInt(parts[3]);
            }
        } catch (Exception e) {
            log.warn("解析库位深度失败: {}", locationId, e);
        }
        return null;
    }

    /**
     * 获取阻挡货物（按载具去重）
     */
    private List<TAppStock> getBlockingStocks(String locationId, Integer blockingDepth) {
        if (StringUtils.isEmpty(locationId) || blockingDepth == null) {
            return List.of();
        }

        try {
            String[] parts = locationId.split("-");
            if (parts.length < 4) return List.of();

            String blockingLocationId = parts[0] + "-" + parts[1] + "-" + parts[2] + "-0" + blockingDepth;

            return appStockService.list(
                    new LambdaQueryWrapper<TAppStock>()
                            .eq(TAppStock::getLocationId, blockingLocationId)
                            .eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode())
            );
        } catch (Exception e) {
            log.warn("获取阻挡货物失败: {}, 深度: {}", locationId, blockingDepth, e);
            return List.of();
        }
    }

    /**
     * 检查能否为阻挡货物找到空闲库位
     */
    private boolean canFindAlternativeLocation(TAppStock blockingStock) {
        try {
            TAppLocation locationFilter = new TAppLocation();
            String currentLocationId = blockingStock.getLocationId();
            String[] parts = currentLocationId.split("-");

            if (parts.length >= 4) {
                locationFilter.setLRow(Integer.parseInt(parts[0].replaceAll("\\D", "")));
                locationFilter.setLCol(Integer.parseInt(parts[1]));
            }

            TAppLocation targetLocation = stackerTaskService.requestOneLocation(
                    locationFilter, blockingStock.getVehicleId());

            if (targetLocation != null) {
                releaseLocation(targetLocation);
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("检查空闲库位失败: {}", blockingStock.getStockId(), e);
            return false;
        }
    }

    /**
     * 释放临时占用的库位
     */
    private void releaseLocation(TAppLocation location) {
        try {
            appLocationService.update(
                    new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<TAppLocation>()
                            .eq(TAppLocation::getLocationId, location.getLocationId())
                            .set(TAppLocation::getIsOccupy, 0)
                            .set(TAppLocation::getVehicleId, "")
            );
        } catch (Exception e) {
            log.warn("释放库位失败: {}", location.getLocationId(), e);
        }
    }
}