package com.jsh.erp.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.MaterialVo4Unit;
import com.jsh.erp.datasource.entities.Supplier;
import com.jsh.erp.datasource.entities.Unit;
import com.jsh.erp.datasource.mappers.MaterialCurrentStockMapperEx;
import com.jsh.erp.datasource.tesco.request.ErpXsddReqVO;
import com.jsh.erp.datasource.vo.DepotHeadXsddRequestVO;
import com.jsh.erp.datasource.vo.DepotItemXsddRequestVO;
import com.jsh.erp.datasource.vo.Material4UnitPrice;
import com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku;
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.utils.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author MS.BLUE
 * @Date 2025-04-12
 */
@Service
public class SyncTescoSystemService {

    private Logger logger = LoggerFactory.getLogger(SyncTescoSystemService.class);

    @Resource
    private MaterialService materialService;

    @Resource
    private DepotHeadService depotHeadService;

    @Resource
    private SequenceService sequenceService;

    @Resource
    private SupplierService supplierService;

    @Resource
    private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;

    @Value("${tesco.openSycn}")
    private boolean openSycn;
    
    @Value("${tesco.sycnErpMaterialStockUrl}")
    private String sycnErpMaterialStockUrl;

    @Value("${tesco.sycnErpMaterialPriceUrl}")
    private String sycnErpMaterialPriceUrl;

