package cn.freemud.demo.service.impl;

import cn.freemud.adapter.ActivityAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.CustomerScoreConstant;
import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.demo.entities.bo.SendGoods;
import cn.freemud.demo.entities.bo.promotion.GetActivityBO;
import cn.freemud.demo.constant.ResponseConstant;
import cn.freemud.demo.entities.bo.goods.ShoppingCartGoodsBO;
import cn.freemud.demo.entities.bo.goods.*;
import cn.freemud.demo.entities.bo.goods.list.ListCartGoodsBO;
import cn.freemud.demo.entities.bo.member.*;
import cn.freemud.demo.entities.bo.promotion.ActivityBO;
import cn.freemud.demo.manager.coupon.CouponManager;
import cn.freemud.demo.manager.customer.CustomerManager;
import cn.freemud.demo.manager.product.ProductManager;
import cn.freemud.demo.manager.promotion.PromotionManager;
import cn.freemud.demo.service.DistributeService;
import cn.freemud.demo.service.ListCartGoodsService;
import cn.freemud.demo.service.MessageService;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.calculate.ActivityCalculationDiscountRequestDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.CouponService;
import cn.freemud.service.impl.AssortmentSdkService;
import cn.freemud.utils.LogUtil;
import cn.freemud.utils.ResponseUtil;
import cn.freemud.utils.WebUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.freemud.constant.ApplicationConstant.*;
import static cn.freemud.constant.ShoppingCartConstant.SHOPPING_CART_EMPTY_GOODS_LIST;
import static cn.freemud.constant.ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS;

@Service
public class AbstractListCartGoodsService implements ListCartGoodsService {

    @Autowired
    private CustomerManager customerManager;

    @Autowired
    private ProductManager productManager;


    @Autowired
    private CouponManager couponManager;

    @Autowired
    private AssortmentSdkService assortmentSdkService;

    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;

    @Autowired
    private ShoppingBaseServiceImpl shoppingBaseService;

    @Autowired
    private PromotionManager promotionManager;

    @Autowired
    private ActivityAdapter activityAdapter;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private DistributeService distributeService;

    @Autowired
    private MessageService messageService;

    @Autowired
    private CouponService couponService;

    private static final String limitCartKey = "ecology:kgd:wxappconfig:open_platform_partner_wxapp_config:appkey_";


    /**
     * 加车的流程
     *
     * @return
     */
    public final ShoppingCartGoodsBO listCartGoods(ListCartGoodsBO listCartGoodsBO) {
        // 基本参数校验
        this.checkParams(listCartGoodsBO);

        // 获取购物车和加车商品信息
        CheckBussinessRulesBO checkBussinessRulesBO = this.getShoppingCartInfo(listCartGoodsBO);
        // 业务校验,例如商品数量库存之类的信息
        AddGoodsToShoppingCartBO addGoodsToShoppingCartBO = this.checkBusinessRules(listCartGoodsBO, checkBussinessRulesBO);

        // 添加商品到购物车
        DiscountResultBO discountResultBO = this.addGoodsToShoppingCart(listCartGoodsBO, addGoodsToShoppingCartBO);

        // 去促销计算优惠
        CalCostBO calCostBO = this.getDiscountResult(listCartGoodsBO, discountResultBO);

        // 计算促销不计算的费用,例如配送费
        DistributeBO distributeBO = this.calCost(listCartGoodsBO, calCostBO);

        // 拼装购物车价格
        SetMessageBO setMessageBO = this.distribute(listCartGoodsBO, distributeBO);

        // 提示语设置,例如满减信息
        ShoppingCartGoodsBO addGoodsShoppingCartBO = this.setMessage(listCartGoodsBO, setMessageBO);

        return addGoodsShoppingCartBO;
    }

    /**
     * 计算不在促销计算范围里的费用
     * @param addGoodsBO
     * @return
     */
    public final DistributeBO calCost(ListCartGoodsBO addGoodsBO, CalCostBO calCostBO) {
        DistributeBO commonSetMessageBO = this.calCommCost(addGoodsBO, calCostBO);

        DistributeBO customSetMessageBO = this.calCustomCost(addGoodsBO, calCostBO, commonSetMessageBO);

        return customSetMessageBO;
    }

    @Override
    public CalCostBO getDiscountResultBefore(ListCartGoodsBO baseRequestDTO, DiscountResultBO discountResultBO) {
        // 计算配送费
        CalCostBO calCostBO = new CalCostBO();
        return calCostBO;
    }

    public final CalCostBO getDiscountResult(ListCartGoodsBO addGoodsBO, DiscountResultBO discountResultBO) {
        CalCostBO before = this.getDiscountResultBefore(addGoodsBO, discountResultBO);

        CalCostBO commonSetMessageBO = this.getComDiscountResult(addGoodsBO, discountResultBO, before);

        CalCostBO customSetMessageBO = this.getDiscountResultAfter(addGoodsBO, discountResultBO, commonSetMessageBO);

        return customSetMessageBO;
    }

    public final SetMessageBO distribute(ListCartGoodsBO addGoodsBO, DistributeBO distributeBO) {
        SetMessageBO commonSetMessageBO = this.commDistribute(addGoodsBO, distributeBO);

        SetMessageBO customSetMessageBO = this.customDistribute(addGoodsBO, distributeBO, commonSetMessageBO);

        return customSetMessageBO;
    }

    /**
     * 设置提示语
     * @param addGoodsBO
     * @return
     */
    public final ShoppingCartGoodsBO setMessage(ListCartGoodsBO addGoodsBO, SetMessageBO setMessageBO) {
        ShoppingCartGoodsBO commonAddGoodsShoppingCartBO = this.setCommMessage(addGoodsBO, setMessageBO);

        ShoppingCartGoodsBO customAddGoodsShoppingCartBO = this.setCustomMessage(addGoodsBO, setMessageBO, commonAddGoodsShoppingCartBO);

        return customAddGoodsShoppingCartBO;
    }


    /**
     * 请求基本参数校验
     * @return
     */
    public final BaseResponse checkParams(ListCartGoodsBO baseRequestDTO) {
        BaseResponse commonBaseResponse = this.checkCommParams(baseRequestDTO);
        if (!ResponseConstant.RESPONSE_SUCCESS_STR.equals(commonBaseResponse.getCode())){
            return commonBaseResponse;
        }
        BaseResponse customBaseResponse = this.checkCustomParams(baseRequestDTO);
        if (!ResponseConstant.RESPONSE_SUCCESS_STR.equals(customBaseResponse.getCode())){
            return customBaseResponse;
        }
        return ResponseBuilder.success();
    }

