
package com.tmerclub.cloud.api.order.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.tmerclub.cloud.api.delivery.constant.StationStockStatus;
import com.tmerclub.cloud.api.delivery.feign.DeliveryFeignClient;
import com.tmerclub.cloud.api.delivery.feign.StationFeignClient;
import com.tmerclub.cloud.api.product.feign.WarehouseFeignClient;
import com.tmerclub.cloud.common.order.vo.WarehouseVO;
import com.tmerclub.cloud.api.product.feign.SkuStockFeignClient;
import com.tmerclub.cloud.api.product.vo.SkuStockVO;
import com.tmerclub.cloud.api.user.feign.UserAddrFeignClient;
import com.tmerclub.cloud.common.cache.constant.CacheNames;
import com.tmerclub.cloud.common.cache.constant.OrderCacheNames;
import com.tmerclub.cloud.common.cache.util.CacheManagerUtil;
import com.tmerclub.cloud.common.cache.util.RedisUtil;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.order.bo.DeliveryModeBO;
import com.tmerclub.cloud.common.order.constant.DeliveryType;
import com.tmerclub.cloud.common.order.constant.OrderType;
import com.tmerclub.cloud.common.order.dto.DvyTypeDTO;
import com.tmerclub.cloud.common.order.dto.OrderDTO;
import com.tmerclub.cloud.common.order.vo.*;
import com.tmerclub.cloud.common.product.constant.*;
import com.tmerclub.cloud.common.product.vo.StockPointSkuVO;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.util.PriceUtil;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 确认订单适配
 * @author tmerclub
 * @date 2020/12/07
 */
@Component
public class ConfirmOrderManager {

    private final Logger LOGGER = LoggerFactory.getLogger(ConfirmOrderManager.class);

    @Autowired
    private CacheManagerUtil cacheManagerUtil;

    @DubboReference
    private DeliveryFeignClient deliveryFeignClient;

    @DubboReference
    private SkuStockFeignClient skuStockFeignClient;

    @DubboReference
    private UserAddrFeignClient userAddrFeignClient;

    @DubboReference
    private WarehouseFeignClient warehouseFeignClient;

    @DubboReference
    private StationFeignClient stationFeignClient;

    /**
     * 过滤物流不同的商品
     * @param dbShopCartItems 用户选择的商品项
     * @return 返回过滤掉的商品项item
     */
    public List<ShopCartItemVO> filterShopItemsByType(ShopCartOrderMergerVO shopCartOrderMerger, UserDeliveryInfoVO userDeliveryInfoVO, List<ShopCartItemVO> dbShopCartItems) {
        // 校验商品是否在配送范围, 用于下面的过滤物流
        this.checkAddr(dbShopCartItems, shopCartOrderMerger.getUserId(), userDeliveryInfoVO);

        Map<Long, Integer> dvyTypeMap = userDeliveryInfoVO.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        LOGGER.info("用户配送参数为:{}" , userDeliveryInfoVO);
        List<ShopCartItemVO> cartItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<ShopCartItemVO> filterItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        // 不可配送的套餐id
        Set<Long> comboIdList = new HashSet<>(Constant.INITIAL_CAPACITY);
        for (ShopCartItemVO shopCartItem : dbShopCartItems) {
            Integer dvyType = dvyTypeMap.get(shopCartItem.getShopId());
            if (dvyType == 3 || Objects.equals(shopCartItem.getMold(), 1)) {
                shopCartItem.setPlatformShareReduce(0L);
                cartItems.add(shopCartItem);
                LOGGER.info("无需配送的商品，shopCartItem:{}", shopCartItem);
                continue;
            }
            DeliveryModeBO deliveryModeVO = shopCartItem.getDeliveryModeBO();
            boolean hasShopDelivery = deliveryModeVO.getHasShopDelivery() != null && Objects.equals(dvyType, DeliveryType.DELIVERY.value()) && deliveryModeVO.getHasShopDelivery();
            boolean hasUserPickUp = deliveryModeVO.getHasUserPickUp() != null && Objects.equals(dvyType, DeliveryType.STATION.value()) && deliveryModeVO.getHasUserPickUp();
            boolean hasCityDelivery = deliveryModeVO.getHasCityDelivery() != null && Objects.equals(dvyType, DeliveryType.SAME_CITY.value()) && deliveryModeVO.getHasCityDelivery();
            if (hasShopDelivery || hasUserPickUp || hasCityDelivery) {
                LOGGER.info("有配送方式的商品，shopCartItem:{}", shopCartItem);
                // 设置平台分摊金额，为计算完商家之后计算平台优惠做准备
                shopCartItem.setPlatformShareReduce(0L);
                 //是否只有一个商品或者只有一个套餐主商品  同时配送方式为同城配送, 不限制用户的地址是否满足配送，避免前端页面显示错误，结算订单的时候会再次判断是否满足配送
                // 过滤出实物商品
                int realItemSize = dbShopCartItems.stream().filter(item -> !Objects.equals(item.getMold(),SpuMold.VIRTUAL.value()) && Objects.equals(item.getSpuType(), SpuType.NORMAL.value())).collect(Collectors.groupingBy(ShopCartItemVO::getSpuId)).size();
                boolean isOneAndSameCity = (dbShopCartItems.size() == 1 || realItemSize == 1) && Objects.equals(dvyType, DeliveryType.SAME_CITY.value());
                // 需要过滤的订单项 - 过滤掉非自提且不在配送范围内的商品,或选择自提但不支持自提的商品
                // 1. 不支持配送、配送类型为自提，但商品不支持自提、或者配送类型为同城，但商品不支持同城
                // 2. 配送类型为同城，且只有一件商品或者套餐的订单中没有实物商品
                boolean shouldFilter = (!shopCartItem.getIsDelivery() || (dvyType == 2 && !hasUserPickUp)) && !isOneAndSameCity;
                if (shouldFilter) {
                    filterItems.add(shopCartItem);
                    LOGGER.info("过滤掉非自提且不在配送范围内的商品,或选择自提但不支持自提的商品,shopCartItem:{}", shopCartItem);
                    // 不可配送的商品是套餐商品
                    if (Objects.nonNull(shopCartItem.getComboId())) {
                        comboIdList.add(shopCartItem.getComboId());
                        LOGGER.info("过滤的商品是套餐商品,shopCartItem:{}", shopCartItem);
                    }
                } else {
                    cartItems.add(shopCartItem);
                    LOGGER.info("不过滤的商品项,shopCartItem:{}", shopCartItem);
                }
                //判断赠品的配送方式是否满足当前店铺的配送方式
                filterGiveawayShopItems(shopCartItem, dvyType);

            } else {
                LOGGER.info("不可配送的商品,shopCartItem:{}", shopCartItem);
                filterItems.add(shopCartItem);
                // 不可配送的商品是套餐商品
                if (Objects.nonNull(shopCartItem.getComboId())) {
                    LOGGER.info("不可配送的商品是套餐商品,shopCartItem:{}", shopCartItem);
                    comboIdList.add(shopCartItem.getComboId());
                }
            }
        }
        // 套餐中有一个不可配送，整个套餐都不可配送
        Iterator<ShopCartItemVO> shopCartItemIterator = cartItems.iterator();
        while (shopCartItemIterator.hasNext()) {
            ShopCartItemVO cartItem = shopCartItemIterator.next();
            if (Objects.nonNull(cartItem.getComboId()) && comboIdList.contains(cartItem.getComboId())) {
                filterItems.add(cartItem);
                shopCartItemIterator.remove();
            }
        }
        LOGGER.info("过滤掉的商品项:{}", filterItems);
        shopCartOrderMerger.setFilterShopItems(filterItems);
        return cartItems;
    }