    public String syncSystemSku(String param) {
        logger.info("获取商品系统sku，返回信息集采系统 param:{}", param);
        JSONObject result = new JSONObject();
        JSONArray dataArray = new JSONArray();

        try {
            // 参数校验
            if (param == null || param.isEmpty()) {
                result.put("code", 1);
                result.put("msg", "参数不能为空");
                return result.toJSONString();
            }

            // 解析传入的JSON参数
            JSONArray barCodeArray = JSON.parseArray(param);
            if (barCodeArray == null || barCodeArray.isEmpty()) {
                result.put("code", 1);
                result.put("msg", "参数格式错误");
                return result.toJSONString();
            }

            // 提取 barCode 到字符串数组
            List<String> barCodeList = new ArrayList<>();
            for (int i = 0; i < barCodeArray.size(); i++) {
                JSONObject barCodeObj = barCodeArray.getJSONObject(i);
                String barCode = barCodeObj.getString("barCode");
                barCodeList.add(barCode);
            }

            // 查询商品信息
            List<MaterialVo4Unit> materialList = materialService.getMaterialByBarCode(barCodeList);
            if (materialList != null && !materialList.isEmpty()) {
                result.put("code", 0);
                for (MaterialVo4Unit material : materialList) {
                    JSONObject item = new JSONObject();
                    item.put("barCode", material.getmBarCode());
                    item.put("systemSku", material.getSystemSku());
                    dataArray.add(item);
                }
            } else {
                result.put("code", 1);
                result.put("msg", "未找到对应商品信息");
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code", 1);
            result.put("msg", "系统异常，请稍后重试");
        }

        // 将数据数组放入返回结果
        result.put("data", dataArray);
        logger.info("  result:{}", result);
        return result.toJSONString();
    }

    /**
     *
     集采下单成功->封装同步erp销售订单请求体

     {
     orderSn:"订单编号"，
     customer:{//客户信息
     name:"客户名称",
     contact:"客户联系方式",
     address:"客户地址"
     },
     item:[{//订单商品信息
     erp_sku:"erp_sku编号",
     unitPrice:"商品单价",
     quantity:"商品下单数量",
     price:"商品实付价格"
     }]
     }

     * @param param
     * @return
     */
    public String syncOrder(String param) {
        logger.info("同步集采订单-》销售订单 param:{}", param);
        JSONObject result = new JSONObject();
        try {
            // 解析传入的JSON参数为 ErpXsddReqVO
            ErpXsddReqVO erpXsddReqVO = JSON.parseObject(param, ErpXsddReqVO.class);
            if (erpXsddReqVO == null) {
                result.put("code", 1);
                result.put("msg", "参数不能为空");
                return result.toJSONString();
            }

            // 校验订单编号
            if (erpXsddReqVO.getOrderSn() == null || erpXsddReqVO.getOrderSn().isEmpty()) {
                result.put("code", 1);
                result.put("msg", "订单编号不能为空");
                return result.toJSONString();
            }

            // 校验客户信息
            if (erpXsddReqVO.getCustomer() == null) {
                result.put("code", 1);
                result.put("msg", "客户信息不能为空");
                return result.toJSONString();
            }

            // 校验订单商品信息
            if (erpXsddReqVO.getItems() == null || erpXsddReqVO.getItems().isEmpty()) {
                result.put("code", 1);
                result.put("msg", "订单商品信息不能为空");
                return result.toJSONString();
            }

            // 构建订单和商品信息
            buildOrderAndItem(erpXsddReqVO);

            // 返回成功结果
            result.put("code", 0);
            result.put("msg", "订单同步成功");
        } catch (Exception e) {
            logger.error("同步订单发生异常", e);
            result.put("code", 1);
            result.put("msg", "系统异常，请稍后重试");
        }
        return result.toJSONString();
    }

    public String sycnTescoStock(Long mId){
        return sycnTescoStock(Arrays.asList(mId));
    }

    public String sycnTescoStock(List<Long> mIdList) {
        if (!openSycn) {
            return "tesco系统同步未开启";
        }
        List<MaterialCurrentStock4SystemSku> stockList = materialCurrentStockMapperEx.getCurrentStockMapByMdIdList(mIdList);
        if (!CollectionUtils.isEmpty(stockList)) {
            try {
                for (MaterialCurrentStock4SystemSku stock : stockList) {
                    Unit unitInfo = new Unit(); // 查询多单位信息
                    stock.setBasicUnit(stock.getUnit());
                    stock.setBasicUnitTotalStock(stock.getBasicUnitTotalStock().setScale(0, RoundingMode.DOWN));
                    if (stock.getUnitId() != null) {
                        unitInfo = materialService.findUnit(stock.getMId());
                        stock.setBasicUnit(unitInfo.getBasicUnit());
                        stock.setLargeUnit(true);
                        processOtherUnitStock(stock, unitInfo);
                    }
                }
                String jsonParam = new ObjectMapper().writeValueAsString(stockList);
                logger.info("同步集采库存请求参数：{}", jsonParam);
                String response = HttpClient.httpPost(sycnErpMaterialStockUrl, jsonParam);
                logger.info("同步集采库存响应：{}", response);
                return jsonParam;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
        return null;
    }

    private void processOtherUnitStock(MaterialCurrentStock4SystemSku stock, Unit unitInfo) {
        if (StringUtils.isNotEmpty(unitInfo.getOtherUnit())) {
            BigDecimal otherUnitTotalStock = stock.getBasicUnitTotalStock().divide(unitInfo.getRatio(), 0, RoundingMode.DOWN);
            String otherUnitStr = "1" + unitInfo.getOtherUnit() + "=" + unitInfo.getRatio().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
            stock.setOtherUnit(otherUnitStr);
            stock.setRatio(unitInfo.getRatio().setScale(0, RoundingMode.DOWN));
            stock.setOtherUnitTotalStock(otherUnitTotalStock);

            if (StringUtils.isNotEmpty(unitInfo.getOtherUnitTwo())) {
                BigDecimal otherUnitTwoTotalStock = stock.getBasicUnitTotalStock().divide(unitInfo.getRatioTwo(), 0, RoundingMode.DOWN);
                String otherUnitTwoStr = "1" + unitInfo.getOtherUnitTwo() + "=" + unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
                stock.setOtherUnitTwo(otherUnitTwoStr);
                stock.setRatioTwo(unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN));
                stock.setOtherUnitTwoTotalStock(otherUnitTwoTotalStock);

                if (StringUtils.isNotEmpty(unitInfo.getOtherUnitThree())) {
                    BigDecimal otherUnitThreeTotalStock = stock.getBasicUnitTotalStock().divide(unitInfo.getRatioThree(), 0, RoundingMode.DOWN);
                    String otherUnitThreeStr = "1" + unitInfo.getOtherUnitThree() + "=" + unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
                    stock.setOtherUnitTwo(otherUnitThreeStr);
                    stock.setRatioThree(unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN));
                    stock.setOtherUnitThreeTotalStock(otherUnitThreeTotalStock);
                }
            }
        }
    }

    public String sycnTescoSalePrice(List<Long> mIdList) {
        if (!openSycn) {
            return "tesco系统同步未开启";
        }
        try {
            List<MaterialCurrentStock4SystemSku> mList = materialService.getMaterialCurrentPriceByIdList(mIdList);
            if (!CollectionUtils.isEmpty(mList)) {
                for (MaterialCurrentStock4SystemSku material : mList){
                    Unit unitInfo = new Unit(); // 查询多单位信息
                    material.setBasicUnit(material.getUnit());
                    if (material.getUnitId() != null) {
                        unitInfo = materialService.findUnit(material.getMId());
                        material.setBasicUnit(unitInfo.getBasicUnit());
                        material.setLargeUnit(true);

                        processOtherUnitSalePrice(material, unitInfo);
                    }
                }

                String jsonParam = new ObjectMapper().writeValueAsString(mList);
                logger.info("同步集采销售价格请求参数：{}", jsonParam);
                String response = HttpClient.httpPost(sycnErpMaterialPriceUrl, jsonParam);
                logger.info("同步集采销售价格响应：{}", response);
                return jsonParam;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    private void processOtherUnitSalePrice(MaterialCurrentStock4SystemSku stock, Unit unitInfo) {
        if (StringUtils.isNotEmpty(unitInfo.getOtherUnit())) {
            BigDecimal otherUnitSalePrice = stock.getBasicUnitSalePrice().multiply(unitInfo.getRatio());
            String otherUnitStr = "1" + unitInfo.getOtherUnit() + "=" + unitInfo.getRatio().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
            stock.setOtherUnit(otherUnitStr);
            stock.setRatio(unitInfo.getRatio().setScale(0, RoundingMode.DOWN));
            stock.setOtherUnitSalePrice(otherUnitSalePrice);

            if (StringUtils.isNotEmpty(unitInfo.getOtherUnitTwo())) {
                BigDecimal otherUnitTwoSalePrice = stock.getBasicUnitSalePrice().multiply(unitInfo.getRatioTwo());
                String otherUnitTwoStr = "1" + unitInfo.getOtherUnitTwo() + "=" + unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
                stock.setOtherUnitTwo(otherUnitTwoStr);
                stock.setRatioTwo(unitInfo.getRatioTwo().setScale(0, RoundingMode.DOWN));
                stock.setOtherUnitTwoSalePrice(otherUnitTwoSalePrice);

                if (StringUtils.isNotEmpty(unitInfo.getOtherUnitThree())) {
                    BigDecimal otherUnitThreeSalePrice = stock.getBasicUnitSalePrice().multiply(unitInfo.getRatioThree());
                    String otherUnitThreeStr = "1" + unitInfo.getOtherUnitThree() + "=" + unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN) + unitInfo.getBasicUnit();
                    stock.setOtherUnitTwo(otherUnitThreeStr);
                    stock.setRatioThree(unitInfo.getRatioThree().setScale(0, RoundingMode.DOWN));
                    stock.setOtherUnitThreeSalePrice(otherUnitThreeSalePrice);
                }
            }
        }
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    private void buildOrderAndItem(ErpXsddReqVO erpXsddReqVO) throws Exception {
        // 1. 初始化订单基本信息
        DepotHeadXsddRequestVO order = initSalesOrder(erpXsddReqVO);

        // 2. 处理订单商品项
        List<DepotItemXsddRequestVO> itemList = processOrderItems(erpXsddReqVO, order);

        // 3. 提交订单
        depotHeadService.syncOrderToXsdd(order, itemList);
    }

    private DepotHeadXsddRequestVO initSalesOrder(ErpXsddReqVO erpXsddReqVO) throws Exception {
        DepotHeadXsddRequestVO order = new DepotHeadXsddRequestVO();
        order.setType("其它");
        order.setSubType("销售订单");
        order.setLinkTesco(erpXsddReqVO.getOrderSn());

        ErpXsddReqVO.Customer customer = erpXsddReqVO.getCustomer();
        // 根据手机号查询客户
        Supplier supplier = supplierService.getCustomerByPhone(customer.getAccount());
        if (supplier == null) {
            // 如果客户不存在，创建新客户
            supplier = new Supplier();
            supplier.setEnabled(true);
            supplier.setSupplier(customer.getName());
            supplier.setTelephone(customer.getAccount());
            supplier.setContacts(customer.getReceiverName());
            supplier.setPhoneNum(customer.getReceiverPhone());
            supplier.setAddress(customer.getReceiverAddress());
            supplier = supplierService.createCustomer(supplier);
        }

        // 绑定客户 ID
        order.setOrganId(supplier.getId());
        order.setReceiverName(customer.getReceiverName());
        order.setReceiverPhone(customer.getReceiverPhone());
        order.setReceiverAddress(customer.getReceiverAddress());
        order.setRemark("集采同步订单");
        String number = sequenceService.buildOnlyNumber();
        String defaultNumber = "XSDD" + number;
        order.setDefaultNumber(defaultNumber);
        order.setNumber(defaultNumber);
        order.setCreateTime(new Date());
        order.setOperTime(new Date());
        order.setCreator(1L); // 创建人ID
        order.setAccountId(1L); // 账户ID
        order.setChangeAmount(BigDecimal.ZERO);
        order.setBackAmount(BigDecimal.ZERO);
        order.setTotalPrice(erpXsddReqVO.getTotalPrice());
        order.setPayType("现付");
        order.setDiscount(BigDecimal.ZERO);
        order.setDiscountMoney(BigDecimal.ZERO);
        order.setDiscountLastMoney(erpXsddReqVO.getTotalPrice());
        order.setStatus("0");
        order.setPurchaseStatus("0");
        order.setSource("2"); // 来源集采商城
        order.setTenantId(null);
        order.setDeleteFlag("0");
        return order;
    }

    /**
     * 处理订单商品项
     */
    private List<DepotItemXsddRequestVO> processOrderItems(ErpXsddReqVO erpXsddReqVO, DepotHeadXsddRequestVO order) throws Exception {

        List<DepotItemXsddRequestVO> itemList = new ArrayList<>();
        List<ErpXsddReqVO.OrderItem> reqVOItems = erpXsddReqVO.getItems();

        // 1. 获取所有商品信息
        List<String> systemSkuList = reqVOItems.stream().map(ErpXsddReqVO.OrderItem::getErpSku).collect(Collectors.toList());
        List<MaterialVo4Unit> materialList = materialService.getMaterialBySystemSku(systemSkuList);
        Map<String, List<MaterialVo4Unit>> skuToMaterialMap = materialList.stream().collect(Collectors.groupingBy(MaterialVo4Unit::getSystemSku));

        // 2. 处理每个订单项
        for (ErpXsddReqVO.OrderItem reqVOItem : reqVOItems) {
            try {
                processSingleOrderItem(reqVOItem, order, itemList, skuToMaterialMap);
            } catch (Exception e) {
                logger.error("处理订单项失败 erp_sku: {}: {}", reqVOItem.getErpSku(), e.getMessage());
                throw e;
            }
        }

        return itemList;
    }


    /**
     * 处理单个订单项
     */
    private void processSingleOrderItem(ErpXsddReqVO.OrderItem reqVOItem, DepotHeadXsddRequestVO order, List<DepotItemXsddRequestVO> itemList, Map<String, List<MaterialVo4Unit>> skuToMaterialMap) throws Exception {

        // 1. 参数校验
        validateOrderItem(reqVOItem);

        // 2. 获取商品信息
        List<MaterialVo4Unit> materials = skuToMaterialMap.get(reqVOItem.getErpSku());
        if (CollectionUtils.isEmpty(materials)) {
            throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ERP_SKU_NOT_DECIMAL_CODE, String.format(ExceptionConstants.MATERIAL_ERP_SKU_NOT_DECIMAL_MSG, reqVOItem.getErpSku()));
        }

        // 3. 获取单位信息
        MaterialVo4Unit primaryMaterial = materials.get(0);
        Material4UnitPrice material4UnitPrice = getMaterial4UnitPrice(primaryMaterial);

        // 4. 匹配销售单位
        UnitMatchResult matchResult = matchUnitAndCalculateBaseQuantity(reqVOItem.getUnitPrice(), BigDecimal.valueOf(reqVOItem.getQuantity()), material4UnitPrice);

        // 5. 根据单位类型分配库存
        if (matchResult.isLargeUnit()) {
            allocateLargeUnitStock(reqVOItem, order, itemList, materials, matchResult, material4UnitPrice);
        } else {
            allocateBasicUnitStock(reqVOItem, order, itemList, materials, matchResult);
        }
    }

    /**
     * 分配大单位库存（不拆分配）
     */
    private void allocateLargeUnitStock(ErpXsddReqVO.OrderItem reqVOItem, DepotHeadXsddRequestVO order, List<DepotItemXsddRequestVO> itemList, List<MaterialVo4Unit> materials,
        UnitMatchResult matchResult, Material4UnitPrice material4UnitPrice) throws Exception {

        String orderUnit = matchResult.getMatchedUnit();
        BigDecimal unitRatio = getUnitRatio(orderUnit, material4UnitPrice);
        BigDecimal remainingOrderQty = matchResult.getOrderUnitQuantity();

        // 分配库存
        for (MaterialVo4Unit m : materials) {
            if (remainingOrderQty.compareTo(BigDecimal.ZERO) <= 0)
                break;

            BigDecimal inventory = m.getInventory();
            if (inventory.compareTo(unitRatio) < 0)
                continue;

            // 计算可分配数量（向下取整）
            BigDecimal allocatableUnits = inventory.divideToIntegralValue(unitRatio).min(remainingOrderQty);

            if (allocatableUnits.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal allocBaseQty = allocatableUnits.multiply(unitRatio);

                // 创建订单项
                DepotItemXsddRequestVO item = createOrderItem(order, m, orderUnit, allocatableUnits, allocBaseQty, reqVOItem.getUnitPrice());
                itemList.add(item);

                // 更新库存
                m.setInventory(inventory.subtract(allocBaseQty));

                // 更新剩余需求
                remainingOrderQty = remainingOrderQty.subtract(allocatableUnits);

                logger.info("分配库存：批次[{}] 分配 {} {} (剩余需求: {})", m.getBatchNumber(), allocatableUnits.toPlainString(), orderUnit, remainingOrderQty.toPlainString());
            }
        }

        // 检查是否完全分配
        if (remainingOrderQty.compareTo(BigDecimal.ZERO) > 0) {
            throw new RuntimeException(buildStockShortageMessage(reqVOItem.getErpSku(), matchResult.getOrderUnitQuantity(), remainingOrderQty, orderUnit, materials, true, // 是大单位
                material4UnitPrice));
        }
    }

    /**
     * 分配基本单位库存
     */
    private void allocateBasicUnitStock(ErpXsddReqVO.OrderItem reqVOItem, DepotHeadXsddRequestVO order, List<DepotItemXsddRequestVO> itemList, List<MaterialVo4Unit> materials, UnitMatchResult matchResult) throws Exception {

        // 获取基本参数
        BigDecimal remainingQty = matchResult.getBaseQuantity(); // 剩余需求数量（基本单位）
        String basicUnit = matchResult.getMatchedUnit(); // 基本单位名称
        String erpSku = reqVOItem.getErpSku();
        BigDecimal unitPrice = reqVOItem.getUnitPrice();

        // 记录原始需求用于错误提示
        BigDecimal originalQty = remainingQty;

        // 遍历库存批次进行分配
        for (MaterialVo4Unit m : materials) {
            if (remainingQty.compareTo(BigDecimal.ZERO) <= 0) {
                break; // 需求已满足
            }

            BigDecimal inventory = m.getInventory();
            if (inventory.compareTo(BigDecimal.ZERO) <= 0) {
                continue; // 跳过无库存批次
            }

            // 计算当前批次可分配数量
            BigDecimal allocateQty = inventory.min(remainingQty);

            // 创建订单明细项
            DepotItemXsddRequestVO item = createOrderItem(order, m, basicUnit, allocateQty, allocateQty, unitPrice);
            itemList.add(item);

            // 更新库存
            m.setInventory(inventory.subtract(allocateQty));

            // 更新剩余需求
            remainingQty = remainingQty.subtract(allocateQty);

            logger.info("分配基本单位库存：批次[{}]  分配 {} {} (剩余需求: {})", m.getBatchNumber(), allocateQty.toPlainString(), basicUnit, remainingQty.toPlainString());
        }

        // 检查是否完全分配
        if (remainingQty.compareTo(BigDecimal.ZERO) > 0) {
            // 在allocateBasicUnitStock方法中调用
            throw new RuntimeException(buildStockShortageMessage(erpSku, originalQty, remainingQty, basicUnit, materials, false, null));
        }
    }


    /**
     * 构建库存不足提示信息（通用方法，支持基本单位和大单位）
     *
     * @param erpSku 商品SKU
     * @param totalQty 总需求数量
     * @param remainingQty 剩余未分配数量
     * @param orderUnit 订单单位
     * @param materials 库存列表
     * @param isLargeUnit 是否为大单位
     * @param material4UnitPrice 单位价格信息（大单位时需要）
     * @return 完整的库存不足提示信息
     */
    private String buildStockShortageMessage(String erpSku, BigDecimal totalQty, BigDecimal remainingQty, String orderUnit, List<MaterialVo4Unit> materials, boolean isLargeUnit, Material4UnitPrice material4UnitPrice) {

        StringBuilder sb = new StringBuilder();
        sb.append("商品[").append(erpSku).append("]库存不足！\n");
        sb.append("需求: ").append(totalQty.toPlainString()).append(" ").append(orderUnit).append("\n");
        sb.append("未分配: ").append(remainingQty.toPlainString()).append(" ").append(orderUnit).append("\n");
        sb.append("当前库存:\n");

        // 获取基本单位名称
        String basicUnit = isLargeUnit ? material4UnitPrice.getBasicUnit() : orderUnit;

        materials.forEach(m -> {
            // 计算当前批次的显示库存量
            String stockDisplay;
            if (isLargeUnit) {
                BigDecimal unitRatio = getUnitRatio(orderUnit, material4UnitPrice);
                BigDecimal stockInOrderUnit = m.getInventory().divideToIntegralValue(unitRatio);
                stockDisplay = String.format("%s %s (%s %s)", stockInOrderUnit.toPlainString(), orderUnit, m.getInventory().toPlainString(), basicUnit);
            } else {
                stockDisplay = m.getInventory().toPlainString() + " " + basicUnit;
            }

            sb.append(String.format("批次[%s] 生产日期[%s] - 库存: %s\n", m.getBatchNumber(), m.getProductionDate(), stockDisplay));
        });

        // 添加建议提示
        if (isLargeUnit) {
            sb.append("\n提示：").append(orderUnit).append("与").append(basicUnit).append("的换算比例为: 1").append(orderUnit).append("=").append(getUnitRatio(orderUnit, material4UnitPrice).toPlainString()).append(basicUnit);
        }

        return sb.toString();
    }


    /**
     * 订单项参数校验
     */
    private void validateOrderItem(ErpXsddReqVO.OrderItem item) throws Exception {
        if (item.getQuantity() == null || item.getQuantity() <= 0) {
            throw new RuntimeException("商品数量必须大于0");
        }
        if (item.getUnitPrice() == null || item.getUnitPrice().compareTo(BigDecimal.ZERO) <= 0) {
            throw new RuntimeException("商品单价必须大于0");
        }
        if (StringUtils.isBlank(item.getErpSku())) {
            throw new RuntimeException("商品SKU不能为空");
        }
    }



    

    /**
     * 创建订单明细项
     */
    private DepotItemXsddRequestVO createOrderItem(DepotHeadXsddRequestVO order, MaterialVo4Unit material, String unit, BigDecimal operNumber, BigDecimal basicNumber, BigDecimal unitPrice) {
        DepotItemXsddRequestVO item = new DepotItemXsddRequestVO();
        item.setHeaderId(order.getId());
        item.setMaterialId(material.getId());
        item.setMaterialExtendId(material.getMeId());
        item.setMaterialUnit(unit);
        item.setSku(material.getSku());
        item.setDepotId(material.getDepotId());
        item.setOperNumber(operNumber);
        item.setBasicNumber(basicNumber);
        item.setUnitPrice(unitPrice);
        item.setTaxRate(BigDecimal.ONE);
        item.setTaxMoney(BigDecimal.ZERO);
        item.setBatchNumber(material.getBatchNumber());
        item.setTaxLastMoney(unitPrice.multiply(operNumber));
        item.setAllPrice(unitPrice.multiply(operNumber));
        return item;
    }


    private Material4UnitPrice getMaterial4UnitPrice(MaterialVo4Unit material) throws Exception {
        Material4UnitPrice material4UnitPrice = new Material4UnitPrice();
        Unit unitInfo = new Unit(); // 查询多单位信息
        unitInfo.setBasicUnit(material.getCommodityUnit());
        if(material.getUnitId() != null){
            unitInfo = materialService.findUnit(material.getId());
        }

        BeanUtils.copyProperties(unitInfo, material4UnitPrice);

        // 设置基础单位价格、基础数量
        material4UnitPrice.setBasicUnitPrice(material.getWholesaleDecimal());
        material4UnitPrice.setBasicUnitNumber(BigDecimal.ONE);

        // 设置其他单位价格、其他数量
        if (StringUtils.isNotEmpty(material4UnitPrice.getOtherUnit())) {
            material4UnitPrice.setOtherUnitPrice(material.getWholesaleDecimal().multiply(material4UnitPrice.getRatio()));
            material4UnitPrice.setOtherUnitNumber(material4UnitPrice.getRatio());
        }

        // 设置其他单位2价格、其他数量2
        if (StringUtils.isNotEmpty(material4UnitPrice.getOtherUnitTwo())) {
            material4UnitPrice.setOtherUnitTwoPrice(material.getWholesaleDecimal().multiply(material4UnitPrice.getRatioTwo()));
            material4UnitPrice.setOtherUnitTwoNumber(material4UnitPrice.getRatioTwo());
        }

        // 设置其他单位3价格、其他数量3
        if (StringUtils.isNotEmpty(material4UnitPrice.getOtherUnitThree())) {
            material4UnitPrice.setOtherUnitThreePrice(material.getWholesaleDecimal().multiply(material4UnitPrice.getRatioThree()));
            material4UnitPrice.setOtherUnitThreeNumber(material4UnitPrice.getRatioThree());
        }
        return material4UnitPrice;
    }



    /**
     * 根据单价匹配单位并计算基本单位数量<br>
     * 如果订单商品单价和商品最小单位单价相等，则使用最小单位, remainingQuantity = quantity<br>
     * 如果订单商品单价和商品其他单位单价相等，则使用其他单位, remainingQuantity = quantity * material4UnitPrice.getRatio()<br>
     * 如果订单商品单价和商品其他单位2单价相等，则使用其他单位2, remainingQuantity = quantity * material4UnitPrice.getRatioTwo()<br>
     * 如果订单商品单价和商品其他单位3单价相等，则使用其他单位3, remainingQuantity = quantity * material4UnitPrice.getRatioThree()<br>
     */
    private UnitMatchResult matchUnitAndCalculateBaseQuantity(BigDecimal orderUnitPrice, BigDecimal orderQuantity, Material4UnitPrice material4UnitPrice) {
        // 允许的价格误差范围
        final BigDecimal PRICE_TOLERANCE = new BigDecimal("0.001");

        // 1. 检查是否匹配基本单位价格
        if (material4UnitPrice.getBasicUnitPrice() != null && orderUnitPrice.subtract(material4UnitPrice.getBasicUnitPrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
            return new UnitMatchResult(material4UnitPrice.getBasicUnit(), orderQuantity, orderQuantity, false);
        }

        // 2. 检查是否匹配副单位价格
        if (material4UnitPrice.getOtherUnitPrice() != null && orderUnitPrice.subtract(material4UnitPrice.getOtherUnitPrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
            BigDecimal baseQuantity = orderQuantity.multiply(material4UnitPrice.getRatio());
            return new UnitMatchResult(material4UnitPrice.getOtherUnit(), orderQuantity, baseQuantity, true);
        }

        // 3. 检查是否匹配副单位2价格
        if (material4UnitPrice.getOtherUnitTwoPrice() != null && orderUnitPrice.subtract(material4UnitPrice.getOtherUnitTwoPrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
            BigDecimal baseQuantity = orderQuantity.multiply(material4UnitPrice.getRatioTwo());
            return new UnitMatchResult(material4UnitPrice.getOtherUnitTwo(), orderQuantity, baseQuantity, true);
        }

        // 4. 检查是否匹配副单位3价格
        if (material4UnitPrice.getOtherUnitThreePrice() != null && orderUnitPrice.subtract(material4UnitPrice.getOtherUnitThreePrice()).abs().compareTo(PRICE_TOLERANCE) <= 0) {
            BigDecimal baseQuantity = orderQuantity.multiply(material4UnitPrice.getRatioThree());
            return new UnitMatchResult(material4UnitPrice.getOtherUnitThree(), orderQuantity, baseQuantity, true);
        }

        // 5. 默认返回基本单位（如果无法匹配）
        return new UnitMatchResult(material4UnitPrice.getBasicUnit(), orderQuantity, orderQuantity, false);
    }



    /**
     * 将基本单位数量转换为订单单位数量
     */
    private BigDecimal convertToOrderUnitQuantity(BigDecimal baseQuantity, String orderUnit, Material4UnitPrice material4UnitPrice) {
        if (orderUnit.equals(material4UnitPrice.getBasicUnit())) {
            return baseQuantity;
        } else if (orderUnit.equals(material4UnitPrice.getOtherUnit())) {
            return baseQuantity.divide(material4UnitPrice.getRatio());
        } else if (orderUnit.equals(material4UnitPrice.getOtherUnitTwo())) {
            return baseQuantity.divide(material4UnitPrice.getRatioTwo());
        } else if (orderUnit.equals(material4UnitPrice.getOtherUnitThree())) {
            return baseQuantity.divide(material4UnitPrice.getRatioThree());
        }
        return baseQuantity;
    }

    /**
     * 获取单位的换算比例
     */
    private BigDecimal getUnitRatio(String unit, Material4UnitPrice material4UnitPrice) {
        if (unit.equals(material4UnitPrice.getBasicUnit())) {
            return BigDecimal.ONE;
        } else if (unit.equals(material4UnitPrice.getOtherUnit())) {
            return material4UnitPrice.getRatio();
        } else if (unit.equals(material4UnitPrice.getOtherUnitTwo())) {
            return material4UnitPrice.getRatioTwo();
        } else if (unit.equals(material4UnitPrice.getOtherUnitThree())) {
            return material4UnitPrice.getRatioThree();
        }
        return BigDecimal.ONE;
    }

    /**
     * 单位匹配结果类
     */
    private static class UnitMatchResult {
        private String matchedUnit;          // 匹配到的单位
        private BigDecimal orderUnitQuantity; // 订单单位数量
        private BigDecimal baseQuantity;     // 基本单位数量
        private boolean isLargeUnit;         // 是否是大单位

        public UnitMatchResult(String matchedUnit, BigDecimal orderUnitQuantity,
                               BigDecimal baseQuantity, boolean isLargeUnit) {
            this.matchedUnit = matchedUnit;
            this.orderUnitQuantity = orderUnitQuantity;
            this.baseQuantity = baseQuantity;
            this.isLargeUnit = isLargeUnit;
        }

        // getter方法
        public String getMatchedUnit() {
            return matchedUnit;
        }

        public BigDecimal getBaseQuantity() {
            return baseQuantity;
        }

        public boolean isLargeUnit() {
            return isLargeUnit;
        }

        public BigDecimal getOrderUnitQuantity() {
            return orderUnitQuantity;
        }

    }


}