    /**
     * 1. 获取加车的商品信息
     * 2. 获取购物车的商品信息
     *
     * @return
     */
    public final CheckBussinessRulesBO getShoppingCartInfo(ListCartGoodsBO baseRequestBO) {
        CheckBussinessRulesBO bo = new CheckBussinessRulesBO();
        // 获取用户信息
        CustomerInfo userInfo = customerManager.getUserInfo(baseRequestBO.getSessionId(), baseRequestBO.getManagerService().getCustomerService());
        bo.setUserId(userInfo.getUserId());
        bo.setIsMember(userInfo.getIsMember());
        baseRequestBO.setUserId(userInfo.getUserId());

        // 获取购物车信息
        // 注意，围餐和点餐redis数据结构不一样
        List<CartGoods> allCartGoodsList = assortmentSdkService.getShoppingCart(baseRequestBO.getPartnerId(), baseRequestBO.getShopId(), userInfo.getUserId(), baseRequestBO.getSessionId(), null, shoppingCartBaseService,null);
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            allCartGoodsList = new ArrayList<>();
        } else {
            // check是否反选取消商品券
            if (StringUtils.isNotBlank(baseRequestBO.getUnChooseCouponCode())){
                // 遍历该商品券选择的商品,并将商品券替换为普通商品
                for (int i = allCartGoodsList.size() - 1; i >= 0; i--){
                    CartGoods cartGoods = allCartGoodsList.get(i);
                    if (GoodsTypeEnum.COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType()) || GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())){
                        CheckSpqInfoRequestDto checkSpqInfoRequestDto = new CheckSpqInfoRequestDto(baseRequestBO.getPartnerId(), baseRequestBO.getShopId(), cartGoods.getSpuId(), baseRequestBO.getMenuType(),null);
                        GetProductsVo productInfo = null;
                        if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                            productInfo = couponService.getSpqProductInfo(checkSpqInfoRequestDto, cartGoods.getSkuId());
                        } else {
                            productInfo = couponService.getSpqProductInfo(checkSpqInfoRequestDto);
                        }
                        if (productInfo == null){
                            allCartGoodsList.remove(i);
                        } else {
                            convert2CartGoods(cartGoods, productInfo);
                        }
                    }
                }
            }

        }
        bo.setCartGoods(allCartGoodsList);

        return bo;
    }


    /**
     * 具体业务逻辑校验, 例如商品数量,库存等校验
     *
     * @return
     */
    public final AddGoodsToShoppingCartBO checkBusinessRules(ListCartGoodsBO baseRequestDTO, CheckBussinessRulesBO checkBussinessRulesBO) {
        AddGoodsToShoppingCartBO commAddGoodsToShoppingCartBO = this.checkCommBusinessRules(baseRequestDTO, checkBussinessRulesBO);
        AddGoodsToShoppingCartBO customAddGoodsToShoppingCartBO = this.checkCustomBusinessRules(baseRequestDTO, checkBussinessRulesBO, commAddGoodsToShoppingCartBO);
        return customAddGoodsToShoppingCartBO;
    }


    /**
     * 添加商品到购物车,并重新设置购物车
     *
     * @return
     */
    public final DiscountResultBO addGoodsToShoppingCart(ListCartGoodsBO baseRequestDTO, AddGoodsToShoppingCartBO addGoodsToShoppingCartBO) {

        DiscountResultBO commCalCostBO = this.commAddGoodsToShoppingCart(baseRequestDTO, addGoodsToShoppingCartBO);

        DiscountResultBO customCalCostBO = this.customAddGoodsToShoppingCart(baseRequestDTO, addGoodsToShoppingCartBO, commCalCostBO);

        return customCalCostBO;
    }


    private BaseResponse checkCommParams(ListCartGoodsBO baseRequestDTO) {

        if (StringUtils.isEmpty(baseRequestDTO.getShopId())){
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }

        return ResponseBuilder.success();
    }

    private AddGoodsToShoppingCartBO checkCommBusinessRules(ListCartGoodsBO baseRequestDTO, CheckBussinessRulesBO checkBussinessRulesBO) {
        AddGoodsToShoppingCartBO bo = new AddGoodsToShoppingCartBO();


        List<CartGoods> cartGoodsList = checkBussinessRulesBO.getCartGoods();

        // 检查校验购物车商品(是否合法,上下架,点餐方式,是否在当前菜单中...),并移除非法商品
        ShoppingCartContext cartContext = convert2ShopingCartContext(baseRequestDTO);
        CheckCartRequest checkCartRequest = shoppingBaseService.checkShoppingCart(cartGoodsList, null, cartContext);

        checkBussinessRulesBO.setChanged(checkCartRequest.getChanged());
        checkBussinessRulesBO.setToastMsg(checkCartRequest.getToastMsg());

        bo.setCartGoods(JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class));
        bo.setChanged(checkCartRequest.getChanged());
        bo.setProduct(checkBussinessRulesBO.getProduct());
        bo.setShoppingCartContext(cartContext);
        bo.setToastMsg(checkCartRequest.getToastMsg());
        bo.setIsMember(checkBussinessRulesBO.getIsMember());

        return bo;
    }

    private DiscountResultBO commAddGoodsToShoppingCart(ListCartGoodsBO baseRequestDTO, AddGoodsToShoppingCartBO addGoodsToShoppingCartBO) {
        DiscountResultBO calCostBO = new DiscountResultBO();
        ShoppingCartContext cartContext = addGoodsToShoppingCartBO.getShoppingCartContext();

        assortmentSdkService.setShoppingCart(cartContext.getPartnerId(), cartContext.getShopId(), cartContext.getUserId(),
                addGoodsToShoppingCartBO.getCartGoods(), baseRequestDTO.getSessionId(), "", shoppingCartBaseService,null);

        calCostBO.setCartGoods(addGoodsToShoppingCartBO.getCartGoods());
        calCostBO.setChanged(addGoodsToShoppingCartBO.getChanged());
        calCostBO.setShoppingCartContext(addGoodsToShoppingCartBO.getShoppingCartContext());
        calCostBO.setToastMsg(addGoodsToShoppingCartBO.getToastMsg());
        calCostBO.setValidCouponMap(addGoodsToShoppingCartBO.getValidCouponMap());
        calCostBO.setSpqIdToCartUuidMap(addGoodsToShoppingCartBO.getSpqIdToCartUuidMap());

        calCostBO.setIsMember(addGoodsToShoppingCartBO.getIsMember());

        return calCostBO;
    }

    public final void updateShoppingCartCache(DiscountResultBO calCostBO) {
        return ;
    }

    private DistributeBO calCommCost(ListCartGoodsBO baseRequestDTO, CalCostBO calCostBO) {
        DistributeBO distributeBO = new  DistributeBO();
        distributeBO.setCalculationDiscountBO(calCostBO.getCalculationDiscountBO());
        distributeBO.setCartGoods(calCostBO.getCartGoods());
        distributeBO.setChanged(calCostBO.getChanged());
        distributeBO.setToastMsg(calCostBO.getToastMsg());
        distributeBO.setDeliveryAmount(calCostBO.getDeliveryAmount());
        return distributeBO;
    }

    private ShoppingCartGoodsBO setCommMessage(ListCartGoodsBO baseRequestDTO, SetMessageBO setMessageBO) {

        ShoppingCartGoodsBO shoppingCartGoodsBO = setMessageBO.getShoppingCartGoodsBO();
        shoppingCartGoodsBO.setChanged(false);
        CalculationDiscountBO.CalculationDiscountResult discountResult = null;
        if (setMessageBO.getCalculationDiscountBO() != null){
            discountResult = setMessageBO.getCalculationDiscountBO().getResult();
        }

        //配送描述
        if (setMessageBO.getDeliveryBO() != null){
            shoppingCartGoodsBO.setDeliveryDiscountDesc(setMessageBO.getDeliveryBO().getDeliveryDiscountDesc());
        }

        // 满减提示
        StringBuilder messageBuilder = new StringBuilder();
        ActivityBO activityBO = setMessageBO.getActivityBO();
        List<ActivityList> activityList = messageService.fullReduceMessage(discountResult, messageBuilder, activityBO);
        /**
         * 调用促销统一活动查询,过滤出参与的满减(目前只有每满减和阶梯满减)
         */
        PromotionMessageDto promotionMessageDto = new PromotionMessageDto();
        if (activityBO != null){
            promotionMessageDto.setActivityId(activityBO.getActivityCode());
            promotionMessageDto.setActivityName(activityBO.getActivityName());
            promotionMessageDto.setActivityType(activityBO.getActivityType());
        }
        promotionMessageDto.setPromotionAmount(0L);
        promotionMessageDto.setPromotionMessage(messageBuilder.toString());
        ActivityTip activityTip = new ActivityTip();
        activityTip.setActivityCode(promotionMessageDto.getActivityId());
        activityTip.setActivityType(promotionMessageDto.getActivityType());
        activityTip.setActivityName(promotionMessageDto.getPromotionMessage());
        activityTip.setActivityList(activityList);
        shoppingCartGoodsBO.setActivityTip(activityTip);
        shoppingCartGoodsBO.setDeliveryFeeZeroReason(0);

        ShoppingCartCustomerScoreVo customerScore = shoppingCartGoodsBO.getCustomerScoreVo();
        // 积分抵扣
        if (customerScore != null && customerScore.getScoreState() != null){
            String msg = "";

            // 积分抵扣状态 1积分可用  2积分不足  3 积分抵扣开关禁用 4、订单金额不满足开启积分抵现要求
            switch (customerScore.getScoreState()) {
                case 1:
                    msg = String.format("共%s积分，可用%s积分抵¥%s", getValue(customerScore.getCurrentScore()), getValue(customerScore.getUseScore()), ((double) customerScore.getReduceAmount()) / 100);
                    break;
                case 2:
                    String[] split = customerScore.getScoreReduceRate().split(":");
                    msg = String.format("共%s积分，每%s积分可抵¥%s", getValue(customerScore.getCurrentScore()), split[0], split[1]);
                    break;
                case 5:
                    msg = "已享受优惠，无法再参与积分抵扣";
                    break;
                case 4:
                    msg = String.format("共%s积分，订单满¥%s可开启积分抵现", getValue(customerScore.getCurrentScore()), ((double) customerScore.getReducePriceLimit()) / 100);
                    break;
                default:
                    break;
            }
            customerScore.setCustomerScorePrompt(msg);
        }

        // 特价提示
        List<Integer> types = new ArrayList<>();
        types.add(ActivityTypeEnum.TYPE_2.getCode());
        types.add(ActivityTypeEnum.TYPE_1.getCode());
        if (discountResult != null){
            List<CalculationDiscountBO.CalculationDiscountResult.Goods> goodsList = discountResult.getGoods()
                    .stream()
                    .filter(d -> CollectionUtils.isNotEmpty(d.getDiscounts()))
                    .collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(goodsList)){
                String toastMsg = "", uid = "";
                CalculationDiscountBO.CalculationDiscountResult.Goods.GoodsDiscount dis = null;
                for (CalculationDiscountBO.CalculationDiscountResult.Goods goods : goodsList) {
                    dis = goods.getDiscounts()
                            .stream()
                            .filter(g -> types.contains(g.getType())).findFirst().orElse(null);
                    if (null == dis) continue;
                    if (goods.getGoodsQuantity() > dis.getActualGoodsNumber()) {
                        //goods.get
                        toastMsg = "该商品限" + dis.getActualGoodsNumber() + "份优惠 超出按照原价计算哦";
                        uid = goods.getCartGoodsUid();
                    }
                }
                shoppingCartGoodsBO.setToastMsg(toastMsg);
                shoppingCartGoodsBO.setUid(uid);
            }

        }

        String toastMsg = shoppingCartGoodsBO.getToastMsg();
        if (StringUtils.isNotEmpty(toastMsg)) {
            toastMsg = ObjectUtils.equals(1, baseRequestDTO.getFlag()) ? SHOPPING_CART_EMPTY_GOODS_LIST : SHOPPING_CART_INVALIAD_GOODS;
            setToastMsgIfNotExist(shoppingCartGoodsBO, toastMsg);
            //结算页，只有商品全部非法（即products为空）时，才提示changed为true toastMsg 不为空
            if (ObjectUtils.equals(1, baseRequestDTO.getFlag())) {
                shoppingCartGoodsBO.setChanged(CollectionUtils.isEmpty(setMessageBO.getCartGoods()));
                shoppingCartGoodsBO.setToastMsg(CollectionUtils.isEmpty(setMessageBO.getCartGoods()) ? toastMsg : "");
            }
        }
        setToastMsgIfNotExist(shoppingCartGoodsBO, setMessageBO.getToastMsg());
        shoppingCartGoodsBO.setVersion(2);

        return shoppingCartGoodsBO;
    }

    private CalCostBO getComDiscountResult(ListCartGoodsBO baseRequestDTO, DiscountResultBO discountResultBO, CalCostBO before) {
        if (before.getGetCalculationDiscountBO() == null){
            before.setCalculationDiscountBO(new CalculationDiscountBO());
            return before;
        }
        if (CollectionUtils.isNotEmpty(before.getGetCalculationDiscountBO().getGoods())){
            CalculationDiscountBO calculationDiscountBO = promotionManager.calculationDiscount(before.getGetCalculationDiscountBO(), baseRequestDTO.getManagerService().getPromotionService());
            calculationDiscountBO.getResult().setValidCouponMap(before.getValidCouponMap());
            calculationDiscountBO.getResult().setSpqIdToCartUuidMap(before.getSpqIdToCartUuidMap());
            before.setCalculationDiscountBO(calculationDiscountBO);
        }

        return before;
    }

    private SetMessageBO commDistribute(ListCartGoodsBO baseRequestDTO, DistributeBO distributeBO) {

        SetMessageBO setMessageBO = new SetMessageBO();

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(baseRequestDTO.getPartnerId(), baseRequestDTO.getShopId(),
                baseRequestDTO.getUserId(), baseRequestDTO.getAppId(), baseRequestDTO.getOrderType());

        ShoppingCartGoodsBO shoppingCartGoodsBO = new ShoppingCartGoodsBO();

        ShoppingGoodsAmountBO shoppingGoodsAmountBO = distributeService.initShoppingCart(distributeBO.getCalculationDiscountBO().getResult(), distributeBO.getCartGoods(), baseRequestDTO.getCouponCode());

        // 满减
        FullReductionBO fullReductionBO = distributeService.fullReduction(baseRequestDTO, distributeBO.getCalculationDiscountBO().getResult(), distributeBO.getCartGoods(), activityQueryDto);
        List<CartGoods> giftGoods = new ArrayList<>();
        AdditionBO additionBO = new AdditionBO(0L ,0l);
        if (distributeBO.getCalculationDiscountBO() != null && CollectionUtils.isNotEmpty(distributeBO.getCartGoods())){
            /**
            * 用促销价格初始化购物车行记录成交价
            */
            // 买赠
            giftGoods  = distributeService.buyGift(distributeBO.getCalculationDiscountBO().getResult(), distributeBO.getCartGoods(), activityQueryDto, baseRequestDTO);


            /**
             * 加价购
             */
            additionBO = this.additionResponse(distributeBO.getCalculationDiscountBO().getResult(), baseRequestDTO);


        }

        /**
         * 积分抵扣
         */
        ScoreReduceBO scoreReduceBO = this.scoreReduce(distributeBO.getCalculationDiscountBO(), baseRequestDTO, shoppingGoodsAmountBO, additionBO);

        /**
         * 配送费
         */
        DeliveryBO delivery = null;
        if (BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(baseRequestDTO.getMenuType())) {
            delivery = this.delivery(distributeBO.getCalculationDiscountBO(), baseRequestDTO,
                    activityQueryDto, distributeBO.getDeliveryAmount());
        }

        /**
         * 特价类型超出部分提示
         */
        Long packAmount = this.getPackAmount(baseRequestDTO, shoppingGoodsAmountBO);
        BuyMemberCardBO buyMemberCardBO = this.addNeedCardAmount(baseRequestDTO);
        // 买一赠一寄杯
        List<ChooseGoodsBO> chooseGoodsBO = distributeService.bugGiftAndSendCup(distributeBO.getCalculationDiscountBO().getResult(), distributeBO.getCartGoods(), activityQueryDto, baseRequestDTO);

        shoppingCartGoodsBO.setOriginalTotalAmount(shoppingGoodsAmountBO.getOriginalTotalAmount());
        shoppingCartGoodsBO.setNewPackAmount(packAmount);
        Long totalAmount = shoppingGoodsAmountBO.getTotalAmount();
        Long totalDiscountAmount = shoppingGoodsAmountBO.getTotalDiscountAmount();
        Long originalTotalAmount = shoppingGoodsAmountBO.getOriginalTotalAmount();
        // 加价购金额
        if (additionBO != null){
            totalAmount += additionBO.getAmount();
            totalDiscountAmount += additionBO.getDiscountAmount();
        }
        // 积分抵扣
        if(scoreReduceBO != null){
            int discountAmount = scoreReduceBO.getDiscountAmount() != null ? scoreReduceBO.getDiscountAmount() : 0;
            totalAmount -= discountAmount;
            totalDiscountAmount -= discountAmount;
            ShoppingCartCustomerScoreVo scoreVo = new ShoppingCartCustomerScoreVo();
            scoreVo.setCurrentScore(scoreReduceBO.getCurrentScore());
            scoreVo.setScoreState(scoreReduceBO.getScoreState());
            scoreVo.setScoreReduceRate(scoreReduceBO.getScoreReduceRate());
            scoreVo.setCustomerScorePrompt(scoreReduceBO.getCustomerScorePrompt());
            scoreVo.setOverlayOffers(scoreReduceBO.getOverlayOffers());
            scoreVo.setReduceAmount(scoreReduceBO.getReduceAmount());
            scoreVo.setReducePriceLimit(scoreReduceBO.getReducePriceLimit());
            scoreVo.setScoreReduceState(scoreReduceBO.getScoreReduceState());
            scoreVo.setUseScore(scoreReduceBO.getUseScore());
            shoppingCartGoodsBO.setCustomerScoreVo(scoreVo);
        }
        // 配送费
        if (delivery != null){
            shoppingCartGoodsBO.setDiscountDeliveryActivityCode(delivery.getActivityCode());
            shoppingCartGoodsBO.setDeliveryAmount(delivery.getDeliveryAmount());
            shoppingCartGoodsBO.setDiscountDeliveryAmount(delivery.getDiscountDeliveryAmount());
            shoppingCartGoodsBO.setThresholdAmount(delivery.getThresholdAmount());
            shoppingCartGoodsBO.setIsDiscountDelivery(delivery.getIsDiscountDelivery());
        }
        if (buyMemberCardBO != null){
            originalTotalAmount += buyMemberCardBO.getActivityPrice();
            totalAmount += (buyMemberCardBO.getActivityPrice() - buyMemberCardBO.getFirstCouponAmount());
            totalDiscountAmount += buyMemberCardBO.getFirstCouponAmount();
            shoppingCartGoodsBO.setCardOriginalAmount(buyMemberCardBO.getActivityPrice());
            shoppingCartGoodsBO.setCardDiscountAmount(buyMemberCardBO.getFirstCouponAmount());
        }

        shoppingCartGoodsBO.setTotalAmount(totalAmount);
        shoppingCartGoodsBO.setTotalDiscountAmount(totalDiscountAmount);
        shoppingCartGoodsBO.setOriginalTotalAmount(originalTotalAmount);
        shoppingCartGoodsBO.setFullDiscount(fullReductionBO.getDiscount());
        if (distributeBO.getCartGoods() == null){
            distributeBO.setCartGoods(new ArrayList<>());
        }
        distributeBO.getCartGoods().addAll(giftGoods);
        shoppingCartGoodsBO.setChooseGoods(chooseGoodsBO);
        shoppingCartGoodsBO.setVersion(2);
        shoppingCartGoodsBO.setProducts(distributeBO.getCartGoods());
        shoppingCartGoodsBO.setProductsCount(distributeBO.getCartGoods().size());


        setMessageBO.setDeliveryBO(delivery);
        setMessageBO.setActivityBO(fullReductionBO.getActivityBO());
        setMessageBO.setShoppingCartGoodsBO(shoppingCartGoodsBO);
        setMessageBO.setCartGoods(distributeBO.getCartGoods());
        setMessageBO.setCalculationDiscountBO(distributeBO.getCalculationDiscountBO());

        return setMessageBO;
    }

    /**
     * 在原价、现价、折扣价上增加第一次使用会员卡的费用
     *
     */
    public BuyMemberCardBO addNeedCardAmount(ListCartGoodsBO baseRequestDTO) {
        BuyMemberCardBO buyMemberCardBO = new BuyMemberCardBO();
        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = baseRequestDTO.getBuyMemberCard();
        if (baseRequestDTO.getBuyMemberCard() == null || StringUtils.isEmpty(buyMemberCard.getPaidId()) || StringUtils.isEmpty(buyMemberCard.getRuleId())) {
            return null;
        }
        GetPaidRuleRequestBO getPaidRuleRequestDto = new GetPaidRuleRequestBO();
        getPaidRuleRequestDto.setPartnerId(baseRequestDTO.getPartnerId());
        getPaidRuleRequestDto.setPaidId(buyMemberCard.getPaidId());
        getPaidRuleRequestDto.setRuleId(buyMemberCard.getRuleId());
        PaidRuleResponseBO paidRule = customerManager.getPaidRule(getPaidRuleRequestDto, baseRequestDTO.getManagerService().getCustomerService());
        if (paidRule != null){
            Integer activityPrice = paidRule.getActivityPrice();

        }
        // 购买会员卡的金额
        Integer activityPrice = paidRule.getActivityPrice();
        // 首次使用会员卡享受的折扣金额
        Integer firstCouponAmount = paidRule.getFirstCouponAmount() == null ? 0 : paidRule.getFirstCouponAmount();

        buyMemberCardBO.setActivityPrice(activityPrice);
        buyMemberCardBO.setFirstCouponAmount(firstCouponAmount);

        return buyMemberCardBO;
    }

    public Long getPackAmount(ListCartGoodsBO baseRequestDTO, ShoppingGoodsAmountBO shoppingGoodsAmountBO) {
        //==========================  购物车查询特有逻辑  =================================
        // 到店自取包装费设为null,外卖要计算包装费，flag为1表示去结算
        // 兼容老版本判断null
        if (Objects.equals(baseRequestDTO.getOrderType(), CreateOrderType.COLLECT_GOODS.getCode())
                && (Objects.equals(baseRequestDTO.getReachStoreType(), null)
                || Objects.equals(baseRequestDTO.getReachStoreType(), OrderType.EAT_IN.getCode()))) {
            return null;
        } else if ((Objects.equals(baseRequestDTO.getOrderType(), CreateOrderType.TAKE_OUT.getCode())
                || Objects.equals(baseRequestDTO.getReachStoreType(), OrderType.COLLECT_GOODS.getCode()))
                && Objects.equals(baseRequestDTO.getFlag(), SubmitPageEnum.YES.getCode())) {
            return  shoppingGoodsAmountBO.getNewPackAmount() == null ? 0L : shoppingGoodsAmountBO.getNewPackAmount();
        }
        return null;
    }

    public DeliveryBO delivery(CalculationDiscountBO calculationDiscountBO, ListCartGoodsBO baseRequestDTO
            , ActivityQueryDto activityQueryDto, Long calDeliveryAmount) {
        DeliveryBO deliveryBO = new DeliveryBO();
        DecimalFormat df = new DecimalFormat("###.##");
        List<ActivityTypeEnum> activityTypeEnums = new LinkedList<>();
        activityTypeEnums.add(ActivityTypeEnum.TYPE_14);

        GetActivityBO getActivityBO = new GetActivityBO();
        getActivityBO.setActivityQueryDto(activityQueryDto);
        getActivityBO.setActivityTypeEnums(activityTypeEnums);
        ActivityBO activityBO = promotionManager.queryActivityByType(getActivityBO, baseRequestDTO.getManagerService().getPromotionService());
        BenefitBeanBO beanDto = new BenefitBeanBO();
        if (activityBO != null){
            beanDto = activityBO.getBenefits().get(0);
            deliveryBO.setActivityCode(activityBO.getActivityCode());
        }
        CalculationDiscountBO.CalculationDiscountResult.Discount discount=null;
        CalculationDiscountBO.CalculationDiscountResult discountResult = null;
        Long deliveryAmount = 0L;
        if (calDeliveryAmount != null){
            deliveryAmount = calDeliveryAmount;
        }
        if (calculationDiscountBO != null && calculationDiscountBO.getResult() != null && CollectionUtils.isNotEmpty(calculationDiscountBO.getResult().getDiscounts())) {
            discountResult = calculationDiscountBO.getResult();
            discount = discountResult.getDiscounts().stream().filter((d) -> ActivityTypeEnum.TYPE_14.getCode().equals(d.getType())).findFirst().orElse(null);
        }

        if(discount!=null) {
            if(beanDto.getBenefitType() == 1) {
                String desc = DELIVERY_DISCOUNT_DESC2;
                deliveryBO.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ));
            }
            else {
                String desc = DELIVERY_DISCOUNT_DESC1;
                deliveryBO.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ,df.format(beanDto.getDiscountAmount().doubleValue() / 100)));
            }
            deliveryBO.setDeliveryAmount(calDeliveryAmount);
            deliveryBO.setDiscountDeliveryAmount(discountResult.getDistributionFee());
            deliveryBO.setThresholdAmount(discount.getThresholdAmount());
            deliveryBO.setIsDiscountDelivery(true);
        } else {
            if (activityBO!=null) {
                if(beanDto.getBenefitType() == 1) {
                    String desc = DELIVERY_DISCOUNT_DESC2;
                    deliveryBO.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ));
                }
                else {
                    String desc = DELIVERY_DISCOUNT_DESC1;
                    deliveryBO.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100 ),df.format(beanDto.getDiscountAmount().doubleValue() / 100)));
                }

                deliveryBO.setDeliveryAmount(deliveryAmount);
                deliveryBO.setDiscountDeliveryAmount(deliveryAmount);
                deliveryBO.setIsDiscountDelivery(false);

            } else {
                String desc = DELIVERY_DISCOUNT_DESC3;
                deliveryBO.setDeliveryDiscountDesc(String.format(desc, df.format(deliveryAmount.doubleValue() / 100)));
                deliveryBO.setDeliveryAmount(deliveryAmount);
                deliveryBO.setDiscountDeliveryAmount(deliveryAmount);
                deliveryBO.setIsDiscountDelivery(false);
            }
        }
        return deliveryBO;
    }


    public ScoreReduceBO scoreReduce(CalculationDiscountBO calculationDiscountBO
            , ListCartGoodsBO baseRequestDTO, ShoppingGoodsAmountBO shoppingGoodsAmountBO, AdditionBO additionBO) {
        ScoreReduceBO scoreReduce = new ScoreReduceBO();
        if (baseRequestDTO == null || baseRequestDTO.getUseCustomerScore() == null
                || baseRequestDTO.getUseCustomerScore() == null
                || baseRequestDTO.getUseCustomerScore().equals(CustomerScoreConstant.NO_DISPLAY.getValue())) {
            return null;
        }

        GetUserScoreUseDetailBO request = new GetUserScoreUseDetailBO();
        request.setMemberId(baseRequestDTO.getUserId());
        request.setPaidAmount(getValue(shoppingGoodsAmountBO.getTotalAmount() + additionBO.getAmount()));
        request.setPartnerId(baseRequestDTO.getPartnerId());
        UserScoreUserDetailBO userScoreUseDetail = null;
        try {
            // 加入try catch是为了custom服务挂掉，购物车服务可以也可以正常
            userScoreUseDetail = customerManager.getUserScoreUseDetail(request, baseRequestDTO.getManagerService().getCustomerService());
        } catch (Exception ex) {
            ErrorLog.errorConvertJson(this.getClass(),"getUserScoreUseDetailError",ex);
        }

        if (userScoreUseDetail != null) {
            Integer discountAmount = 0;
            if (CustomerScoreConstant.SUBSTRACT.getValue().equals(baseRequestDTO.getUseCustomerScore())) {
                //设置 购物车总金额=购物车总价-积分扣减金额
                discountAmount = getValue(userScoreUseDetail.getReduceAmount());
            }
            //设置 积分抵扣VO
            scoreReduce.setCurrentScore(getValue(userScoreUseDetail.getCurrentScore()));
            scoreReduce.setReduceAmount(getValue(userScoreUseDetail.getReduceAmount()));
            scoreReduce.setReducePriceLimit(getValue(userScoreUseDetail.getReducePriceLimit()));
            scoreReduce.setOverlayOffers(userScoreUseDetail.getOverlayOffers());
            scoreReduce.setScoreReduceState(getValue(userScoreUseDetail.getScoreState()));
            // 是否可优惠同享{0所有订单均可抵扣,1仅限原价订单才可抵扣（享受了促销活动、或使用了优惠券，不能进行积分抵扣
            if (getValue(userScoreUseDetail.getOverlayOffers()) == 0) {
                scoreReduce.setScoreReduceState(getValue(userScoreUseDetail.getScoreState()));
            } else {
                CalculationDiscountBO.CalculationDiscountResult discountResult = null;
                if (calculationDiscountBO != null){
                    discountResult = calculationDiscountBO.getResult();
                }
                if (discountResult != null){
                    if (StringUtils.isNotBlank(baseRequestDTO.getCouponCode()) || (discountResult.getTotalDiscountAmount().intValue() > 0)
                            || (!CollectionUtils.isEmpty(discountResult.getDiscounts()))) {
                        //是否有换购
                        int type81 = 0;
                        for (CalculationDiscountBO.CalculationDiscountResult.Discount discount : discountResult.getDiscounts()) {
                            if (ActivityTypeEnum.TYPE_81.getCode().equals(discount.getType())) {
                                type81 = 1;
                                break;
                            }
                        }
                        //集点
                        long discountCount = discountResult.getDiscounts().stream().filter(discount -> !ActivityTypeEnum.TYPE_221.getCode().equals(discount.getType())).count();

                        //积分抵扣开关禁用 有换购活动 且选中了换购商品
                        // - 有换购且选中了换购商品
                        // - 有换购且没有选中换购商品 且除集点以外还有其他促销
                        if ((type81 == 0 && discountCount >= 1)
                                || (type81 == 1 && !CollectionUtils.isEmpty(baseRequestDTO.getSendGoods()))
                                || (type81 == 1 && discountCount > 1)) {
                            scoreReduce.setScoreReduceState(5);
                            userScoreUseDetail.setScoreState(5);
                            scoreReduce.setReduceAmount(0);
                        }
                    }
                }
            }
            scoreReduce.setUseScore(getValue(userScoreUseDetail.getUseScore()));
            scoreReduce.setScoreState(userScoreUseDetail.getScoreState());
            scoreReduce.setScoreReduceRate(userScoreUseDetail.getScoreReduceRate());
        } else {
            scoreReduce = null;
        }
        return scoreReduce;
    }

    private Integer getValue(Object object) {
        Integer result = 0;
        try {
            if (object != null) {
                if (object instanceof Integer) {
                    result = (Integer) object;
                }
                else if (object instanceof String) {
                    result = Integer.parseInt((String) object);
                }
                else if (object instanceof Double) {
                    result = (int) ((double) object);
                }
                else if (object instanceof Float) {
                    result = (int) ((float) object);
                }
                else if (object instanceof BigDecimal) {
                    result = ((BigDecimal) object).intValue();
                }
                else if (object instanceof Long) {
                    result = ((Long) object).intValue();
                }
            }
        } catch (Exception ex) {
            ErrorLog.errorConvertJson(this.getClass(),"getScoreValueFail",ex);
        }
        return result;
    }

    public AdditionBO additionResponse(CalculationDiscountBO.CalculationDiscountResult discountResult
            , ListCartGoodsBO baseRequestDTO) {
        AdditionBO additionBO = new AdditionBO();
        if (baseRequestDTO == null
                || CollectionUtils.isEmpty(baseRequestDTO.getSendGoods())
                || discountResult == null
                || CollectionUtils.isEmpty(discountResult.getSendGoods())) {
            return new AdditionBO(0L ,0l);
        }

        //检查是否有加价购商品
        List<CalculationDiscountBO.CalculationDiscountResult.SendActivity> sendGoods = discountResult.getSendGoods()
                .stream()
                .filter(s -> ActivityTypeEnum.TYPE_81.getCode().equals(s.getActivityType()))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(sendGoods)) {
            return new AdditionBO(0L ,0l);
        }
        List<CreateOrderVo.PremiumExchangeActivity.Product> additionalProducts = this.buildPremiumExchangeActivityProduct(baseRequestDTO);
        List<CalculationDiscountBO.CalculationDiscountResult.SendActivity> additionalActivityList = discountResult.getSendGoods();
        ResponseResult checkResult = checkAdditionalGoods(additionalProducts, additionalActivityList);
        if (!ObjectUtils.equals(ResponseResult.SUCCESS, checkResult)) {
            throw new ServiceException(checkResult);
        }


        Long totalDiscountPrice = 0L;
        Long totalNowPrice = 0L;
        // goodsId->qty
        Map<String, Integer> map = baseRequestDTO.getSendGoods()
                .stream()
                .collect(Collectors.toMap(SendGoods::getGoodsId, SendGoods::getQty));

        //goodsId -> originalPrice
        Map<String, Long> OriginalPrice = sendGoods.get(0)
                .getSendGoods()
                .stream()
                .collect(Collectors.toMap(CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods::getGoodsId, CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods::getOriginalPrice));

        //goodsId->nowPrice
        Map<String, Long> newPrice = sendGoods.get(0)
                .getSendGoods()
                .stream()
                .collect(Collectors.toMap(CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods::getGoodsId, CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods::getNowPrice));

        for (String str : map.keySet()) {
            Integer qty = map.get(str);
            if (OriginalPrice.get(str) != null && OriginalPrice.get(str) != 0) {
                totalDiscountPrice += qty * (OriginalPrice.get(str) - newPrice.get(str));
                totalNowPrice      += qty * newPrice.get(str);
            }
        }
        additionBO.setAmount(totalNowPrice);
        additionBO.setDiscountAmount(totalDiscountPrice);
        return additionBO;
    }


    /**
     * 构建加价购商品校验参数
     *
     * @param baseRequestDTO 入参
     * @return 返回商品
     */
    public List<CreateOrderVo.PremiumExchangeActivity.Product> buildPremiumExchangeActivityProduct(ListCartGoodsBO baseRequestDTO) {

        List<SendGoods> sendGoods = baseRequestDTO.getSendGoods();
        List<String> goodsIds = sendGoods
                .stream()
                .map(SendGoods::getGoodsId)
                .collect(Collectors.toList());

        Map<String, SendGoods> goodQtyMap = sendGoods
                .stream()
                .collect(Collectors.toMap(SendGoods::getGoodsId, Function.identity(), (k1, k2) -> k1));
        GetProductBO getProductBO = new GetProductBO();
        getProductBO.setMenuType(baseRequestDTO.getMenuType());
        getProductBO.setPartnerId(baseRequestDTO.getPartnerId());
        getProductBO.setStoreId(baseRequestDTO.getShopId());
        getProductBO.setGoodsId(goodsIds);


        List<ProductBO> productsInfo = productManager.getProductsInfo(getProductBO, baseRequestDTO.getManagerService().getProductService());

        if (CollectionUtils.isEmpty(productsInfo)) {
            throw new ServiceException(ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST);
        }

        return productsInfo.stream().map(productBean ->{
            CreateOrderVo.PremiumExchangeActivity.Product product = new CreateOrderVo.PremiumExchangeActivity.Product();
            List<ProductBO.SkuProductBean> skuList = productBean.getSkuList();
            List<String> skuIds = null;
            if (null!=skuList) {
                skuIds = skuList.stream().map(ProductBO.SkuProductBean::getSkuId).collect(Collectors.toList());
            }
            if (!CollectionUtils.isEmpty(skuIds)) {
                for (String skuId : skuIds) {
                    SendGoods sendGood = goodQtyMap.get(skuId);
                    if (null != sendGood) {
                        product.setQty(sendGood.getQty());
                        product.setSpuId(productBean.getSpuId());
                        product.setSkuId(sendGood.getGoodsId());
                        product.setStatus(productBean.getStatus());
                        break;
                    }
                }
            }
            else {
                SendGoods sendGood = goodQtyMap.get(productBean.getSpuId());
                if (null != sendGood) {
                    product.setQty(sendGood.getQty());
                    product.setSpuId(sendGood.getGoodsId());
                    product.setSkuId(sendGood.getGoodsId());
                    product.setStatus(productBean.getStatus());
                }
            }
            return product;
        }).collect(Collectors.toList());
    }


    /**
     * check加价购
     *
     * @param additionalProducts     购物车添加的加价购商品
     * @param additionalActivityList 加价购活动
     * @return
     */
    private ResponseResult checkAdditionalGoods(List<CreateOrderVo.PremiumExchangeActivity.Product> additionalProducts
            , List<CalculationDiscountBO.CalculationDiscountResult.SendActivity> additionalActivityList) {
        //无加价购活动
        if (CollectionUtils.isEmpty(additionalActivityList)) {
            return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
        }
        //加价购活动中换购商品为空
        List<CalculationDiscountBO.CalculationDiscountResult.SendActivity> additionalActivity = additionalActivityList
                .stream()
                .filter(activity -> ObjectUtils.equals(ActivityTypeEnum.TYPE_81.getCode(), activity.getActivityType()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(additionalActivity)) {
            return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
        }
        //购物车中总加价购数量>每单可换购总数量
        Integer totalAdditionalProductCount = additionalProducts.stream().mapToInt(CreateOrderVo.PremiumExchangeActivity.Product::getQty).sum();
        if (totalAdditionalProductCount > additionalActivity.get(0).getMaxNum()) {
            return ResponseResult.PREMIUM_EXCHANGE_GOODS_OUT_OF_LIMIT;
        }
        //加价购活动中的换购商品列表Map
        Map<String, CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods> sendGoodsMap = additionalActivity.get(0).getSendGoods()
                .stream()
                .collect(Collectors.toMap(CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods::getGoodsId, Function.identity(), (k1, k2) -> k1));
        for (CreateOrderVo.PremiumExchangeActivity.Product product : additionalProducts) {
            if (ShoppingCartConstant.OFF_LINE_PRODUCT.equals(product.getStatus()) || ShoppingCartConstant.SOLD_OUT_PRODUCT.equals(product.getStatus())) {
                return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
            }
            if (ShoppingCartConstant.NOT_ON_LINE_PRODUCT.equals(product.getStatus())) {
                return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_ON_LINE;
            }
            // 购物车中加价购商品不在活动商品列表中 或  每个商品的换购数量>活动限制数量
            CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods sendGoods = Objects.isNull(sendGoodsMap.get(product.getSkuId())) ? sendGoodsMap.get(product.getSpuId()) : sendGoodsMap.get(product.getSkuId());
            if (Objects.isNull(sendGoods)) {
                return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
            }
            if (product.getQty() > sendGoods.getSendNumber()) {
                return ResponseResult.PREMIUM_EXCHANGE_GOODS_OUT_OF_LIMIT;
            }
        }
        return ResponseResult.SUCCESS;
    }



    private List<ChooseGoodsBO> bugGiftAndSendCup(CalculationDiscountBO calculationDiscountBO, List<CartGoods> cartGoods, ActivityQueryDto activityQueryDto, ListCartGoodsBO baseRequestDTO){

        if(calculationDiscountBO == null || calculationDiscountBO.getResult() == null){
            return null;
        }
        CalculationDiscountBO.CalculationDiscountResult result = calculationDiscountBO.getResult();
        //  过略出来买一赠一寄杯活动，没有直接返回
        List<CalculationDiscountBO.CalculationDiscountResult.Discount> discounts = result.getDiscounts();
        if(null == discounts || discounts.isEmpty()){
            return null;
        }
        List<CalculationDiscountBO.CalculationDiscountResult.Discount> buyOneGiveOneSendDiscounts = discounts
                .stream()
                .filter(discount -> ObjectUtils.equals(discount.getType(), ActivityTypeEnum.TYPE_63.getCode()))
                .collect(Collectors.toList());
        if(null == buyOneGiveOneSendDiscounts || buyOneGiveOneSendDiscounts.isEmpty()){
            return null;
        }

        if (buyOneGiveOneSendDiscounts == null || CollectionUtils.isEmpty(result.getGoods())) {
            return null;
        }
/*        String menuType = shoppingCartInfoRequestVo == null ? null : shoppingCartInfoRequestVo.getMenuType();
        // 构建赠品detail
        List<ProductBeanDTO> beanDTOList = this.drawGiftInfo(discountResult, activityQueryDto, menuType);
        this.setCartGoods(discountResult, cartGoodsList, beanDTOList);*/

        // 设置用户可以选择的寄送商品券码
        return this.buildSendGoods(result);

    }


    private void setToastMsgIfNotExist(ShoppingCartGoodsBO shoppingCartGoodsBO, String message) {
        if (StringUtils.isEmpty(shoppingCartGoodsBO.getToastMsg())) {
            shoppingCartGoodsBO.setToastMsg(message);
        }
    }

    /**
     * 设置没有加入购物车的提示语
     * @param messageBuilder
     */
    private ArrayList<ActivityList> setMessageNotInShoppingCart(StringBuilder messageBuilder, ActivityBO activityBO, List<BenefitBeanBO> benefitBeanBOList, BenefitBeanBO benefitBeanBO) {

        ArrayList<ActivityList> activityList = new ArrayList<>();
        if (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityBO.getActivityType())) {
            messageBuilder.append("每满 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount(benefitBeanBO.getThresholdAmount() * 1.00 / 100))
                    .append("</span> 减 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount(benefitBeanBO.getDiscountAmount() * 1.00 / 100))
                    .append("</span> ")
                    .append("最高减 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount(activityBO.getMaxMoney() * 1.00 / 100))
                    .append("</span> 元");

            //满足  x 元 减 Y 元 ，最高 减 Z元
            ActivityList notInShopping = new ActivityList();
            notInShopping.setTipType(1);
            notInShopping.setSatisfy(WebUtil.formatAmount(benefitBeanBO.getThresholdAmount() * 1.00 / 100).toString());
            notInShopping.setDeduct(WebUtil.formatAmount(benefitBeanBO.getDiscountAmount() * 1.00 / 100).toString());
            notInShopping.setMaxDeduct(WebUtil.formatAmount(activityBO.getMaxMoney() * 1.00 / 100).toString());
            activityList.add(notInShopping);
        }
        if (Objects.equals(ActivityTypeEnum.TYPE_12.getCode(), activityBO.getActivityType())) {
            int len = benefitBeanBOList.size();
            // // 购物车中无商品或者存在与满减互斥的活动
            for (int i = len - 1; i >= 0; i--) {
                benefitBeanBO = benefitBeanBOList.get(i);
                messageBuilder.append("满 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(benefitBeanBO.getThresholdAmount() * 1.00 / 100))
                        .append("</span> 减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(benefitBeanBO.getDiscountAmount() * 1.00 / 100))
                        .append("</span> 元");
                if (i > 0) messageBuilder.append("，");
            }
            //  阶梯满减：满足 X 元 减 Y 元,
            for (int j = len - 1; j >= 0; j--) {
                benefitBeanBO = benefitBeanBOList.get(j);
                ActivityList notInShopping = new ActivityList();
                notInShopping.setTipType(2);
                notInShopping.setSatisfy(WebUtil.formatAmount(benefitBeanBO.getThresholdAmount() * 1.00 / 100).toString());
                notInShopping.setDeduct(WebUtil.formatAmount(benefitBeanBO.getDiscountAmount() * 1.00 / 100).toString());
                activityList.add(notInShopping);
            }
        }
        return activityList;
    }


    /**
     * 设置加入商品满足购物车时的提示语
     *
     * @param messageBuilder
     * @param activityPrompts
     * @param activityResponseDto
     */
    private List<ActivityList> setMessageSatisfyCart(StringBuilder messageBuilder, List<CalculationDiscountBO.CalculationDiscountResult.ActivityPrompt> activityPrompts
            , ActivityBO activityResponseDto) {
        ArrayList<ActivityList> result = new ArrayList<>();
        ActivityList satisfyList = new ActivityList();
        CalculationDiscountBO.CalculationDiscountResult.ActivityPrompt activityPrompt = activityPrompts.get(0);
        if (activityPrompt.getAlreadyDiscountAmount() == null
                || activityPrompt.getAlreadyDiscountAmount() == 0) {
            messageBuilder.append("满 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount(activityPrompt.getThresholdAmount() * 1.00 / 100))
                    .append("</span> 减 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount(activityPrompt.getDiscountAmout() * 1.00 / 100))
                    .append("</span> ")
                    .append("还差 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100))
                    .append("</span> 元");
            // 满足 X 元 减 Y 元 还差 Z元
            satisfyList.setTipType(3);
            satisfyList.setSatisfy(WebUtil.formatAmount(activityPrompt.getThresholdAmount() * 1.00 / 100).toString());
            satisfyList.setDeduct(WebUtil.formatAmount(activityPrompt.getDiscountAmout() * 1.00 / 100).toString());
            satisfyList.setMissing(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100).toString());
        } else {
            Long toDiscountAmout;
            if (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityResponseDto.getActivityType())) {
                toDiscountAmout = activityPrompt.getDiscountAmout() + activityPrompt.getAlreadyDiscountAmount();
            } else {
                toDiscountAmout = activityPrompt.getDiscountAmout();
            }
            //已减 X 元 再买 Y 元 减 Z 元
            messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount(activityPrompt.getAlreadyDiscountAmount() * 1.00 / 100))
                    .append("</span> 元 再买 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100))
                    .append("</span> 元减 <span style=\"color:#fa5555\">")
                    .append(WebUtil.formatAmount(toDiscountAmout * 1.00 / 100))
                    .append("</span> 元");
            satisfyList.setTipType(4);
            satisfyList.setDeduct(WebUtil.formatAmount(activityPrompt.getAlreadyDiscountAmount() * 1.00 / 100).toString());
            satisfyList.setAgainBuy(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100).toString());
            satisfyList.setAgianDeduct(WebUtil.formatAmount(toDiscountAmout * 1.00 / 100).toString());
        }
        result.add(satisfyList);
        return result;
    }


    /**
     * 设置加入商品不满足购物车时的提示语
     *
     * @param messageBuilder
     * @param discountList
     */
    private List<ActivityList> setMessageNoSatisfyCart(StringBuilder messageBuilder, List<CalculationDiscountBO.CalculationDiscountResult.Discount> discountList) {
        List<ActivityList> activityList = new ArrayList<>();
        discountList = discountList.parallelStream().filter(k -> (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), k.getType())
                || Objects.equals(ActivityTypeEnum.TYPE_12.getCode(), k.getType()))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(discountList)) {
            return null;
        }
        //已减 X 元
        messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                .append(WebUtil.formatAmount(discountList.get(0).getDiscount() * 1.00 / 100))
                .append("</span> 元");
        ActivityList noSatisfy = new ActivityList();
        noSatisfy.setTipType(5);
        noSatisfy.setDeduct(WebUtil.formatAmount(discountList.get(0).getDiscount() * 1.00 / 100).toString());
        activityList.add(noSatisfy);
        return activityList;
    }

    private List<CartGoods> buyGift(CalculationDiscountBO.CalculationDiscountResult result, List<CartGoods> cartGoods, ActivityQueryDto activityQueryDto, ListCartGoodsBO baseRequestDTO){


        if (result == null || CollectionUtils.isEmpty(result.getGoods())) {
            return new ArrayList<>();
        }
        List<ProductBO> products = this.drawGiftInfo(result, baseRequestDTO);
        return this.gifAddCart(products, result);
    }

    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList,
                                             String goodsCode,String goodsId, Integer goodsQuantity, Long originalPrice, Integer memberDiscount,CartGoods cartGoods) {
        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods();
        calculationDiscountGoods.setGoodsCode(goodsCode);
        calculationDiscountGoods.setGoodsId(goodsId);
        calculationDiscountGoods.setGoodsQuantity(goodsQuantity);
        calculationDiscountGoods.setOriginalPrice(originalPrice);
        calculationDiscountGoods.setMemberDiscount(memberDiscount);
        //新增咖啡月卡券券号
        calculationDiscountGoods.setCouponCode(cartGoods.getCouponCode());
        calculationDiscountGoods.setCartGoodsUid(cartGoods.getCartGoodsUid());

        ArrayList<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material> materials = new ArrayList<>();
        //可选搭配
        if (cartGoods != null && CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
            for (CartGoods.ComboxGoods materialGoods : cartGoods.getProductGroupList()) {
                if("0".equals(materialGoods.getGoodsId())){
                    continue;
                }
                ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material material = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material();
                material.setType(2);
                material.setGoodsId(materialGoods.getGoodsId());
                material.setGoodsQuantity(materialGoods.getQty());
                material.setOriginalPrice(null != materialGoods.getFinalPrice() ?
                        materialGoods.getFinalPrice() : 0);
                materials.add(material);
            }
        }

        //固定商品
        if (cartGoods != null && CollectionUtils.isNotEmpty(cartGoods.getProductComboList())) {
            for (CartGoods.ComboxGoods materialGoods : cartGoods.getProductComboList()) {
                //加料
                if (CollectionUtils.isNotEmpty(materialGoods.getProductMaterialList())) {
                    for (CartGoods.MaterialGoods materialGoods2 : materialGoods.getProductMaterialList()) {
                        if (StringUtils.isEmpty(materialGoods2.getSpuId())) {
                            continue;
                        }
                        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material material = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material();
                        material.setType(1);
                        material.setGoodsId(materialGoods2.getSpuId());
                        material.setGoodsQuantity(1);
                        material.setOriginalPrice(null != materialGoods2.getFinalPrice() ?
                                materialGoods2.getFinalPrice() : 0);
                        materials.add(material);
                    }
                }
            }
        }

        //加料
        if (null != cartGoods && CollectionUtils.isNotEmpty(cartGoods.getProductMaterialList())) {
            for (CartGoods.MaterialGoods materialGoods : cartGoods.getProductMaterialList()) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material material = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material();
                material.setType(1);
                material.setGoodsId(materialGoods.getSpuId());
                material.setGoodsQuantity(1);
                material.setOriginalPrice(null != materialGoods.getOriginalPrice() ?
                        materialGoods.getOriginalPrice() : 0);
                material.setNowPrice(null != materialGoods.getFinalPrice() ? materialGoods.getFinalPrice().intValue():0);
                materials.add(material);
            }
        }
        calculationDiscountGoods.setSmallMaterial(materials);
        calculationDiscountGoodsList.add(calculationDiscountGoods);

    }

    private FullReductionBO fullReduction(ListCartGoodsBO baseRequestDTO, CalculationDiscountBO calculationDiscountBO, List<CartGoods> cartGoodsList, ActivityQueryDto activityQueryDto){

        FullReductionBO fullReduction = new FullReductionBO();


        List<ActivityTypeEnum> activityTypeEnums = new LinkedList<>();
        /**
         * 每满减 TYPE_11\ 阶梯满减 TYPE_12
         */
        activityTypeEnums.add(ActivityTypeEnum.TYPE_11);
        activityTypeEnums.add(ActivityTypeEnum.TYPE_12);
        activityTypeEnums.add(ActivityTypeEnum.TYPE_3);
        activityTypeEnums.add(ActivityTypeEnum.TYPE_31);

        GetActivityBO getActivityBO = new GetActivityBO();
        getActivityBO.setActivityQueryDto(activityQueryDto);
        getActivityBO.setActivityTypeEnums(activityTypeEnums);


        ActivityBO activityBO = promotionManager.queryActivityByType(getActivityBO, baseRequestDTO.getManagerService().getPromotionService());
        fullReduction.setActivityBO(activityBO);

        if (activityBO == null || calculationDiscountBO == null || calculationDiscountBO.getResult() == null){
            return fullReduction;
        }
        CalculationDiscountBO.CalculationDiscountResult discountResult = calculationDiscountBO.getResult();
        List<CalculationDiscountBO.CalculationDiscountResult.Discount> discounts = discountResult.getDiscounts();
        List<CalculationDiscountBO.CalculationDiscountResult.Discount> fullDiscountsList = discounts
                .stream()
                .filter(d -> ActivityTypeEnum.TYPE_11.getCode().equals(d.getType()) || ActivityTypeEnum.TYPE_12.getCode().equals(d.getType()))
                .collect(Collectors.toList());
        /**
         * 设置到响应中 总的满减优惠金额
         */
        if (CollectionUtils.isNotEmpty(fullDiscountsList)) {

            long fullDiscount = 0L;
            fullDiscount = fullDiscountsList.stream().filter(d -> d.getDiscount() != null).mapToLong(CalculationDiscountBO.CalculationDiscountResult.Discount::getDiscount).sum();
            fullReduction.setDiscount(fullDiscount);
        }

        List<Integer> typeEnums = activityTypeEnums.stream().map(ActivityTypeEnum::getCode).collect(Collectors.toList());
        /**
         * 还原满减折扣到行记录上
         */
        Map<String, CalculationDiscountBO.CalculationDiscountResult.Goods> map = discountResult.getGoods()
                .stream()
                .filter(g -> null != g.getCartGoodsUid())
                .collect(Collectors.toMap(CalculationDiscountBO.CalculationDiscountResult.Goods::getCartGoodsUid, Function.identity(), (k1, k2) -> k1));

        long full = 0L;
        long sum = 0L;
        for (CartGoods cart : cartGoodsList) {
            CalculationDiscountBO.CalculationDiscountResult.Goods discountMap = map.get(cart.getCartGoodsUid());
            full = 0L;
            sum = 0L;
            if (null==discountMap) continue;
            if (CollectionUtils.isNotEmpty(discountMap.getDiscounts())) {
                sum = discountMap.getDiscounts()
                        .stream()
                        .filter(d -> typeEnums.contains(d.getType()))
                        .mapToLong(CalculationDiscountBO.CalculationDiscountResult.Goods.GoodsDiscount::getDiscount)
                        .sum();
                cart.setAmount(cart.getAmount() + sum);
            }
            //小料
            if (CollectionUtils.isNotEmpty(cart.getProductMaterialList())) {
                List<CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial> materialDiscount = discountMap.getSmallMaterial();
                HashMap<String, Long> mDiscount = drawnFullDiscount(materialDiscount, typeEnums, 1);
                if (!mDiscount.isEmpty()) {
                    for (CartGoods.MaterialGoods mt : cart.getProductMaterialList()) {
                        Long md = mDiscount.get(mt.getSpuId());
                        if (md != null) {
                            mt.setAmount(mt.getAmount() + md);
                        }
                    }
                }
            }
            //可选商品
            if (CollectionUtils.isNotEmpty(cart.getProductGroupList())) {
                List<CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial> materialDiscount = discountMap.getSmallMaterial();
                HashMap<String, Long> mDiscount = drawnFullDiscount(materialDiscount, typeEnums, 2);
                if (!mDiscount.isEmpty()) {
                    for (CartGoods.ComboxGoods com : cart.getProductGroupList()) {
                        Long md = mDiscount.get(com.getGoodsId());
                        if (md != null) {
                            com.setAmount(com.getAmount() + md);
                            cart.setAmount(cart.getAmount() + md);
                        }
                    }
                }
            }
        }
        return fullReduction;

    }


    private ShoppingCartContext convert2ShopingCartContext(ListCartGoodsBO baseRequestDTO){
        ShoppingCartContext cartContext = new ShoppingCartContext();
        cartContext.setMenuType(baseRequestDTO.getMenuType());
        cartContext.setOrderType(baseRequestDTO.getOrderType());
        cartContext.setPartnerId(baseRequestDTO.getPartnerId());
        cartContext.setShopId(baseRequestDTO.getShopId());
        cartContext.setUserId(baseRequestDTO.getUserId());
        cartContext.setSessionId(baseRequestDTO.getSessionId());
        cartContext.setTableNumber(baseRequestDTO.getTableNumber());
        return cartContext;
    }

    private void checkStocks(ListCartGoodsBO baseRequestDTO, CheckBussinessRulesBO checkBussinessRulesBO){


    }


    private void checkMeal(List<CartGoods> cartGoodsList, CartGoods addGoods){

        if (GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType().equals(addGoods.getGoodsType())) {
            if (CollectionUtils.isEmpty(addGoods.getProductGroupList()) && CollectionUtils.isEmpty(addGoods.getProductComboList())) {
                throw new ServiceException(ResponseResult.SHOPPING_CART_NO_MEAL);
            }
        }

        for (CartGoods cartGoods : cartGoodsList){
            if (GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType().equals(addGoods.getGoodsType())) {
                if (CollectionUtils.isEmpty(addGoods.getProductGroupList()) && CollectionUtils.isEmpty(addGoods.getProductComboList())) {
                    throw new ServiceException(ResponseResult.SHOPPING_CART_NO_MEAL);
                }
            }
        }
    }

    /**
     * 初始化价格
     */
    public ShoppingGoodsAmountBO initShoppingCart(CalculationDiscountBO calculationDiscountBO
            , List<CartGoods> cartGoodsList) {
        ShoppingGoodsAmountBO shoppingGoodsAmountBO = new ShoppingGoodsAmountBO();

        /**
         * 使用促销算价赋值行记录
         */
        List<CalculationDiscountBO.CalculationDiscountResult.Goods> goods = null;
        CalculationDiscountBO.CalculationDiscountResult discountResult = null;
        if (calculationDiscountBO != null && calculationDiscountBO.getResult() != null && CollectionUtils.isNotEmpty(calculationDiscountBO.getResult().getGoods())) {
            discountResult = calculationDiscountBO.getResult();
            goods = discountResult.getGoods();
        }
        long totalOriginalAmount = 0L, totalAmount = 0L, totalPackageAmount = 0L;
        long originalAmount = 0L, amount = 0L, packageAmount = 0L;
        for (CartGoods cartGoods : cartGoodsList) {
            originalAmount = 0L;amount = 0L;packageAmount = 0L;

            //原价行记录
            originalAmount = cartGoods.getOriginalPrice() * cartGoods.getQty();
            cartGoods.setOriginalAmount(originalAmount);

            this.rowRealAmount(goods, cartGoods);
            //成交价行记录
            amount = cartGoods.getAmount();
            totalAmount += amount;
            totalOriginalAmount += cartGoods.getOriginalAmount();

            //包装费行记录
            packageAmount = cartGoods.getPackPrice() * cartGoods.getQty();
            cartGoods.setPackPrice(packageAmount);
            totalPackageAmount += packageAmount;
        }
        shoppingGoodsAmountBO.setOriginalTotalAmount(discountResult == null ? totalOriginalAmount : discountResult.getOriginalTotalAmount());
        shoppingGoodsAmountBO.setTotalAmount(discountResult == null ? totalAmount : discountResult.getTotalAmount());
        shoppingGoodsAmountBO.setNewPackAmount(totalPackageAmount);
        shoppingGoodsAmountBO.setTotalDiscountAmount(discountResult == null ? 0L : discountResult.getTotalDiscountAmount());
        return shoppingGoodsAmountBO;
    }


    private void rowRealAmount(List<CalculationDiscountBO.CalculationDiscountResult.Goods> goods, CartGoods cartGoods) {

        CalculationDiscountBO.CalculationDiscountResult.Goods find = goods
                .stream().filter((k) -> k.getCartGoodsUid().equals(cartGoods.getCartGoodsUid()))
                .findFirst()
                .get();

        if (find == null) return;
        cartGoods.setAmount(find.getRealAmount());
        //cartGoods.setOriginalAmount(find.getOriginalPrice());
        /**
         * 套餐的原价
         */
        Long originPrice = 0L;
        if (CollectionUtils.isNotEmpty(cartGoods.getProductComboList())) {
            for (CartGoods.ComboxGoods com : cartGoods.getProductComboList()) {
                originPrice += com.getFinalPrice() * cartGoods.getQty() * com.getQty();
            }
        }
        /**
         * 可选搭配
         */
        if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
            Integer type2 = 2;
            Map<String, CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial> gChoices = find.getSmallMaterial()
                    .stream().filter(d -> type2.equals(d.getType()))
                    .collect(Collectors.toMap(CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial::getGoodsId, Function.identity(), (k1, k2) -> k1));
            long amount = 0L;

            //可选搭配
            for (CartGoods.ComboxGoods choice : cartGoods.getProductGroupList()) {
                CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial mt = gChoices.get(choice.getGoodsId());
                if (mt == null) {
                    amount += choice.getAmount() * choice.getQty();
                }
                else {
                    amount += mt.getRealAmount();
                    choice.setAmount(mt.getRealAmount().longValue());
                }
                originPrice += choice.getFinalPrice() * choice.getQty()*cartGoods.getQty();
            }
            cartGoods.setAmount(cartGoods.getAmount() + amount);
        }
        /**
         * 小料
         */
        if (CollectionUtils.isNotEmpty(cartGoods.getProductMaterialList())) {
            Integer type1 = 1;
            Map<String, CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial> sChoices = find.getSmallMaterial()
                    .stream().filter(d -> type1.equals(d.getType()))
                    .collect(Collectors.toMap(CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial::getGoodsId, Function.identity(), (k1, k2) -> k1));

            for (CartGoods.MaterialGoods mg : cartGoods.getProductMaterialList()) {
                CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial sm = sChoices.get(mg.getSpuId());
                if (sm != null) {
                    mg.setAmount(sm.getRealAmount().longValue());
                }
            }
        }
        if (GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
            cartGoods.setOriginalAmount(originPrice);
        }

    }

    /**
     * 抽取满减的折扣金额 按货对应
     * 小料和可选搭配
     */
    public HashMap<String, Long> drawnFullDiscount(List<CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial> materialDiscount, List<Integer> typeEnums, Integer type) {
        HashMap<String, Long> hashMap = new HashMap<>();
        if (CollectionUtils.isEmpty(materialDiscount)) return hashMap;
        for (CalculationDiscountBO.CalculationDiscountResult.Goods.SmallMaterial smallMaterial : materialDiscount) {
            if (CollectionUtils.isEmpty(smallMaterial.getDiscounts()) && !type.equals(smallMaterial.getType()))
                continue;
            for (CalculationDiscountBO.CalculationDiscountResult.Goods.GoodsDiscount discount : smallMaterial.getDiscounts()) {
                if (typeEnums.contains(discount.getType())) {
                    Long aLong = hashMap.get(discount.getGoodsId()) == null ? 0L : hashMap.get(discount.getGoodsId());
                    hashMap.put(discount.getGoodsId(), aLong + discount.getDiscount());
                }
            }
        }
        return hashMap;
    }

    /**
     * 赠品detail
     *
     * @param discountResult
     */
    private List<ProductBO> drawGiftInfo(CalculationDiscountBO.CalculationDiscountResult discountResult, ListCartGoodsBO baseRequestDTO) {

        List<ProductBO> productBeanList = new ArrayList<>();
        List<String> gifts = this.getProductIdsForGift(discountResult);

        if (CollectionUtils.isEmpty(gifts)) return productBeanList;

        GetProductBO getProductBO = new GetProductBO();
        getProductBO.setGoodsId(gifts);
        getProductBO.setPartnerId(baseRequestDTO.getPartnerId());
        getProductBO.setStoreId(baseRequestDTO.getShopId());
        getProductBO.setMenuType(baseRequestDTO.getMenuType());
        List<ProductBO> productsInfo = productManager.getProductsInfo(getProductBO, baseRequestDTO.getManagerService().getProductService());

        return productsInfo;
    }

    /**
     * 抽取赠品
     * goodsId->goods
     *
     * @param discountResult
     * @return
     */
    private List<String> getProductIdsForGift(CalculationDiscountBO.CalculationDiscountResult discountResult) {

        List<String> gifts = new ArrayList<>();
        if (CollectionUtils.isEmpty(discountResult.getGoods())) {
            return gifts;
        }
        gifts = discountResult.getGoods()
                .stream()
                .filter(d -> CalculationGoodsType.TYPE_1.getType().equals(d.getCartGoodType()))
                .map(CalculationDiscountBO.CalculationDiscountResult.Goods::getGoodsId)
                .collect(Collectors.toList());
        return gifts;
    }

    public List<CartGoods> gifAddCart(List<ProductBO> products , CalculationDiscountBO.CalculationDiscountResult discountResult) {
        List<CartGoods> giftGoods = new ArrayList<>();
        Map<String, CalculationDiscountBO.CalculationDiscountResult.Goods> discountForGift = this.getDiscountForGift(discountResult);

        for (ProductBO product : products) {
            String k = product.getSpuId();
            CalculationDiscountBO.CalculationDiscountResult.Goods goods = discountForGift.get(k);
            CalculationDiscountBO.CalculationDiscountResult.Goods.GoodsDiscount discount = goods.getDiscounts()
                    .stream()
                    .filter(g -> ActivityTypeEnum.TYPE_63.getCode().equals(g.getType()) ||ActivityTypeEnum.TYPE_62.getCode().equals(g.getType()) || ActivityTypeEnum.TYPE_61.getCode().equals(g.getType()))
                    .findFirst()
                    .get();
            CartGoods cartGood = new CartGoods();
            cartGood.setGoodsId(goods.getGoodsId());
            cartGood.setGoodsType(1);
            cartGood.setSpuId(goods.getGoodsId());
            cartGood.setSkuId(goods.getGoodsId());
            cartGood.setOriginalPrice(product.getFinalPrice());
            cartGood.setPackPrice(product.getPackPrice());
            cartGood.setOriginalAmount(goods.getOriginalPrice() * goods.getGoodsQuantity());
            cartGood.setAmount(goods.getRealAmount());
            cartGood.setName(product.getName());
            cartGood.setSpuName(product.getName());
            cartGood.setCategoryName(product.getName());
            cartGood.setPic(product.getPicture());
            cartGood.setSkuName(product.getName());
            cartGood.setActivityType(discount.getType());
            cartGood.setStockLimit(ObjectUtils.equals(1, product.getStockLimit()));
            cartGood.setCustomerCode(product.getCustomerCode());
            cartGood.setUnit(product.getUnit());
            cartGood.setWeight(product.getWeight());
            cartGood.setQty(goods.getGoodsQuantity());
            cartGood.setClassificationId(product.getCategory());
            cartGood.setClassificationName(product.getCategoryName());
            // nodeId标识activeCode,用于计算均摊时每个商品在每个活动上均摊金额
            cartGood.setNodeId(discount.getActivityCode());
            giftGoods.add(cartGood);
        }
        return giftGoods;
    }

    public Map<String, CalculationDiscountBO.CalculationDiscountResult.Goods> getDiscountForGift(CalculationDiscountBO.CalculationDiscountResult discountResult) {

        Map<String, CalculationDiscountBO.CalculationDiscountResult.Goods> gifts = discountResult.getGoods()
                .stream()
                .filter(d -> CalculationGoodsType.TYPE_1.getType().equals(d.getCartGoodType()))
                .collect(Collectors.toMap(CalculationDiscountBO.CalculationDiscountResult.Goods::getGoodsId, Function.identity(), (k1, k2) -> k1));
        return gifts;
    }


    /**
     * 构建用户可以商品券信息
     *
     * @param discountResult
     * @return
     */
    private List<ChooseGoodsBO> buildSendGoods(CalculationDiscountBO.CalculationDiscountResult discountResult) {

        // 赠送、换购商品信息集合
        List<CalculationDiscountBO.CalculationDiscountResult.SendActivity> sendGoods = discountResult.getSendGoods();
        if (sendGoods == null || sendGoods.isEmpty()) {
            return null;
        }

        // 抽取买一赠一寄件活动送的商品
        List<CalculationDiscountBO.CalculationDiscountResult.SendActivity> buyOneGiveOneSendGoods = sendGoods
                .stream()
                .filter(sendGood -> ObjectUtils.equals(sendGood.getActivityType(), ActivityTypeEnum.TYPE_63.getCode()))
                .collect(Collectors.toList());

        if (null == buyOneGiveOneSendGoods || buyOneGiveOneSendGoods.isEmpty()) {
            return null;
        }

        List<ChooseGoodsBO> chooseGoods =  new ArrayList<>() ;
        buyOneGiveOneSendGoods.forEach(sendActivity -> {

            // 这个是真正的送的券
            List<CalculationDiscountBO.CalculationDiscountResult.SendActivity.SendGoods> innerSendGoods = sendActivity.getSendGoods();
            if (innerSendGoods == null || innerSendGoods.isEmpty()) {
                return;
            }

            innerSendGoods.forEach(innerSendGood -> {
                ChooseGoodsBO chooseGood = new ChooseGoodsBO();
                chooseGood.setActiveCode(sendActivity.getActivityCode());
                chooseGood.setActiveType(sendActivity.getActivityType());
                chooseGood.setGoodsId(innerSendGood.getGoodsId());
                chooseGood.setQty(innerSendGood.getSendNumber());
                chooseGood.setCouponQty(1);
                chooseGood.setCartGoodsUid(innerSendGood.getOriginalGoodsUid());
                chooseGood.setCouponCode(innerSendGood.getSendCouponCode());
                chooseGood.setCouponName(innerSendGood.getSendCouponName());
                chooseGood.setSendCoupon(innerSendGood.getSendCoupon());
                chooseGood.setGoodsName(innerSendGood.getGoodsName());
                chooseGoods.add(chooseGood);
            });

        });
        return chooseGoods;
    }


    private void convert2CartGoods(CartGoods cartGoods, GetProductsVo productInfo) {
        cartGoods.setCartGoodsUid(UUID.randomUUID().toString());
        Integer goodsType = GoodsTypeEnum.SPU_GOODS.getGoodsType();
        if (productInfo.getType() == null ||  productInfo.getType() == 1) {
            goodsType = GoodsTypeEnum.SPU_GOODS.getGoodsType();
        } else {
            goodsType = GoodsTypeEnum.SKU_GOODS.getGoodsType();
        }
        cartGoods.setGoodsType(goodsType);
        cartGoods.setAmount(productInfo.getFinalPrice());
        cartGoods.setCategoryName(productInfo.getCategoryName());
        cartGoods.setCustomerCode(productInfo.getCustomerCode());
        cartGoods.setFinalPrice(null);
        cartGoods.setGoodsId(cartGoods.getSkuId());
        cartGoods.setMaterialAmount(0l);
        cartGoods.setName(goodsType == GoodsTypeEnum.SPU_GOODS.getGoodsType() ? productInfo.getSpuName() : productInfo.getSkuName());
        cartGoods.setOriginalPrice(productInfo.getFinalPrice());
        cartGoods.setOriginalMaterialAmount(0l);
        cartGoods.setSpuId(productInfo.getSpuId());
        cartGoods.setSkuId(cartGoods.getSkuId());
        cartGoods.setSpuName(productInfo.getSpuName());
        cartGoods.setSkuName(productInfo.getSkuName());
        cartGoods.setCouponCode(null);

    }

}
