package com.haha.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haha.common.dto.FloorConfig;
import com.haha.common.dto.GoodsItem;
import com.haha.common.enums.ReplenishmentOrderStatusEnum;
import com.haha.common.exception.BusinessException;
import com.haha.entity.*;
import com.haha.entity.dto.ReplenishmentOrderCreateDTO;
import com.haha.entity.dto.ReplenishmentOrderQueryDTO;
import com.haha.entity.dto.ReplenishmentOrderUpdateDTO;
import com.haha.entity.dto.ReplenishmentSuggestionVO;
import com.haha.entity.dto.ReplenishmentSuggestionVO.SuggestionItem;
import com.haha.mapper.*;
import com.haha.service.ReplenishmentOrderService;
// TODO: 企得宝 ERP SDK - 暂未对接，后续接入时取消注释
// import com.qdb.sdk.QdbClient;
// import com.qdb.sdk.QdbException;
// import com.qdb.sdk.model.request.OrderGoods;
// import com.qdb.sdk.model.request.OrderPay;
// import com.qdb.sdk.model.request.OrderSaveRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

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

/**
 * 补货单服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ReplenishmentOrderServiceImpl extends ServiceImpl<ReplenishmentOrderMapper, ReplenishmentOrder>
        implements ReplenishmentOrderService {

    private final ReplenishmentOrderMapper orderMapper;
    private final ReplenishmentOrderItemMapper orderItemMapper;
    private final DeviceMapper deviceMapper;
    private final ShopMapper shopMapper;
    private final LayerTemplateMapper layerTemplateMapper;
    private final DeviceInventoryMapper deviceInventoryMapper;
    private final ProductMapper productMapper;

    private final ObjectMapper objectMapper = new ObjectMapper();

    // TODO: 企得宝 ERP SDK - 暂未对接，后续接入时取消注释
    // @Autowired(required = false)
    // private QdbClient qdbClient;

    @Override
    public IPage<ReplenishmentOrder> getPage(ReplenishmentOrderQueryDTO queryDTO) {
        queryDTO.validate();

        LambdaQueryWrapper<ReplenishmentOrder> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(queryDTO.getOrderNo())) {
            wrapper.like(ReplenishmentOrder::getOrderNo, queryDTO.getOrderNo());
        }
        if (StringUtils.hasText(queryDTO.getDeviceId())) {
            wrapper.eq(ReplenishmentOrder::getDeviceId, queryDTO.getDeviceId());
        }
        if (queryDTO.getShopId() != null) {
            wrapper.eq(ReplenishmentOrder::getShopId, queryDTO.getShopId());
        }
        if (queryDTO.getStatus() != null) {
            wrapper.eq(ReplenishmentOrder::getStatus, queryDTO.getStatus());
        }
        if (queryDTO.getCreatorId() != null) {
            wrapper.eq(ReplenishmentOrder::getCreatorId, queryDTO.getCreatorId());
        }
        if (StringUtils.hasText(queryDTO.getStartTime())) {
            wrapper.ge(ReplenishmentOrder::getCreateTime,
                    LocalDate.parse(queryDTO.getStartTime()).atStartOfDay());
        }
        if (StringUtils.hasText(queryDTO.getEndTime())) {
            wrapper.le(ReplenishmentOrder::getCreateTime,
                    LocalDate.parse(queryDTO.getEndTime()).atTime(23, 59, 59));
        }

        wrapper.orderByDesc(ReplenishmentOrder::getCreateTime);

        Page<ReplenishmentOrder> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        IPage<ReplenishmentOrder> result = page(page, wrapper);

        // 批量查询补货单明细数量，避免 N+1
        List<Long> orderIds = result.getRecords().stream()
                .map(ReplenishmentOrder::getId).collect(Collectors.toList());
        Map<Long, Long> countMap = new HashMap<>();
        if (!orderIds.isEmpty()) {
            List<ReplenishmentOrderItem> allItems = orderItemMapper.selectList(
                    new LambdaQueryWrapper<ReplenishmentOrderItem>()
                            .in(ReplenishmentOrderItem::getOrderId, orderIds));
            countMap = allItems.stream().collect(Collectors.groupingBy(
                    ReplenishmentOrderItem::getOrderId, Collectors.counting()));
        }

        for (ReplenishmentOrder order : result.getRecords()) {
            fillStatusLabel(order);
            order.setItemCount(countMap.getOrDefault(order.getId(), 0L).intValue());
        }

        // 批量填充 shopName 和 deviceName
        populateNames(result.getRecords());

        return result;
    }

    @Override
    public ReplenishmentOrder getDetailWithItems(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        fillStatusLabel(order);
        populateNames(java.util.Collections.singletonList(order));
        return order;
    }

    @Override
    public List<ReplenishmentOrderItem> getItems(Long orderId) {
        List<ReplenishmentOrderItem> items = orderItemMapper.selectByOrderId(orderId);
        // 批量填充商品图片
        Set<String> codes = items.stream()
                .map(ReplenishmentOrderItem::getProductCode).filter(StringUtils::hasText)
                .collect(Collectors.toSet());
        Map<String, String> imageMap = new HashMap<>();
        if (!codes.isEmpty()) {
            List<Product> products = productMapper.selectList(
                    new LambdaQueryWrapper<Product>().in(Product::getCode, codes));
            imageMap = products.stream()
                    .filter(p -> p.getPic() != null)
                    .collect(Collectors.toMap(Product::getCode, Product::getPic, (a, b) -> a));
        }
        for (ReplenishmentOrderItem item : items) {
            if (item.getProductCode() != null) {
                item.setProductImage(imageMap.get(item.getProductCode()));
            }
        }
        return items;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder createOrder(ReplenishmentOrderCreateDTO dto, Long creatorId, String creatorName) {
        ReplenishmentOrder order = new ReplenishmentOrder();
        order.setOrderNo(generateOrderNo());
        order.setDeviceId(dto.getDeviceId());
        order.setShopId(dto.getShopId());
        order.setStatus(ReplenishmentOrderStatusEnum.DRAFT.getCode());
        order.setSupplierName(dto.getSupplierName());
        order.setWarehouseName(dto.getWarehouseName());
        order.setExpectedArrivalTime(dto.getExpectedArrivalTime());
        order.setRemark(dto.getRemark());
        order.setCreatorId(creatorId);
        order.setCreatorName(creatorName);
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());

        int totalQuantity = 0;
        BigDecimal totalAmount = BigDecimal.ZERO;
        List<ReplenishmentOrderItem> items = new ArrayList<>();

        for (ReplenishmentOrderCreateDTO.ReplenishmentOrderItemDTO itemDto : dto.getItems()) {
            ReplenishmentOrderItem item = new ReplenishmentOrderItem();
            item.setDeviceId(dto.getDeviceId());
            item.setProductId(itemDto.getProductId());
            item.setProductCode(itemDto.getProductCode());
            item.setProductName(itemDto.getProductName());
            item.setPlannedQuantity(itemDto.getPlannedQuantity());
            item.setUnitPrice(itemDto.getUnitPrice());
            item.setShelfNum(itemDto.getShelfNum());
            item.setPosition(itemDto.getPosition());

            if (itemDto.getUnitPrice() != null) {
                BigDecimal itemTotal = itemDto.getUnitPrice()
                        .multiply(BigDecimal.valueOf(itemDto.getPlannedQuantity()));
                item.setTotalPrice(itemTotal);
                totalAmount = totalAmount.add(itemTotal);
            }
            totalQuantity += itemDto.getPlannedQuantity();
            items.add(item);
        }

        order.setTotalQuantity(totalQuantity);
        order.setTotalAmount(totalAmount);

        save(order);

        for (ReplenishmentOrderItem item : items) {
            item.setOrderId(order.getId());
            item.setCreateTime(LocalDateTime.now());
            orderItemMapper.insert(item);
        }

        log.info("创建补货单: orderNo={}, deviceId={}, items={}", order.getOrderNo(), dto.getDeviceId(), items.size());

        fillStatusLabel(order);
        order.setItemCount(items.size());
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder updateOrder(ReplenishmentOrderUpdateDTO dto) {
        ReplenishmentOrder order = getById(dto.getId());
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.DRAFT.getCode()) {
            throw new BusinessException(400, "仅草稿状态的补货单可编辑");
        }

        if (dto.getSupplierName() != null) {
            order.setSupplierName(dto.getSupplierName());
        }
        if (dto.getWarehouseName() != null) {
            order.setWarehouseName(dto.getWarehouseName());
        }
        if (dto.getExpectedArrivalTime() != null) {
            order.setExpectedArrivalTime(dto.getExpectedArrivalTime());
        }
        if (dto.getRemark() != null) {
            order.setRemark(dto.getRemark());
        }
        order.setUpdateTime(LocalDateTime.now());

        if (dto.getItems() != null && !dto.getItems().isEmpty()) {
            orderItemMapper.deleteByOrderId(dto.getId());

            int totalQuantity = 0;
            BigDecimal totalAmount = BigDecimal.ZERO;

            for (ReplenishmentOrderCreateDTO.ReplenishmentOrderItemDTO itemDto : dto.getItems()) {
                ReplenishmentOrderItem item = new ReplenishmentOrderItem();
                item.setOrderId(dto.getId());
                item.setDeviceId(order.getDeviceId());
                item.setProductId(itemDto.getProductId());
                item.setProductCode(itemDto.getProductCode());
                item.setProductName(itemDto.getProductName());
                item.setPlannedQuantity(itemDto.getPlannedQuantity());
                item.setUnitPrice(itemDto.getUnitPrice());
                item.setShelfNum(itemDto.getShelfNum());
                item.setPosition(itemDto.getPosition());

                if (itemDto.getUnitPrice() != null) {
                    BigDecimal itemTotal = itemDto.getUnitPrice()
                            .multiply(BigDecimal.valueOf(itemDto.getPlannedQuantity()));
                    item.setTotalPrice(itemTotal);
                    totalAmount = totalAmount.add(itemTotal);
                }
                totalQuantity += itemDto.getPlannedQuantity();
                item.setCreateTime(LocalDateTime.now());
                orderItemMapper.insert(item);
            }

            order.setTotalQuantity(totalQuantity);
            order.setTotalAmount(totalAmount);
        }

        updateById(order);

        log.info("更新补货单: id={}, orderNo={}", dto.getId(), order.getOrderNo());

        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.DRAFT.getCode()) {
            throw new BusinessException(400, "仅草稿状态的补货单可删除");
        }

        orderItemMapper.deleteByOrderId(id);
        removeById(id);

        log.info("删除补货单: id={}, orderNo={}", id, order.getOrderNo());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder submitOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.DRAFT.getCode()) {
            throw new BusinessException(400, "仅草稿状态的补货单可提交");
        }

        order.setStatus(ReplenishmentOrderStatusEnum.SUBMITTED.getCode());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);

        log.info("提交补货单: id={}, orderNo={}", id, order.getOrderNo());

        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder syncToErp(Long id) {
        // TODO: 企得宝 ERP SDK - 暂未对接，后续接入时实现
        log.warn("syncToErp 暂未实现，企得宝 ERP SDK 尚未接入: id={}", id);
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder completeOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.SYNCED_TO_ERP.getCode()) {
            throw new BusinessException(400, "仅已同步ERP的补货单可完成");
        }

        // 同步更新设备库存
        List<ReplenishmentOrderItem> items = orderItemMapper.selectByOrderId(id);
        for (ReplenishmentOrderItem item : items) {
            if (item.getPlannedQuantity() == null || item.getPlannedQuantity() <= 0) continue;

            // 查找或创建库存记录
            LambdaQueryWrapper<DeviceInventory> wrapper = new LambdaQueryWrapper<DeviceInventory>()
                    .eq(DeviceInventory::getDeviceId, order.getDeviceId())
                    .eq(DeviceInventory::getProductCode, item.getProductCode());
            DeviceInventory inv = deviceInventoryMapper.selectOne(wrapper);
            if (inv == null) {
                inv = new DeviceInventory();
                inv.setDeviceId(order.getDeviceId());
                inv.setProductId(item.getProductId());
                inv.setProductCode(item.getProductCode());
                inv.setProductName(item.getProductName());
                inv.setStock(0);
                inv.setShelfNum(item.getShelfNum());
                inv.setPosition(item.getPosition());
                inv.setWarningThreshold(5);
                inv.setCreateTime(LocalDateTime.now());
                inv.setUpdateTime(LocalDateTime.now());
            }

            int beforeStock = inv.getStock() != null ? inv.getStock() : 0;
            int afterStock = beforeStock + item.getPlannedQuantity();
            inv.setStock(afterStock);
            inv.setLastRestockTime(LocalDateTime.now());
            inv.setUpdateTime(LocalDateTime.now());
            if (inv.getId() == null) {
                deviceInventoryMapper.insert(inv);
            } else {
                deviceInventoryMapper.updateById(inv);
            }

            item.setBeforeStock(beforeStock);
            item.setAfterStock(afterStock);
            item.setActualQuantity(item.getPlannedQuantity());
            orderItemMapper.updateById(item);

            log.info("更新设备库存: deviceId={}, productCode={}, {} -> {}",
                    order.getDeviceId(), item.getProductCode(), beforeStock, afterStock);
        }

        order.setStatus(ReplenishmentOrderStatusEnum.COMPLETED.getCode());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);

        log.info("完成补货单: id={}, orderNo={}, items={}", id, order.getOrderNo(), items.size());

        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder cancelOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        int status = order.getStatus();
        if (status != ReplenishmentOrderStatusEnum.DRAFT.getCode()
                && status != ReplenishmentOrderStatusEnum.SUBMITTED.getCode()) {
            throw new BusinessException(400, "仅草稿或已提交状态的补货单可取消");
        }

        order.setStatus(ReplenishmentOrderStatusEnum.CANCELLED.getCode());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);

        log.info("取消补货单: id={}, orderNo={}", id, order.getOrderNo());

        fillStatusLabel(order);
        return order;
    }

    /**
     * 批量填充 shopName 和 deviceName
     */
    private void populateNames(List<ReplenishmentOrder> orders) {
        Set<Long> shopIds = orders.stream()
                .map(ReplenishmentOrder::getShopId).filter(id -> id != null).collect(Collectors.toSet());
        Set<String> deviceIds = orders.stream()
                .map(ReplenishmentOrder::getDeviceId).filter(StringUtils::hasText).collect(Collectors.toSet());

        Map<Long, String> shopNameMap = new HashMap<>();
        if (!shopIds.isEmpty()) {
            List<Shop> shops = shopMapper.selectBatchIds(shopIds);
            shopNameMap = shops.stream().collect(Collectors.toMap(Shop::getId, Shop::getName, (a, b) -> a));
        }

        Map<String, String> deviceNameMap = new HashMap<>();
        if (!deviceIds.isEmpty()) {
            List<Device> devices = deviceMapper.selectList(
                    new LambdaQueryWrapper<Device>().in(Device::getDeviceId, deviceIds));
            deviceNameMap = devices.stream().collect(Collectors.toMap(Device::getDeviceId, Device::getName, (a, b) -> a));
        }

        for (ReplenishmentOrder order : orders) {
            order.setShopName(shopNameMap.getOrDefault(order.getShopId(), ""));
            order.setDeviceName(deviceNameMap.getOrDefault(order.getDeviceId(), ""));
        }
    }

    @Override
    public List<ReplenishmentSuggestionVO> getSuggestions(List<String> deviceIds) {
        if (deviceIds == null || deviceIds.isEmpty()) {
            return java.util.Collections.emptyList();
        }

        // 批量查询设备
        List<Device> devices = deviceMapper.selectList(
                new LambdaQueryWrapper<Device>().in(Device::getDeviceId, deviceIds));
        Map<String, Device> deviceMap = devices.stream()
                .collect(Collectors.toMap(Device::getDeviceId, d -> d, (a, b) -> a));

        // 批量查询门店
        Set<Long> shopIds = devices.stream().map(Device::getShopId).filter(id -> id != null).collect(Collectors.toSet());
        Map<Long, String> shopNameMap = new HashMap<>();
        if (!shopIds.isEmpty()) {
            shopNameMap = shopMapper.selectBatchIds(shopIds).stream()
                    .collect(Collectors.toMap(Shop::getId, Shop::getName, (a, b) -> a));
        }

        // 批量查询层模版
        List<LayerTemplate> allTemplates = new java.util.ArrayList<>();
        for (String deviceId : deviceIds) {
            allTemplates.addAll(layerTemplateMapper.selectByDeviceId(deviceId));
        }
        Map<String, List<LayerTemplate>> templateMap = allTemplates.stream()
                .collect(Collectors.groupingBy(LayerTemplate::getDeviceId));

        // 批量查询当前库存
        List<DeviceInventory> allInventories = deviceInventoryMapper.selectList(
                new LambdaQueryWrapper<DeviceInventory>().in(DeviceInventory::getDeviceId, deviceIds));
        Map<String, Map<String, DeviceInventory>> inventoryMap = new HashMap<>();
        for (DeviceInventory inv : allInventories) {
            inventoryMap.computeIfAbsent(inv.getDeviceId(), k -> new HashMap<>())
                    .put(inv.getProductCode(), inv);
        }

        // 收集所有需要查询的 productCode
        Set<String> allCodes = new HashSet<>();
        for (String deviceId : deviceIds) {
            List<LayerTemplate> temps = templateMap.getOrDefault(deviceId, java.util.Collections.emptyList());
            for (LayerTemplate temp : temps) {
                for (FloorConfig floor : parseFloors(temp.getLeftFloors())) {
                    for (GoodsItem goods : floor.getGoods()) {
                        if (goods.getKey() != null) allCodes.add(goods.getKey());
                    }
                }
                for (FloorConfig floor : parseFloors(temp.getRightFloors())) {
                    for (GoodsItem goods : floor.getGoods()) {
                        if (goods.getKey() != null) allCodes.add(goods.getKey());
                    }
                }
            }
        }

        // 批量查询 Product（按 code）
        Map<String, Product> productMap = new HashMap<>();
        if (!allCodes.isEmpty()) {
            List<Product> products = productMapper.selectList(
                    new LambdaQueryWrapper<Product>().in(Product::getCode, allCodes));
            productMap = products.stream().collect(Collectors.toMap(Product::getCode, p -> p, (a, b) -> a));
        }

        // 生成补货建议
        List<ReplenishmentSuggestionVO> result = new java.util.ArrayList<>();

        for (String deviceId : deviceIds) {
            Device device = deviceMap.get(deviceId);
            if (device == null) continue;

            // 解析模版，按 productCode 累加标准库存
            Map<String, Accumulator> accumulators = new LinkedHashMap<>();
            List<LayerTemplate> temps = templateMap.getOrDefault(deviceId, java.util.Collections.emptyList());
            for (LayerTemplate temp : temps) {
                int floorNum = temp.getShelfNum() != null ? temp.getShelfNum() : 1;
                for (FloorConfig floor : parseFloors(temp.getLeftFloors())) {
                    for (GoodsItem goods : floor.getGoods()) {
                        if (goods.getKey() != null && goods.getStock() != null && goods.getStock() > 0) {
                            accumulators.computeIfAbsent(goods.getKey(), k -> new Accumulator())
                                    .addTemplateStock(goods.getStock(), floorNum, "left", goods.getPic());
                        }
                    }
                }
                for (FloorConfig floor : parseFloors(temp.getRightFloors())) {
                    for (GoodsItem goods : floor.getGoods()) {
                        if (goods.getKey() != null && goods.getStock() != null && goods.getStock() > 0) {
                            accumulators.computeIfAbsent(goods.getKey(), k -> new Accumulator())
                                    .addTemplateStock(goods.getStock(), floorNum, "right", goods.getPic());
                        }
                    }
                }
            }

            if (accumulators.isEmpty()) continue;

            // 获取当前库存
            Map<String, DeviceInventory> deviceInvs = inventoryMap.getOrDefault(deviceId, new HashMap<>());

            List<SuggestionItem> items = new java.util.ArrayList<>();
            for (Map.Entry<String, Accumulator> entry : accumulators.entrySet()) {
                String code = entry.getKey();
                Accumulator acc = entry.getValue();
                int currentStock = deviceInvs.containsKey(code) ? deviceInvs.get(code).getStock() : 0;
                int suggestedQty = acc.templateStock - currentStock;
                if (suggestedQty <= 0) continue;

                SuggestionItem item = new SuggestionItem();
                item.setProductCode(code);
                item.setTemplateStock(acc.templateStock);
                item.setCurrentStock(currentStock);
                item.setSuggestedQuantity(suggestedQty);
                item.setShelfNum(acc.shelfNum);
                item.setPosition(acc.position);

                Product product = productMap.get(code);
                if (product != null) {
                    item.setProductId(product.getId());
                    item.setProductName(product.getName());
                    if (product.getRetailPrice() != null) {
                        item.setUnitPrice(BigDecimal.valueOf(product.getRetailPrice()));
                    }
                    if (product.getPic() != null) {
                        item.setProductImage(product.getPic());
                    }
                }
                if (item.getProductImage() == null && acc.productImage != null) {
                    item.setProductImage(acc.productImage);
                }
                items.add(item);
            }

            if (!items.isEmpty()) {
                ReplenishmentSuggestionVO vo = new ReplenishmentSuggestionVO();
                vo.setDeviceId(deviceId);
                vo.setDeviceName(device.getName());
                vo.setShopId(device.getShopId());
                vo.setShopName(shopNameMap.getOrDefault(device.getShopId(), ""));
                vo.setItems(items);
                result.add(vo);
            }
        }

        return result;
    }

    /**
     * 解析楼层 JSON 字符串
     */
    private List<FloorConfig> parseFloors(String floorsJson) {
        if (!StringUtils.hasText(floorsJson)) {
            return java.util.Collections.emptyList();
        }
        try {
            return objectMapper.readValue(floorsJson, new TypeReference<List<FloorConfig>>() {});
        } catch (Exception e) {
            log.warn("解析楼层JSON失败: {}", e.getMessage());
            return java.util.Collections.emptyList();
        }
    }

    /**
     * 累加器：合并同一商品在多层的标准库存
     */
    private static class Accumulator {
        int templateStock = 0;
        int shelfNum = 0;
        String position = "";
        String productImage;

        void addTemplateStock(int stock, int floor, String pos, String image) {
            this.templateStock += stock;
            if (this.position.isEmpty()) {
                this.shelfNum = floor;
                this.position = pos;
            }
            if (this.productImage == null && image != null) {
                this.productImage = image;
            }
        }
    }
    /**
     * 生成补货单号：RO + yyyyMMdd + 4位序号
     */
    private String generateOrderNo() {
        String datePrefix = "RO" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String maxNo = orderMapper.selectMaxOrderNoToday();
        int seq = 1;
        if (maxNo != null && maxNo.startsWith(datePrefix)) {
            try {
                seq = Integer.parseInt(maxNo.substring(maxNo.length() - 4)) + 1;
            } catch (NumberFormatException e) {
                log.warn("解析补货单号失败: {}", maxNo);
            }
        }
        return datePrefix + String.format("%04d", seq);
    }

    private void fillStatusLabel(ReplenishmentOrder order) {
        if (order.getStatus() != null) {
            var statusEnum = ReplenishmentOrderStatusEnum.getLabelByCode(order.getStatus());
            order.setStatusLabel(statusEnum.getLabel());
            order.setStatusColor(statusEnum.getColor());
        }
    }
}