    private static void filterGiveawayShopItems(ShopCartItemVO shopCartItem, Integer dvyType) {
        if (CollUtil.isEmpty(shopCartItem.getGiveawayShopCartItemList())) {
            return;
        }
        Iterator<ShopCartItemVO> iterator = shopCartItem.getGiveawayShopCartItemList().iterator();
        while (iterator.hasNext()) {
            ShopCartItemVO shopCartItemVO = iterator.next();
            // 虚拟商品不需要判断物流
            if (Objects.equals(shopCartItemVO.getMold(), SpuMold.VIRTUAL.value())) {
                continue;
            }
            DeliveryModeBO deliveryModeVO = shopCartItem.getDeliveryModeBO();
            // 赠品的配送方式要满足店铺的配送类型
            boolean canDelivary = (Objects.equals(DeliveryType.DELIVERY.value(), dvyType) && BooleanUtil.isTrue(deliveryModeVO.getHasShopDelivery())) ||
                    (Objects.equals(DeliveryType.STATION.value(), dvyType) && BooleanUtil.isTrue(deliveryModeVO.getHasUserPickUp())) ||
                    (Objects.equals(DeliveryType.SAME_CITY.value(), dvyType) && BooleanUtil.isTrue(deliveryModeVO.getHasCityDelivery()));
            // 不符合店铺配送类型的赠品，就不赠送了
            if (!canDelivary) {
                iterator.remove();
            }
        }
    }

    /**
     * 组合商品操作，并返回组合商品订单Map
     * @param shopCartItems 用户选择的商品项
     * @return 返回过滤掉的商品项item
     */
    public List<ShopCartItemVO> handleComboShopItems(List<ShopCartItemVO> shopCartItems) {
        List<ShopCartItemVO> comboShopCartItems = shopCartItems.stream().filter(shopCartItemVO -> Objects.equals(shopCartItemVO.getMold(), SpuMold.COMBO.value())).toList();
        if(CollectionUtil.isEmpty(comboShopCartItems)){
            return shopCartItems;
        }
        // 获取所有的非组合商品购物项item，并把组合商品的item放入新的商品项列表
        shopCartItems = shopCartItems.stream().filter(shopCartItemVO -> !Objects.equals(shopCartItemVO.getMold(), SpuMold.COMBO.value())).toList();
        List<ShopCartItemVO> filterComboShopCartItems = new ArrayList<>(shopCartItems);
        for (ShopCartItemVO comboShopCartItem : comboShopCartItems) {
            filterComboShopCartItems.addAll(comboShopCartItem.getComboShopCartItems());
        }
        return filterComboShopCartItems;
    }

    /**
     * 当算完一遍店铺的各种满减活动时，重算一遍订单金额
     */
    public void recalculateAmountWhenFinishingCalculateShop(ShopCartOrderMergerVO shopCartOrderMerger, List<ShopCartVO> shopCarts, UserDeliveryInfoVO userDeliveryInfo) {

        Map<Long, ShopTransFeeVO> shopIdWithShopTransFee = userDeliveryInfo.getShopIdWithShopTransFee();
        Map<Long, Map<Long, ShopTransFeeVO>> supplierIdWithShopTransFeeMap = userDeliveryInfo.getSupplierIdWithShopTransFeeMap();
        shopCartOrderMerger.setSupplierIdWithShopTransFeeMap(supplierIdWithShopTransFeeMap);
        shopCartOrderMerger.setPreSaleTransFeeMap(userDeliveryInfo.getPreSaleTransFeeMap());
        if (Objects.isNull(supplierIdWithShopTransFeeMap)) {
            supplierIdWithShopTransFeeMap = new HashMap<>(0);
        }
        // 所有店铺的订单信息
        List<ShopCartOrderVO> shopCartOrders = new ArrayList<>(Constant.INITIAL_CAPACITY);
        long actualTotal = 0;
        long total = 0;
        int totalCount = 0;
        long allOrderReduce = 0;
        long totalTransfee = 0;
        long scoreTotal = 0L;
        Map<Long, Integer> shopCityStatusMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (Objects.nonNull(userDeliveryInfo.getShopCityStatusVOS())) {
            shopCityStatusMap = userDeliveryInfo.getShopCityStatusVOS().stream().collect(Collectors.toMap(ShopCityStatusVO::getShopId, ShopCityStatusVO::getShopCityStatus));
        }
        Map<Long, Long> shopStartDeliveryFees = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (Objects.nonNull(userDeliveryInfo.getShopStartDeliveryFees())) {
            shopStartDeliveryFees = userDeliveryInfo.getShopStartDeliveryFees();
        }
        // 所有店铺所有的商品item
        for (ShopCartVO shopCart : shopCarts) {
            // 每个店铺的订单信息
            ShopCartOrderVO shopCartOrder = getShopCartOrderVO(shopCartOrderMerger, shopCityStatusMap, shopStartDeliveryFees, shopCart);
            total += shopCart.getTotal();
            totalCount += shopCart.getTotalCount();
            allOrderReduce += shopCart.getShopReduce();

            // 积分订单使用积分
            if (Objects.equals(shopCartOrderMerger.getOrderType(), OrderType.SCORE)) {
                shopCartOrder.setUseScore(shopCart.getScoreTotal());
            }

            // 如果某家店因为各种优惠活动满减，使得金额变为负数，则这家店最低应该支付一分钱，而里面最贵的那件商品，也是支付一分钱，优惠金额 = （商品金额 - 一分钱）
            // 平台端的订单不使用优惠，不需要此判断
            if (shopCart.getActualTotal() < 1L && !Objects.equals(shopCart.getShopId(), Constant.PLATFORM_SHOP_ID)) {
                shopCartOrder.setActualTotal(1L);
                shopCartOrder.setShopReduce(shopCart.getTotal() - 1L);

                List<ShopCartItemVO> shopCartShopCartItem = getShopShopCartItem(shopCart.getShopCartItemDiscounts());
                resetActualTotal(shopCartShopCartItem);
            }

            //店铺优惠金额 = 优惠金额
            shopCartOrder.setShopReduce(shopCartOrder.getShopReduce());

            // 计算总运费金额
            totalTransfee = calculateTransFee(shopIdWithShopTransFee, supplierIdWithShopTransFeeMap, totalTransfee, shopCart, shopCartOrder);

            handleShopReduce(shopCart, shopCartOrder);
            actualTotal += shopCartOrder.getActualTotal();
            if (Objects.equals(shopCartOrderMerger.getOrderType(), OrderType.SCORE)) {
                LOGGER.info("积分订单使用积分:{}", shopCart.getScoreTotal());
                shopCartOrder.setUseScore(shopCart.getScoreTotal());
            } else {
                shopCartOrder.setUseScore(shopCartOrder.getUseScore());
                LOGGER.info("非积分订单使用积分:{}", shopCartOrder.getUseScore());
            }
            shopCartOrder.setDiscountReduce(shopCart.getDiscountReduce());
            shopCartOrders.add(shopCartOrder);
            scoreTotal += shopCart.getScoreTotal();
        }

        shopCartOrderMerger.setActualTotal(actualTotal);
        shopCartOrderMerger.setTotal(total);
        shopCartOrderMerger.setTotalCount(totalCount);
        shopCartOrderMerger.setOrderReduce(allOrderReduce);
        shopCartOrderMerger.setTotalTransfee(totalTransfee);
        shopCartOrderMerger.setShopCartOrders(shopCartOrders);
        shopCartOrderMerger.setUserAddr(userDeliveryInfo.getUserAddr());
        shopCartOrderMerger.setShopCityStatus(userDeliveryInfo.getShopCityStatus());
        if (Objects.equals(shopCartOrderMerger.getOrderType(), OrderType.SCORE)) {
            shopCartOrderMerger.setUsableScore(scoreTotal);
        }
    }

