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.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;
import com.qdb.sdk.QdbClient;
import com.qdb.sdk.QdbException;
import com.qdb.sdk.model.request.OrderGoods;
import com.qdb.sdk.model.request.OrderSaveRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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 com.alibaba.fastjson2.JSON;
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 DeviceInventoryMapper deviceInventoryMapper;
    private final ProductMapper productMapper;
    private final ErpGoodsMapper erpGoodsMapper;
    private final com.haha.service.DeviceInventoryService deviceInventoryService;

    @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);

        // 批量设置 orderId + 批量插入（1 次 INSERT 替代 N 次逐条）
        for (ReplenishmentOrderItem item : items) {
            item.setOrderId(order.getId());
            item.setCreateTime(LocalDateTime.now());
        }
        if (!items.isEmpty()) {
            orderItemMapper.insertBatch(items);
        }

        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;
            List<ReplenishmentOrderItem> newItems = new ArrayList<>();

            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());
                newItems.add(item);
            }
            if (!newItems.isEmpty()) {
                orderItemMapper.insertBatch(newItems);
            }

            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) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.SUBMITTED.getCode()) {
            throw new BusinessException(400, "仅已提交状态的补货单可同步ERP");
        }

        if (qdbClient == null) {
            throw new BusinessException(500, "ERP SDK 未配置，无法同步");
        }

        // 查询设备（获取 erpShopId 和 deviceName）
        Device device = deviceMapper.selectByDeviceId(order.getDeviceId());
        if (device == null) {
            throw new BusinessException(400, "设备不存在: " + order.getDeviceId());
        }
        if (device.getErpShopId() == null) {
            throw new BusinessException(400, "设备未绑定ERP店铺");
        }

        // 查询门店（获取收件人地址和联系方式）
        Shop shop = null;
        if (order.getShopId() != null) {
            shop = shopMapper.selectById(order.getShopId());
        }
        if (shop == null) {
            throw new BusinessException(400, "门店信息不存在");
        }

        // 校验门店必填字段（ERP 要求收件人信息完整）
        if (!StringUtils.hasText(shop.getContactName())) {
            throw new BusinessException(400, "门店「" + shop.getName() + "」未设置联系人姓名，请先在门店管理中完善信息");
        }
        if (!StringUtils.hasText(shop.getContactPhone())) {
            throw new BusinessException(400, "门店「" + shop.getName() + "」未设置联系电话，请先在门店管理中完善信息");
        }
        if (!StringUtils.hasText(shop.getProvince())
                || !StringUtils.hasText(shop.getCity())
                || !StringUtils.hasText(shop.getDistrict())
                || !StringUtils.hasText(shop.getAddress())) {
            throw new BusinessException(400, "门店「" + shop.getName() + "」收件地址不完整（省/市/区/详细地址），请先在门店管理中完善信息");
        }

        // 查询明细
        List<ReplenishmentOrderItem> items = orderItemMapper.selectByOrderId(id);
        if (items == null || items.isEmpty()) {
            throw new BusinessException(400, "补货单无明细");
        }

        // 批量查询 Product
        Set<String> productCodes = items.stream()
                .map(ReplenishmentOrderItem::getProductCode)
                .filter(org.springframework.util.StringUtils::hasText)
                .collect(Collectors.toSet());

        Map<String, Product> productMap = new HashMap<>();
        if (!productCodes.isEmpty()) {
            List<Product> products = productMapper.selectList(
                    new LambdaQueryWrapper<Product>().in(Product::getCode, productCodes));
            productMap = products.stream().collect(Collectors.toMap(Product::getCode, p -> p, (a, b) -> a));
        }

        // 批量查询 ERP 商品（t_product.erp_goods_id = t_erp_goods.erp_goods_id）
        Set<Long> erpGoodsIds = productMap.values().stream()
                .map(Product::getErpGoodsId).filter(Objects::nonNull).collect(Collectors.toSet());
        Map<Long, String> erpGoodsCodeMap = new HashMap<>();
        if (!erpGoodsIds.isEmpty()) {
            List<ErpGoods> erpGoodsList = erpGoodsMapper.selectList(
                    new LambdaQueryWrapper<ErpGoods>().in(ErpGoods::getErpGoodsId, erpGoodsIds));
            erpGoodsCodeMap = erpGoodsList.stream()
                    .collect(Collectors.toMap(ErpGoods::getErpGoodsId, ErpGoods::getGoodsCode, (a, b) -> a));
        }

        // 构建订单商品列表
        List<OrderGoods> ordersGoods = new ArrayList<>();
        for (ReplenishmentOrderItem item : items) {
            String productCode = item.getProductCode();
            Product product = productMap.get(productCode);
            if (product == null || product.getErpGoodsId() == null) {
                log.error("syncToErp 商品无ERP关联: name={}, code={}",
                        item.getProductName(), productCode);
                throw new BusinessException(400,
                        "商品「" + item.getProductName() + "」未关联ERP商品，请先在ERP商品管理中绑定");
            }

            String goodsCode = erpGoodsCodeMap.get(product.getErpGoodsId());
            if (goodsCode == null) {
                throw new BusinessException(400,
                        "商品「" + item.getProductName() + "」ERP商品编码未找到");
            }

            // 单价优先级: 补货明细 > 商品零售价(Product.retailPrice) > 商品售价(Product.price)
            BigDecimal price = item.getUnitPrice();
            if (price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
                if (product != null && product.getRetailPrice() != null && product.getRetailPrice() > 0) {
                    price = BigDecimal.valueOf(product.getRetailPrice());
                } else if (product != null && product.getPrice() != null && product.getPrice() > 0) {
                    price = BigDecimal.valueOf(product.getPrice());
                }
            }
            if (price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
                throw new BusinessException(400,
                        "商品「" + item.getProductName() + "」无有效单价，请先在补货明细中填写单价或确保商品有零售价");
            }
            BigDecimal quantity = BigDecimal.valueOf(item.getPlannedQuantity() != null ? item.getPlannedQuantity() : 0);

            OrderGoods goods = OrderGoods.builder()
                    .platformGoodsCode(goodsCode)
                    .goodsPlatformCode(goodsCode)
                    .platformGoodsName(item.getProductName())
                    .quantity(quantity)
                    .price(price)
                    .realPrice(price)
                    .build();
            ordersGoods.add(goods);
        }

        // 构建请求
        OrderSaveRequest request = OrderSaveRequest.builder()
                .shopId(device.getErpShopId())
                .tradeNo(order.getOrderNo())
                .platformTradeStatus("02")
                .platformRefundStatus("0")
                .orderTypeCode("3")
                .postAmount(BigDecimal.ZERO)
                .payAmount(BigDecimal.ZERO)
                .receiverProvince(shop.getProvince())
                .receiverCity(shop.getCity())
                .receiverDistrict(shop.getDistrict())
                .receiverAddress(shop.getAddress())
                .receiverName(shop.getContactName())
                .receiverMobile(shop.getContactPhone())
                .receiverPhone(shop.getContactPhone())
                .warehouseName("充电桩餐饮项目")
                .vipName(device.getName())
                // 物流公司编码 001 = 深圳市丰渡供应链管理有限公司
                .platformLogisticsCompanyCode("001")
                .ordersGoods(ordersGoods)
                .build();

        try {
            // 打开发送给 ERP 的完整 JSON，定位"必填参数未填"时使用
            if (log.isInfoEnabled()) {
                log.info("syncToErp 请求参数: {}", JSON.toJSONString(request));
            }
            qdbClient.getOrderApi().saveOrder(request);
            log.info("补货单同步ERP成功: orderNo={}, items={}", order.getOrderNo(), ordersGoods.size());
        } catch (QdbException e) {
            log.error("补货单同步ERP失败: orderNo={}, request={}, error={}",
                    order.getOrderNo(), JSON.toJSONString(request), e.getMessage(), e);
            throw new BusinessException(500, "ERP同步失败: " + e.getMessage());
        }

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

        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);
        List<ReplenishmentOrderItem> validItems = items.stream()
                .filter(it -> it.getPlannedQuantity() != null && it.getPlannedQuantity() > 0)
                .toList();

        if (!validItems.isEmpty()) {
            // 1. 批量查询已有库存（1 次 SELECT IN）
            List<Long> productIds = validItems.stream()
                    .map(ReplenishmentOrderItem::getProductId).toList();
            List<DeviceInventory> existingInventories = deviceInventoryMapper.selectList(
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<DeviceInventory>()
                            .eq(DeviceInventory::getDeviceId, order.getDeviceId())
                            .in(DeviceInventory::getProductId, productIds));
            Map<Long, DeviceInventory> inventoryByProductId = new HashMap<>();
            for (DeviceInventory inv : existingInventories) {
                inventoryByProductId.put(inv.getProductId(), inv);
            }

            // 2. 区分新建和更新
            List<DeviceInventory> toInsert = new ArrayList<>();
            List<DeviceInventory> toUpdate = new ArrayList<>();

            for (ReplenishmentOrderItem item : validItems) {
                DeviceInventory inv = inventoryByProductId.get(item.getProductId());
                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());
                }

                int beforeStock = inv.getStock() != null ? inv.getStock() : 0;
                int afterStock = beforeStock + item.getPlannedQuantity();
                inv.setStock(afterStock);
                inv.setLastRestockTime(LocalDateTime.now());
                inv.setUpdateTime(LocalDateTime.now());
                (inv.getId() == null ? toInsert : toUpdate).add(inv);

                item.setBeforeStock(beforeStock);
                item.setAfterStock(afterStock);
                if (item.getActualQuantity() == null) {
                    item.setActualQuantity(item.getPlannedQuantity());
                }

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

            // 3. 批量写入（1 次批量 INSERT + 1 次批量 UPDATE）
            if (!toInsert.isEmpty()) {
                deviceInventoryService.saveBatch(toInsert);
            }
            if (!toUpdate.isEmpty()) {
                deviceInventoryService.updateBatchById(toUpdate);
            }

            // 4. 更新补货单明细的 beforeStock/afterStock（已从内存设置，逐条 updateById）
            for (ReplenishmentOrderItem item : validItems) {
                orderItemMapper.updateById(item);
            }
        }

        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));
        }

        // 批量查询库存（含 standardStock 字段）
        List<DeviceInventory> allInventories = deviceInventoryMapper.selectList(
                new LambdaQueryWrapper<DeviceInventory>().in(DeviceInventory::getDeviceId, deviceIds));
        Map<String, List<DeviceInventory>> inventoryByDevice = new HashMap<>();
        Set<String> allCodes = new HashSet<>();
        for (DeviceInventory inv : allInventories) {
            inventoryByDevice.computeIfAbsent(inv.getDeviceId(), k -> new java.util.ArrayList<>()).add(inv);
            if (inv.getProductCode() != null) allCodes.add(inv.getProductCode());
        }

        // 批量查询 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));
        }

        // 生成补货建议：直接使用 DeviceInventory.standardStock
        List<ReplenishmentSuggestionVO> result = new java.util.ArrayList<>();

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

            List<DeviceInventory> deviceInvs = inventoryByDevice.getOrDefault(deviceId, new java.util.ArrayList<>());
            if (deviceInvs.isEmpty()) continue;

            List<SuggestionItem> items = new java.util.ArrayList<>();
            for (DeviceInventory inv : deviceInvs) {
                int standardStock = inv.getStandardStock() != null ? inv.getStandardStock() : 0;
                if (standardStock == 0) continue; // 无标准库存的跳过

                int currentStock = inv.getStock() != null ? inv.getStock() : 0;
                int suggestedQty = standardStock - currentStock;
                if (suggestedQty <= 0) continue;

                SuggestionItem item = new SuggestionItem();
                item.setProductCode(inv.getProductCode());
                item.setTemplateStock(standardStock);
                item.setCurrentStock(currentStock);
                item.setSuggestedQuantity(suggestedQty);
                item.setShelfNum(inv.getShelfNum());
                item.setPosition(inv.getPosition());

                Product product = productMap.get(inv.getProductCode());
                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());
                    }
                }
                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;
    }

    /**
     * 生成补货单号：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());
        }
    }
}