    private static void handleShopReduce(ShopCartVO shopCart, ShopCartOrderVO shopCartOrder) {
        // 店铺优惠券优惠金额
        shopCartOrder.setCouponReduce(shopCart.getCouponReduce());
        shopCartOrder.setShopCartItemDiscounts(shopCart.getShopCartItemDiscounts());
        shopCartOrder.setCoupons(shopCart.getCoupons());
        shopCartOrder.setTotal(shopCart.getTotal());
        shopCartOrder.setTotalCount(shopCart.getTotalCount());
        shopCartOrder.setShopComboAmount(shopCart.getShopComboAmount());
    }

    private static long calculateTransFee(Map<Long, ShopTransFeeVO> shopIdWithShopTransFee, Map<Long, Map<Long, ShopTransFeeVO>> supplierIdWithShopTransFeeMap, long totalTransfee, ShopCartVO shopCart, ShopCartOrderVO shopCartOrder) {
        Set<Long> supplierIds = new HashSet<>(Constant.INITIAL_CAPACITY);
        // 计算当前店铺的供应商发货商品运费
        for (ShopCartItemDiscountVO shopCartItemDiscount : shopCart.getShopCartItemDiscounts()) {
            Set<Long> ids = shopCartItemDiscount.getShopCartItems().stream().filter(shopCartItemVO -> Objects.equals(shopCartItemVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value()))
                    .map(ShopCartItemVO::getSupplierId).collect(Collectors.toSet());
            supplierIds.addAll(ids);
        }

        // 店铺订单中有供应商运费，需要计算供应商商品的运费
        if (supplierIdWithShopTransFeeMap.containsKey(shopCart.getShopId())) {
            Map<Long, ShopTransFeeVO> shopSupplierIdWithShopTransFeeMap = supplierIdWithShopTransFeeMap.get(shopCart.getShopId());
            for (Long supplierId : supplierIds) {
                if (!shopSupplierIdWithShopTransFeeMap.containsKey(supplierId)) {
                    continue;
                }
                ShopTransFeeVO supplierTransFeeVO = shopSupplierIdWithShopTransFeeMap.get(supplierId);
                shopCartOrder.setActualTotal(shopCartOrder.getActualTotal() + supplierTransFeeVO.getTransfee());
                // 运费
                shopCartOrder.setTransfee(shopCartOrder.getTransfee() + supplierTransFeeVO.getTransfee());
                shopCartOrder.setFreeTransfee(shopCartOrder.getFreeTransfee() + supplierTransFeeVO.getFreeTransfee());
                totalTransfee += supplierTransFeeVO.getTransfee();
            }
        }

        // 计算店铺运费
        if (CollectionUtil.isNotEmpty(shopIdWithShopTransFee) && shopIdWithShopTransFee.containsKey(shopCartOrder.getShopId())) {
            ShopTransFeeVO shopTransFeeVO = shopIdWithShopTransFee.get(shopCartOrder.getShopId());

            // 店铺的实付 = 购物车实付 + 运费
            shopCartOrder.setActualTotal(shopCartOrder.getActualTotal() + shopTransFeeVO.getTransfee());
            // 运费
            shopCartOrder.setTransfee(shopCartOrder.getTransfee() + shopTransFeeVO.getTransfee());
            shopCartOrder.setFreeTransfee(shopCartOrder.getFreeTransfee() + shopTransFeeVO.getFreeTransfee());
            totalTransfee += shopTransFeeVO.getTransfee();
        }
        return totalTransfee;
    }

    private static ShopCartOrderVO getShopCartOrderVO(ShopCartOrderMergerVO shopCartOrderMerger, Map<Long, Integer> shopCityStatusMap, Map<Long, Long> shopStartDeliveryFees, ShopCartVO shopCart) {
        ShopCartOrderVO shopCartOrder = new ShopCartOrderVO();
        shopCartOrder.setShopCityStatus(shopCityStatusMap.getOrDefault(shopCart.getShopId(), null));
        shopCartOrder.setOrderType(shopCartOrderMerger.getOrderType().value());
        shopCartOrder.setShopId(shopCart.getShopId());
        shopCartOrder.setShopName(shopCart.getShopName());
        shopCartOrder.setShopType(shopCart.getShopType());
        shopCartOrder.setShopReduce(shopCart.getShopReduce());
        shopCartOrder.setStartDeliveryFee(shopStartDeliveryFees.containsKey(shopCart.getShopId()) ? shopStartDeliveryFees.get(shopCart.getShopId()).doubleValue() : 0L);
        shopCartOrder.setTransfee(0L);
        shopCartOrder.setFreeTransfee(0L);
        shopCartOrder.setActualTotal(shopCart.getActualTotal());
        return shopCartOrder;
    }

    /**
     * 结束平台优惠的计算之后，还要重算一遍金额
     */
    public void recalculateAmountWhenFinishingCalculatePlatform(ShopCartOrderMergerVO shopCartOrderMerger, UserDeliveryInfoVO userDeliveryInfo) {
        Map<Long, ShopTransFeeVO> shopIdWithShopTransFee = userDeliveryInfo.getShopIdWithShopTransFee();
        //所有订单实际金额
        long actualTotal = 0L;
        //所有订单优惠金额
        long allOrderReduce = 0L;
        // 总运费金额
        long totalTransfee = 0L;
        // 运费减免金额
        long freeTransfee = 0L;
        List<ShopCartOrderVO> shopCartOrders = shopCartOrderMerger.getShopCartOrders();
        List<VirtualRemarkVO> virtualRemarkList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (ShopCartOrderVO shopCartOrder : shopCartOrders) {
            //订单实际金额
            long orderActualTotal = 0L;
            //商家优惠金额
            long orderReduceAmount = 0L;
            //商家优惠金额
            long orderPlatformAmount = 0L;
            List<ShopCartItemVO> shopCartShopCartItem = getShopShopCartItem(shopCartOrder.getShopCartItemDiscounts());
            for (ShopCartItemVO shopCartItem : shopCartShopCartItem) {
                this.handleShopCartItem(shopCartItem, virtualRemarkList);
                orderActualTotal += shopCartItem.getActualTotal();
                orderReduceAmount += shopCartItem.getShareReduce();
                orderPlatformAmount += shopCartItem.getPlatformShareReduce();
            }
            // 如果是定金预售，优惠处理下定金和尾款
            if (Objects.equals(shopCartOrderMerger.getPreSaleType(), PreSaleType.DEPOSIT.value())) {
                this.handlePreSale(shopCartOrder, shopCartShopCartItem, shopCartOrderMerger);
            }
            // 如果是折扣特别小的情况下，导致实际金额为0是，改变最小支付金额为0.01元,并且优惠金额减去0.01（积分抵扣除外，积分能够完全抵扣）
            // 此时的实际支付金额已经包含运费了
            boolean isMinPrice = shopCartOrder.getActualTotal() < 1
                    && (shopCartOrder.getScoreReduce() == null || shopCartOrder.getScoreReduce() < 1L);
            if(isMinPrice) {
                // 重算订单项
                resetActualTotal(shopCartShopCartItem);
                shopCartOrder.setActualTotal(1L);
                shopCartOrder.setShopReduce(shopCartOrder.getTotal() - 1L);
            }
            if (shopCartOrder.getLevelFreeTransfee() != null && shopCartOrder.getLevelFreeTransfee() != 0L) {
                // 店铺先说包邮，然后平台再说会员包邮，所以实际上平台的包邮剩下来的邮费 = shopCartOrder.getLevelFreeTransfee() - shopCartOrder.getTransfee()
                Long transfee = shopCartOrder.getLevelFreeTransfee() - shopCartOrder.getTransfee();
                //放入平台优惠金额,如果用户等级免自营店运费也要放进去
                shopCartOrder.setPlatformAmount(shopCartOrder.getPlatformAmount() + transfee);
                shopCartOrder.setActualTotal(orderActualTotal - transfee);
                // 平台会员减免运费金额
                freeTransfee += shopCartOrder.getLevelFreeTransfee();
            }
            actualTotal += shopCartOrder.getActualTotal();
            allOrderReduce += shopCartOrder.getShopReduce();
            totalTransfee += shopCartOrder.getTransfee();
//            // 店铺减免运费金额
//            freeTransfee += (Objects.isNull(shopCartOrder.getLevelFreeTransfee()) ? 0 : shopCartOrder.getFreeTransfee());
        }
        shopCartOrderMerger.setActualTotal(actualTotal);
        shopCartOrderMerger.setVirtualRemarkList(virtualRemarkList);
        shopCartOrderMerger.setTotalTransfee(totalTransfee);
        shopCartOrderMerger.setFreeTransfee(freeTransfee);
        shopCartOrderMerger.setOrderReduce(allOrderReduce);
        shopCartOrderMerger.setUserAddr(userDeliveryInfo.getUserAddr());
        shopCartOrderMerger.setShopCityStatus(userDeliveryInfo.getShopCityStatus());


    }

    private void handleShopCartItem(ShopCartItemVO shopCartItem, List<VirtualRemarkVO> virtualRemarkList) {
        shopCartItem.setShareReduce(shopCartItem.getShareReduce() + shopCartItem.getPlatformShareReduce());
        shopCartItem.setActualTotal(shopCartItem.getTotalAmount() - shopCartItem.getShareReduce());
        // 确保字符串为数组格式类型后，再进行JSON转换，否则会报错
        String virtualRemarkStr = shopCartItem.getVirtualRemark();
        boolean isHandleVirtualRemark = StrUtil.isNotBlank(virtualRemarkStr)
                && virtualRemarkStr.startsWith("[")
                && virtualRemarkStr.endsWith("]");
        if (isHandleVirtualRemark) {
            List<VirtualRemarkVO> virtualRemarks = JSON.parseArray(shopCartItem.getVirtualRemark(), VirtualRemarkVO.class);
            virtualRemarks.forEach(virtualRemark -> virtualRemark.setSpuId(shopCartItem.getSpuId()));
            shopCartItem.setVirtualRemarkList(virtualRemarks);
            virtualRemarkList.addAll(shopCartItem.getVirtualRemarkList());
        }
    }

    private void handlePreSale(ShopCartOrderVO shopCartOrder, List<ShopCartItemVO> shopCartShopCartItem, ShopCartOrderMergerVO shopCartOrderMerger) {
        // 定金预售只能买一个商品，直接处理这个商品
        ShopCartItemVO shopCartItemVO = shopCartShopCartItem.get(0);
        // 实际定金
        if (shopCartItemVO.getShareReduce() > shopCartItemVO.getBalanceAmount()) {
            long actualDepositAmount = shopCartItemVO.getShareReduce() - shopCartItemVO.getBalanceAmount();
            shopCartItemVO.setActualDepositAmount(Math.max(shopCartItemVO.getActualDepositAmount() - actualDepositAmount, 1L));
        }
        // 实际尾款 = max(尾款 - 优惠，0）
        shopCartItemVO.setActualBalanceAmount(Math.max(shopCartItemVO.getBalanceAmount() - shopCartItemVO.getShareReduce(), 0L));
        shopCartOrder.setShopReduce(shopCartOrder.getShopReduce() + shopCartItemVO.getDepositReduceAmount());
        shopCartOrderMerger.setTotalDepositReduceAmount(shopCartItemVO.getDepositReduceAmount());
        shopCartOrderMerger.setBalanceAmount(shopCartItemVO.getBalanceAmount());
        shopCartOrderMerger.setActualBalanceAmount(shopCartItemVO.getActualBalanceAmount());
        shopCartOrderMerger.setTotalDepositAmount(shopCartItemVO.getActualDepositAmount());
    }

    /**
     * 重新计算金额，避免订单无法支付
     */
    private void resetActualTotal(List<ShopCartItemVO> shopCartShopCartItem) {
        Iterator<ShopCartItemVO> iterator = shopCartShopCartItem.iterator();
        while (iterator.hasNext()) {
            ShopCartItemVO shopCartItem = iterator.next();
            shopCartItem.setShareReduce(shopCartItem.getShareReduce() + shopCartItem.getPlatformShareReduce());
            shopCartItem.setActualTotal(shopCartItem.getTotalAmount() - shopCartItem.getShareReduce());
            if (iterator.hasNext()) {
                shopCartItem.setActualTotal(0L);
                shopCartItem.setShareReduce(shopCartItem.getTotalAmount());
            } else {
                shopCartItem.setActualTotal(1L);
                shopCartItem.setShareReduce(shopCartItem.getTotalAmount() - 1L);
            }
        }
    }

    /**
     * 获取店铺下的所有订单
     */
    private List<ShopCartItemVO> getShopShopCartItem(List<ShopCartItemDiscountVO> shopCartItemDiscounts) {
        List<ShopCartItemVO> shopCartShopCartItem = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (ShopCartItemDiscountVO shopCartItemDiscount : shopCartItemDiscounts) {
            shopCartShopCartItem.addAll(shopCartItemDiscount.getShopCartItems());
        }
        shopCartShopCartItem.sort(Comparator.comparingDouble(ShopCartItemVO::getTotalAmount));
        return shopCartShopCartItem;
    }


    /**
     * 确认订单计算平台佣金
     * @param shopCartOrderMerger
     */
    public void confirmPlatformCommission(ShopCartOrderMergerVO shopCartOrderMerger) {
        for (ShopCartOrderVO shopCartOrder : shopCartOrderMerger.getShopCartOrders()) {
            Long totalPlatformCommission = 0L;
            for (ShopCartItemDiscountVO shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemVO shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    if (Objects.equals(shopCartOrderMerger.getOrderType().value(), OrderType.SCORE.value())) {
                        // 分摊比例
                        shopCartItem.setRate(0.0);
                        // 平台佣金
                        shopCartItem.setPlatformCommission(0L);
                        shopCartItem.setSupplierRate(0.0);
                        shopCartItem.setPurchasePlatformCommission(0L);
                        continue;
                    }
                    // 平台佣金,如果是商家代销，供应商采购价的佣金也需要计算
                    // 平台对商家的差价抽佣 = （商家定的销售价格 - 供应商价格）-（商家定的销售价格 - 供应商价格）* 平台抽佣百分比
                    // 平台对商家的差价抽佣 = （用户实付金额 + 平台优惠金额 - 供应商金额） * 比例
                    long shopAmount = shopCartItem.getActualTotal() + shopCartItem.getPlatformShareReduce() - shopCartItem.getTotalPurchaseAmount();
                    shopAmount = Math.max(shopAmount, 0L);
                    // 平台佣金
                    shopCartItem.setPlatformCommission(PriceUtil.divideByBankerRounding((long) ((shopAmount) * shopCartItem.getRate()), 100));
                    // 供应商没有平台优惠，此时不用加上平台优惠进行计算
                    // 平台对供应商的抽佣 = 供应商采购价 * 平台抽佣百分比
                    shopCartItem.setPurchasePlatformCommission(PriceUtil.divideByBankerRounding((long) (shopCartItem.getTotalPurchaseAmount() * shopCartItem.getSupplierRate()), 100));
                    totalPlatformCommission += shopCartItem.getPlatformCommission();
                }
            }
            shopCartOrder.setPlatformCommission(totalPlatformCommission);
        }
    }


    public void cacheCalculatedInfo(Long userId, ShopCartOrderMergerVO shopCartOrderMerger) {
        // 防止重复提交
        RedisUtil.STRING_REDIS_TEMPLATE.opsForValue().set(OrderCacheNames.ORDER_CONFIRM_UUID_KEY + CacheNames.UNION + userId, String.valueOf(userId));
        // 保存订单计算结果缓存，省得重新计算 并且 用户确认的订单金额与提交的一致
        cacheManagerUtil.putCache(OrderCacheNames.ORDER_CONFIRM_KEY, String.valueOf(userId), shopCartOrderMerger);
    }



    public UserDeliveryInfoVO getUserDeliveryInfoVO(List<ShopCartItemVO> shopCartItemsDb, Long userId, OrderDTO orderParam) {
        UserDeliveryInfoVO userDeliveryInfoVO = new UserDeliveryInfoVO();
        userDeliveryInfoVO.setAddrId(orderParam.getAddrId());
        userDeliveryInfoVO.setDvyTypes(orderParam.getDvyTypes());
        userDeliveryInfoVO.setDeliveryTemplateIds(new ArrayList<>());

        DvyTypeDTO dvyTypeDTO = orderParam.getDvyTypes().get(0);

        // 没有订单项或者是自提订单，处理完直接返回即可，不需要获取用户地址
        if (CollectionUtil.isEmpty(shopCartItemsDb) || Objects.equals(dvyTypeDTO.getDvyType(), DeliveryType.STATION.value())) {
            // 自提订单，将自提相关的参数插入地址信息中
            if (Objects.equals(dvyTypeDTO.getDvyType(), DeliveryType.STATION.value())) {
                userDeliveryInfoVO.setStationId(orderParam.getDvyTypes().get(0).getStationId());
                OrderSelfStationVO orderSelfStationVO = new OrderSelfStationVO();
                orderSelfStationVO.setLat(dvyTypeDTO.getLat());
                orderSelfStationVO.setLng(dvyTypeDTO.getLng());
                orderSelfStationVO.setStationId(userDeliveryInfoVO.getStationId());
                orderSelfStationVO.setStationStockStatus(StationStockStatus.HAS_STOCK.getStatus());
                userDeliveryInfoVO.setOrderSelfStation(orderSelfStationVO);
            }
        }
        boolean activityProd = Objects.equals(shopCartItemsDb.get(0).getSpuType(), SpuType.GROUP.value()) ||
                Objects.equals(shopCartItemsDb.get(0).getSpuType(), SpuType.SECKILL.value()) ||
                Objects.equals(shopCartItemsDb.get(0).getSpuType(), SpuType.SCORE.value());

        boolean getUserAddr = true;
        Map<Long, Integer> dvyTypeMap = orderParam.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        Long addrId = orderParam.getAddrId();
        for (ShopCartItemVO shopCartItemVO : shopCartItemsDb) {

            List<Long> deliveryTemplateIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
            Integer devType = dvyTypeMap.get(shopCartItemVO.getShopId());
            // 满足条件的不需要判断物流配送范围 1.活动商品 2.虚拟商品 3.无需物流 4.用户自提
            if(Objects.equals(shopCartItemVO.getMold(),SpuMold.COMBO.value())){
                // 可配送，添加模板id
                if (!delivery(shopCartItemVO, devType)) {
                    deliveryTemplateIds.add(shopCartItemVO.getDeliveryTemplateId());
                };
            }
            if (getUserAddr) {
                // 获取用户地址信息
                ServerResponseEntity<UserAddrVO> userAddrResponse;
                if (addrId != 0) {
                    userAddrResponse = userAddrFeignClient.getUserAddrByAddrId(addrId);
                } else {
                    userAddrResponse = userAddrFeignClient.getUserAddrByUserId(userId);
                }
                if (!userAddrResponse.isSuccess()) {
                    LOGGER.error("用户选择物流配送，获取用户地址信息失败，userAddrResponse:{}", userAddrResponse);
                    throw new LuckException("用户选择物流配送，获取用户地址信息失败");
                }
                if (Objects.isNull(userDeliveryInfoVO.getUserAddr())) {
                    UserAddrVO userAddr = userAddrResponse.getData();
                    if (userAddr == null) {
                        LOGGER.info("用户选择物流配送，获取用户地址信息为空");
                        userDeliveryInfoVO.setTotalTransfee(0L);
                        userDeliveryInfoVO.setShopCityStatus(-1);
                    }
                    LOGGER.info("用户选择物流配送，查询的地址信息 -- userAddrResponse:{}", userAddrResponse);
                    userDeliveryInfoVO.setUserAddr(userAddr);
                    // 查过一次，下次遍历不用再查了
                    getUserAddr = false;
                }
            }

            // 没有地址，或者是活动商品，不需要获取模板id
            if (Objects.isNull(orderParam.getAddrId()) || activityProd) {
                return userDeliveryInfoVO;
            }

            if (!delivery(shopCartItemVO, devType) && Objects.equals(shopCartItemVO.getMold(), SpuMold.REAL.value())) {
                deliveryTemplateIds.add(shopCartItemVO.getDeliveryTemplateId());
            };

            if (Objects.nonNull(userDeliveryInfoVO.getUserAddr())) {
                // 快递配送且用户地址也完整，添加商品运费模板到列表中
                userDeliveryInfoVO.getDeliveryTemplateIds().addAll(deliveryTemplateIds);
            }
        }
        return userDeliveryInfoVO;
    }

    private static boolean delivery(ShopCartItemVO shopCartItemVO, Integer devType) {
        // 需要配送的条件： 1.实物商品 2.快递或者同城
        // 不是快递或者同城
        if (!Objects.equals(devType, DeliveryType.DELIVERY.value()) || !Objects.equals(devType, DeliveryType.SAME_CITY.value())) {
            return true;
        }
        // 不是实物商品
        if (!Objects.equals(shopCartItemVO.getMold(), SpuMold.REAL.value())) {
            return true;
        }
        return false;
    }

    public UserDeliveryInfoVO checkAddr(List<ShopCartItemVO> shopCartItemsDb, Long userId, UserDeliveryInfoVO userDeliveryInfoVO) {
        Map<Long, TransportVO> transportMap;
        if (MapUtil.isNotEmpty(userDeliveryInfoVO.getTransportMap())) {
            transportMap = userDeliveryInfoVO.getTransportMap();
        } else {
            transportMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        }

        Map<Long, Integer> dvyTypeMap = userDeliveryInfoVO.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        for (ShopCartItemVO shopCartItemVO : shopCartItemsDb) {
            Integer devType = dvyTypeMap.get(shopCartItemVO.getShopId());
            // 满足条件的不需要判断物流配送范围 1.活动商品 2.虚拟商品 3.无需物流 4.用户自提
            boolean delivery = notDelivery(shopCartItemVO, devType);
            //判断用户的默认地址是否在配送范围内
            if (delivery) {
                LOGGER.info("活动商品或虚拟商品不校验地址");
                shopCartItemVO.setIsDelivery(true);
                continue;
            }

            Long addrId = userDeliveryInfoVO.getAddrId();
            if (shopCartItemVO.getDeliveryTemplateId() == null || Objects.isNull(userDeliveryInfoVO) || addrId == null) {
                LOGGER.info("模板id或地址id为空，不校验");
                // 模板、地址id为空，不可以配送
                shopCartItemVO.setIsDelivery(false);
                continue;
            }

            UserAddrVO userAddr = userDeliveryInfoVO.getUserAddr();
            if (Objects.isNull(userAddr)) {
                // 用户没有设置地址，先跳过处理
                shopCartItemVO.setIsDelivery(true);
                continue;
            }
            // 固定运费或者包邮的商品不需要判断可配送区域
            if (shopCartItemVO.getDeliveryTemplateId() == 0 || shopCartItemVO.getDeliveryTemplateId() == -1) {
                shopCartItemVO.setIsDelivery(true);
                continue;
            }

            // 判断用户地址是否在物流模板中的可配送区域
            TransportVO transportVO = transportMap.get(shopCartItemVO.getDeliveryTemplateId());

            if (transportVO == null) {
                // 这里分出来是因为秒杀、团购、积分订单获取物流是通过dubbo，普通订单不需要通过dubbo
                // 秒杀、团购、积分商品才会进入这里，普通商品在执行getUserDeliveryInfoVO()后就获取物流集合
                transportVO = deliveryFeignClient.getTransportAndAllItemsById(shopCartItemVO.getDeliveryTemplateId());
                transportMap.put(shopCartItemVO.getDeliveryTemplateId(), transportVO);
            }

            List<TransfeeVO> transFees = transportVO.getTransFees();
            boolean isDelivery = false;
            // 包邮代表可以配送 - 兼容旧运费模板
            if (Objects.equals(transportVO.getIsFreeFee(), 1)) {
                isDelivery = true;
            } else if (CollUtil.isNotEmpty(transFees)) {
                for (TransfeeVO transFee : transFees) {
                    for (AreaVO areaVO : transFee.getCityList()) {
                        if (Objects.equals(areaVO.getAreaId(), userAddr.getAreaId())) {
                            isDelivery = true;
                            break;
                        }
                    }
                }
            }
            shopCartItemVO.setIsDelivery(isDelivery);
        }
        return userDeliveryInfoVO;
    }



    /**
     * 插入快递配送的库存区域id
     * @param userDeliveryInfoVO
     * @param shopCarts
     */
    public void handleShopCartStockPoint(UserDeliveryInfoVO userDeliveryInfoVO, List<ShopCartVO> shopCarts, List<ShopCartItemVO> shopCartItemsDb, Integer spuMold) {
        Map<Long, Integer> dvyTypeMap = userDeliveryInfoVO.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        List<ShopCartItemVO> shopCartItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (ShopCartVO shopCart : shopCarts) {
            for (ShopCartItemDiscountVO shopCartItemDiscount : shopCart.getShopCartItemDiscounts()) {
                for (ShopCartItemVO shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    shopCartItems.add(shopCartItem);
                    if (CollUtil.isNotEmpty(shopCartItem.getComboShopCartItems())) {
                        shopCartItems.addAll(shopCartItem.getComboShopCartItems());
                    }
                }
            }
        }
        for (ShopCartItemVO shopCartItemVO : shopCartItemsDb) {
            if (CollUtil.isEmpty(shopCartItemVO.getGiveawayShopCartItemList()) || !Objects.equals(shopCartItemVO.getMold(), SpuMold.COMBO.value())) {
                continue;
            }
            shopCartItems.addAll(shopCartItemVO.getGiveawayShopCartItemList());
        }
        Long areaId = null;
        if (Objects.nonNull(userDeliveryInfoVO.getUserAddr())) {
            areaId = userDeliveryInfoVO.getUserAddr().getAreaId();
        }
        // 非虚拟商品，且用户未选择订单地址，等用户选择地址后再获取快递配送的仓库
        if (Objects.isNull(areaId) && !Objects.equals(spuMold, SpuMold.VIRTUAL.value())) {
            return;
        }

        Map<String, SkuStockVO> giveawayStockMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        for (ShopCartItemVO shopCartItem : shopCartItems) {
            if(Objects.equals(shopCartItem.getMold(),SpuMold.COMBO.value())) {
                continue;
            }
            Long defaultPointId = shopCartItem.getStockPointList().get(0).getStockPointId();
            List<WarehouseVO> warehouseList = shopCartItem.getWarehouseList();
            shopCartItem.setStockPointType(StockPointType.WAREHOUSE.getValue());
            // 设置默认仓库
            // 供应商发货的代销商品先不用处理
            Integer dvyType = dvyTypeMap.get(shopCartItem.getShopId());
            // 商品满足以下任意一项则使用默认仓库的库存：仅有默认仓库的sku、虚拟商品、同城配送、积分商品
            boolean defaultPoint = shopCartItem.getStockPointList().size() == 1 ||
                    Objects.equals(shopCartItem.getMold(), SpuMold.VIRTUAL.value()) ||
                    Objects.equals(shopCartItem.getSpuType(), SpuType.SCORE.value()) ||
                    Objects.equals(dvyType, DeliveryType.SAME_CITY.value());
            if (defaultPoint) {
                // 使用默认仓库id
                shopCartItem.setStockPointId(defaultPointId);
                continue;
            }

            if (Objects.equals(dvyType, DeliveryType.STATION.value())) {
                // 用户自提 - 判断是共享总部库存还是门店是独立销售库存
                // 默认是共享总部库存，也就是默认仓库id
                Long stationId = defaultPointId;
                for (StockPointSkuVO stockPointSkuVO : shopCartItem.getStockPointList()) {
                    // 门店是独立销售库存，则使用门店id
                    boolean useStationStock = Objects.equals(stockPointSkuVO.getStockPointId(), userDeliveryInfoVO.getStationId()) &&
                            Objects.equals(stockPointSkuVO.getStockPointType(), 2) &&
                            Objects.equals(stockPointSkuVO.getStockMode(), 2);
                    if (useStationStock) {
                        stationId = stockPointSkuVO.getStockPointId();
                        // 仓库类型更改为门店
                        shopCartItem.setStockPointType(StockPointType.STATION.getValue());
                        break;
                    }
                }
                shopCartItem.setStockPointId(stationId);
                continue;
            }

            // 未设置库存区域id的订单项
            setStockPointId(warehouseList, shopCartItem, areaId);

        }
        for (ShopCartItemVO shopCartItem : shopCartItems) {
            // 加载完仓库id后，再校验是否为赠品
            if (CollUtil.isEmpty(shopCartItem.getGiveawayShopCartItemList())) {
                continue;
            }
            for (ShopCartItemVO giveawayShopCartItem : shopCartItem.getGiveawayShopCartItemList()) {
                // 赠品必须跟主商品一个仓库
                giveawayShopCartItem.setStockPointId(shopCartItem.getStockPointId());
                // 赠品需要判断库存，所以先收集赠品的库存信息
                String stockKey = giveawayShopCartItem.getSkuId() + Constant.UNDERLINE + giveawayShopCartItem.getStockPointId();
                if (giveawayStockMap.containsKey(stockKey)) {
                    continue;
                }
                SkuStockVO skuStockVO = new SkuStockVO(giveawayShopCartItem.getSkuId());
                skuStockVO.setStockPointId(giveawayShopCartItem.getStockPointId());
                giveawayStockMap.put(stockKey, skuStockVO);
            }
        }
        shopCartItems.forEach(shopCartItemVO -> shopCartItemVO.setWarehouseList(null));
        // 校验赠品库存，并去除库存不足的赠品
        this.checkGiveawayStock(shopCartItems, shopCarts, shopCartItemsDb, giveawayStockMap);
    }
    private static void setStockPointId(List<WarehouseVO> warehouseList, ShopCartItemVO shopCartItem, Long areaId) {
        List<StockPointSkuVO> stockPointList = shopCartItem.getStockPointList();
        Map<Long, WarehouseVO> warehouseMap = warehouseList.stream().collect(Collectors.toMap(WarehouseVO::getWarehouseId, Function.identity()));
        for (StockPointSkuVO stockPointSkuVO : stockPointList) {
            WarehouseVO warehouseVO = warehouseMap.get(stockPointSkuVO.getStockPointId());
            // 默认仓库不处理
            if (Objects.isNull(warehouseVO) || Objects.equals(warehouseVO.getType(), 0)) {
                continue;
            }
            // 用户订单地址包含在仓库配送区域内，则使用区域库存id
            if (warehouseVO.getAreaIds().contains(areaId)) {
                shopCartItem.setStockPointId(warehouseVO.getWarehouseId());
                return;
            }

        }
        // 地址不满足区域仓库的配送范围，则使用默认的仓库
        if (Objects.isNull(shopCartItem.getStockPointId())) {
            shopCartItem.setStockPointId(stockPointList.get(0).getStockPointId());
        }
    }

    private void checkGiveawayStock(List<ShopCartItemVO> shopCartItems, List<ShopCartVO> shopCarts, List<ShopCartItemVO> shopCartItemsDb, Map<String, SkuStockVO> giveawayStockMap) {
        // 没有赠品，不需要检验赠品库存
        if (giveawayStockMap.isEmpty()) {
            return;
        }
        // 查询赠品的库存
        Map<String, SkuStockVO> skuStockMap = skuStockFeignClient.listSkuStock(new ArrayList<>(giveawayStockMap.values()));
        // 先扣除主商品的库存
        for (ShopCartItemVO shopCartItemVO : shopCartItems) {
            // 这里是主商品的库存扣除，赠品先跳过不处理
            if (Objects.nonNull(shopCartItemVO.getGiveawayRefundPrice())) {
                continue;
            }
            String stockKey = shopCartItemVO.getSkuId() + Constant.UNDERLINE + shopCartItemVO.getStockPointId();
            // 没有跟赠品相同的区域库存，就不用操作
            if (!skuStockMap.containsKey(stockKey)) {
                continue;
            }
            SkuStockVO skuStockVO = skuStockMap.get(stockKey);
            // sku库存先扣除主商品的购买数量
            skuStockVO.setStock(skuStockVO.getStock() - shopCartItemVO.getCount());
            // 小于等于0，都去除改sku的库存，库存为0就说明没有足够的数量给赠品
            if (skuStockVO.getStock() <= 0) {
                skuStockMap.remove(stockKey);
            }
        }
        // 扣完主商品的库存后，按顺序开始扣除赠品的库存

        // 先扣除组合商品的赠品库存
        for (ShopCartItemVO shopCartItemVO : shopCartItemsDb) {
            handleGiveaway(skuStockMap, shopCartItemVO);
        }
        // 再扣除普通商品
        for (ShopCartVO shopCart : shopCarts) {
            for (ShopCartItemDiscountVO shopCartItemDiscount : shopCart.getShopCartItemDiscounts()) {
                for (ShopCartItemVO shopCartItemVO : shopCartItemDiscount.getShopCartItems()) {
                    handleGiveaway(skuStockMap, shopCartItemVO);
                }
            }
        }
    }

    private static void handleGiveaway(Map<String, SkuStockVO> skuStockMap, ShopCartItemVO shopCartItemVO) {
        // 没有赠品的购物车项，跳过处理
        if (CollUtil.isEmpty(shopCartItemVO.getGiveawayShopCartItemList())) {
            return;
        }
        // 删除没有足够库存的赠品项
        shopCartItemVO.getGiveawayShopCartItemList().removeIf(giveawayShopCartItem -> {
            String stockKey = giveawayShopCartItem.getSkuId() + Constant.UNDERLINE + giveawayShopCartItem.getStockPointId();
            // 没有跟赠品的区域库存，代表库存数量不足, 删除该赠品
            if (!skuStockMap.containsKey(stockKey)) {
                return true;
            }
            SkuStockVO skuStockVO = skuStockMap.get(stockKey);
            // 扣除赠品库存
            skuStockVO.setStock(skuStockVO.getStock() - shopCartItemVO.getCount());
            // sku库存数量不足，删除该赠品
            if (skuStockVO.getStock() <= 0) {
                return true;
            }
            return false;
        });
    }


    private static boolean notDelivery(ShopCartItemVO shopCartItemVO, Integer devType) {
        return Objects.equals(shopCartItemVO.getSpuType(), SpuType.ACTIVE.value()) ||
                Objects.equals(shopCartItemVO.getMold(), SpuMold.VIRTUAL.value()) ||
                Objects.equals(devType, DeliveryType.NOT_DELIVERY.value()) ||
                Objects.equals(devType, DeliveryType.STATION.value());
    }

    public void handleStationOrder(ShopCartOrderMergerVO shopCartOrderMerger, List<ShopCartItemVO> shopCartItems, UserDeliveryInfoVO userDeliveryInfoVO) {
        Map<Long, OrderStationSpuDTO> orderStationSpuMap = getStationOrderStockMap(shopCartItems, userDeliveryInfoVO);
        if (MapUtil.isEmpty(orderStationSpuMap)) {
            if (Objects.nonNull(userDeliveryInfoVO.getOrderSelfStation())) {
                shopCartOrderMerger.setOrderSelfStation(userDeliveryInfoVO.getOrderSelfStation());
            }
            return;
        }
        OrderSelfStationVO orderSelfStationVO = stationFeignClient.getOrderStation(userDeliveryInfoVO, new ArrayList<>(orderStationSpuMap.values()));
        userDeliveryInfoVO.setStationId(orderSelfStationVO.getStationId());
        userDeliveryInfoVO.setOrderSelfStation(orderSelfStationVO);
        shopCartOrderMerger.setOrderSelfStation(orderSelfStationVO);
        if (Objects.nonNull(userDeliveryInfoVO.getStationId())) {
            shopCartOrderMerger.setStationId(userDeliveryInfoVO.getStationId());
        }
    }

    public Map<Long, OrderStationSpuDTO> getStationOrderStockMap(List<ShopCartItemVO> shopCartItems, UserDeliveryInfoVO userDeliveryInfoVO) {
        Integer dvyType = userDeliveryInfoVO.getDvyTypes().get(0).getDvyType();
        if (Objects.nonNull(userDeliveryInfoVO.getStationId()) || !Objects.equals(dvyType, DeliveryType.STATION.value())) {
            return new HashMap<>(0);
        }

        List<ShopCartItemVO> shopCartItemList = new ArrayList<>(shopCartItems.size());
        shopCartItems.forEach(shopCartItemVO -> {
            if (CollUtil.isNotEmpty(shopCartItemVO.getComboShopCartItems())) {
                shopCartItemList.addAll(shopCartItemVO.getComboShopCartItems());
            } else {
                shopCartItemList.add(shopCartItemVO);
            }
        });
        Map<Long, OrderStationSpuDTO> orderStationSpuMap = new HashMap<>(shopCartItemList.size());
        for (ShopCartItemVO shopCartItemVO : shopCartItemList) {
            if (!orderStationSpuMap.containsKey(shopCartItemVO.getSkuId())) {
                OrderStationSpuDTO orderStationSpuDTO = new OrderStationSpuDTO();
                orderStationSpuDTO.setSkuId(shopCartItemVO.getSkuId());
                orderStationSpuDTO.setCount(shopCartItemVO.getCount());
                orderStationSpuDTO.setSpuMold(shopCartItemVO.getMold());
                orderStationSpuMap.put(shopCartItemVO.getSkuId(), orderStationSpuDTO);
                continue;
            }
            OrderStationSpuDTO orderStationSpuDTO = orderStationSpuMap.get(shopCartItemVO.getSkuId());
            orderStationSpuDTO.setCount(orderStationSpuDTO.getCount() + shopCartItemVO.getCount());
        }
        return orderStationSpuMap;
    }
}
