/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title:
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: ping.wu
 * @date: 2018/5/18 19:46
 * @version V1.0
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
package cn.freemud.service.impl;

import cn.freemud.adapter.ShoppingCartConvertAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.*;
import cn.freemud.service.thirdparty.*;
import cn.freemud.utils.PromotionFactory;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
import com.freemud.sdk.api.assortment.shoppingcart.request.CheckCartRequest;
import com.freemud.sdk.api.assortment.shoppingcart.service.ShoppingCartBaseService;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartMallBaseServiceImpl;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
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.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

@Slf4j
@Service
public class ShoppingCartMallServiceImpl implements ShoppingCartNewService {


    @Autowired
    private ItemService itemService;

    @Autowired
    private ShoppingCartMallBaseServiceImpl shoppingCartBaseService;
    @Autowired
    private BuriedPointService buriedPointService;
    @Autowired
    private StockClient stockClient;
    @Autowired
    private AssortmentSdkService assortmentSdkService;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;

    /**
     * 从微信卡券向购物车中添加商品
     */
    @Override
    public BaseResponse addGoodsByCard(AddGoodsByWeixinCardRequestVo request) {
        throw new UnsupportedOperationException("暂不支持此操作");
    }

    /**
     * 添加商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @return
     */
    @Override
    public BaseResponse addGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo) {
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(addShoppingCartGoodsRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = addShoppingCartGoodsRequestVo.getPartnerId();
        String appId = addShoppingCartGoodsRequestVo.getAppId();
        String spuId = addShoppingCartGoodsRequestVo.getSpuId();
        String skuId = addShoppingCartGoodsRequestVo.getSkuId();
        String goodsId = StringUtils.isEmpty(skuId) ? spuId : skuId;
        String storeId = this.getBindMallShopId(appId);
        addShoppingCartGoodsRequestVo.setShopId(storeId);

        /**
         * 不支持优惠券
         */
        if(spuId.startsWith(CommonsConstant.COUPON_PREFIX)) {
            return ResponseUtil.error(ResponseResult.COUPON_SHOP_NOTSUPPORT);
        }
        CartGoods cartGoods = ShoppingCartConvertAdapter.convent2CartGoods(addShoppingCartGoodsRequestVo);
        List<Long> productIds = Lists.newArrayList(Long.parseLong(goodsId));
        //商品skuId或者商品券的商品id
        String spuId2 = spuId;
        // 获取商品详细信息
        List<ProductBeanDTO> productBeanListSpuClass = assortmentSdkService.getProductsInfoSdk(partnerId, storeId, Collections.singletonList(spuId2),BusinessTypeEnum.SAAS_MALL.getName(), this.shoppingCartBaseService);
        //查询多个商品库存信息
        queryManyGoodsStocks(addShoppingCartGoodsRequestVo, productIds, productBeanListSpuClass, skuId);

        //缓存中获取购物车商品信息
        // 注意，围餐和点餐redis数据结构不一样
        List<CartGoods> allCartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, addShoppingCartGoodsRequestVo.getSessionId(), null, shoppingCartBaseService);
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            allCartGoodsList = new ArrayList<>();
        }

        String productName = null;
        //添加非商品券商品
        Map<String, List<CartGoods>> map = addNotProductGoods(addShoppingCartGoodsRequestVo, cartGoods, goodsId, userId, shoppingCartGoodsResponseVo, allCartGoodsList, productBeanListSpuClass);
        for (Map.Entry<String, List<CartGoods>> entry : map.entrySet()) {
            productName = entry.getKey();
            allCartGoodsList = entry.getValue();
        }

        // 当商品数量被设为0时
        if (Objects.equals(cartGoods.getQty(), 0)) {
            assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoods.getCartGoodsUid(), 0, "", shoppingCartBaseService);
        }
        // 促销活动的优惠金额计算
        updateShoppingCartGoodsDiscount(null, null, null, allCartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto);
        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, allCartGoodsList,null);

        //埋点添加购物车行为
        this.buriedPointShoppingCart(addShoppingCartGoodsRequestVo, spuId, productName);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }


    /**
     * 埋点添加购物车行为
     *
     * @param addShoppingCartGoodsRequestVo
     * @param spuId
     * @param productName
     */
    private void buriedPointShoppingCart(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, String spuId, String productName) {
        if (StringUtils.isEmpty(productName)) {
            return;
        }

        List<ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo> productVos = Lists.newArrayList();
        ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo productVo = new ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo();
        productVo.setProductName(productName);
        productVo.setProductId(spuId);
        productVo.setSpuId(spuId);
        productVos.add(productVo);
        BuriedPointShoppingCartRequestDto shoppingCartRequestDto = BuriedPointShoppingCartRequestDto.builder()
                .sessionId(addShoppingCartGoodsRequestVo.getSessionId()).partnerId(addShoppingCartGoodsRequestVo.getPartnerId())
                .storeId(addShoppingCartGoodsRequestVo.getShopId()).build();
        buriedPointService.buriedPointAddShoppingCart(productVos, shoppingCartRequestDto);
    }

    /**
     * 更新商品数量
     *
     * @param updateShoppingCartGoodsQtyRequestVo
     * @return
     */
    @Override
    public BaseResponse updateGoodsQty(UpdateShoppingCartGoodsQtyRequestVo updateShoppingCartGoodsQtyRequestVo) {
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(updateShoppingCartGoodsQtyRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = updateShoppingCartGoodsQtyRequestVo.getPartnerId();
        String appId = updateShoppingCartGoodsQtyRequestVo.getAppId();
        String storeId = this.getBindMallShopId(appId);
        updateShoppingCartGoodsQtyRequestVo.setShopId(storeId);
        String cartGoodsUid = updateShoppingCartGoodsQtyRequestVo.getCartGoodsUid();
        Integer qty = updateShoppingCartGoodsQtyRequestVo.getQty();
        // 先验证商品是否存在
        CartGoods cartGoods = assortmentSdkService.getCartGoodsBySdk(partnerId, userId, storeId, cartGoodsUid, "", shoppingCartBaseService);
        if (cartGoods == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
        }
        // 检查购物车商品库存数量
        checkUpdateStock(updateShoppingCartGoodsQtyRequestVo, cartGoods);

        // 更新购物车中数量
        List<CartGoods> cartGoodsList = assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoodsUid, qty, "", shoppingCartBaseService);

        // check购物车中所有商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, updateShoppingCartGoodsQtyRequestVo.getOrderType(), "", BusinessTypeEnum.SAAS_MALL.getName() ,shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);
        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, updateShoppingCartGoodsQtyRequestVo.getSessionId(), "", shoppingCartBaseService);

        // 促销活动的优惠金额计算
        updateShoppingCartGoodsDiscount(null, null, null, cartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto);
        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg());

        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * 检查购物车商品库存数量
     *
     * @param updateShoppingCartGoodsQtyRequestVo
     * @param cartGoods
     */
    private void checkUpdateStock(UpdateShoppingCartGoodsQtyRequestVo updateShoppingCartGoodsQtyRequestVo, CartGoods cartGoods) {
        Integer qty = updateShoppingCartGoodsQtyRequestVo.getQty();
        // 购物车商品数量减少
        if (cartGoods.getQty() > qty) {
            return;
        }
        String partnerId = updateShoppingCartGoodsQtyRequestVo.getPartnerId();
        String storeId = updateShoppingCartGoodsQtyRequestVo.getShopId();
        //查询商品信息
        List<String> pids = new ArrayList<>();
        pids.add(cartGoods.getGoodsId());
        Map<String, GetProductsVo> products = itemService.getProducts(pids, partnerId, storeId);

        GetProductsVo getProductsVo = products.get(cartGoods.getGoodsId());
        // 商品没有库存限制
        if ((getProductsVo == null) || (getProductsVo.getStockLimit() != 1)) {
            return;
        }
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel("saas");
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        requestDto.setProductIds(Collections.singletonList(Long.parseLong(cartGoods.getGoodsId())));
        GetProductStockResponseDto availableStocks = stockClient.getAvailableStocks(requestDto);
        if ((availableStocks != null) && (ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode()))) {
            if ((CollectionUtils.isEmpty(availableStocks.getResult())) || (qty > availableStocks.getResult().get(0).getQty())) {
                throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
            }
        }
    }


    /**
     * 购物车商品详情接口
     *
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @Override
    public BaseResponse getGoodsList(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(shoppingCartInfoRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String appId = shoppingCartInfoRequestVo.getAppId();
        String storeId = this.getBindMallShopId(appId);
        shoppingCartInfoRequestVo.setShopId(storeId);

        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, "", shoppingCartBaseService);
        if (cartGoodsList == null) {
            cartGoodsList = new ArrayList<>();
        }
        // check购物车中所有商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getOrderType(), "", BusinessTypeEnum.SAAS_MALL.getName() ,shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);
        //1.5.4 多规格的sku商品计算包装费
        //checkSkuOnVersion(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo);
        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService);

        // 促销活动的优惠金额计算
        this.updateShoppingCartGoodsDiscount(null, null, null, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto);
        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo,  cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg());

        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * svc 卡支付使用
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @Override
    public BaseResponse getGoodsListCheck(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        throw new UnsupportedOperationException("暂不支持此操作");
    }

    /**
     * 清空购物车
     *
     * @param shoppingCartClearRequestVo
     * @return
     */
    @Override
    public BaseResponse clear(ShoppingCartClearRequestVo shoppingCartClearRequestVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(shoppingCartClearRequestVo.getSessionId());
        String appId = shoppingCartClearRequestVo.getAppId();
        if (StringUtils.isBlank(appId)) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING, "appId不能为空");
        }

        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartClearRequestVo.getPartnerId();
        String storeId = this.getBindMallShopId(appId);
        shoppingCartClearRequestVo.setShopId(storeId);

        // 构造请求参数，进行清空购物车
        com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto cartParamDto = assortmentSdkService.getCartParamDto(partnerId, storeId, userId);
        shoppingCartBaseService.clear(cartParamDto, LogThreadLocal.getTrackingNo());

        // 支付成功回调不查询任何数据，直接返回成功结果
        if (ObjectUtils.equals(shoppingCartClearRequestVo.getOperationType(), OperationTypeEnum.PAY_SUCCESS.getOperationType())) {
            return ResponseUtil.success();
        }

        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        ActivityTip activityTip = new ActivityTip();
        shoppingCartGoodsResponseVo.setActivityTip(activityTip);
        shoppingCartGoodsResponseVo.setProducts(new ArrayList<>());
        shoppingCartGoodsResponseVo.setProductsCount(0);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * 供点单获取优惠均摊调用，传入的shopId为绑定商城的shopId
     */
    @Override
    public BaseResponse<ShoppingCartGoodsDto> getShoppingCartGoods(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo,
                                                                   CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity) {
        ShoppingCartGoodsDto shoppingCartGoodsDto = new ShoppingCartGoodsDto();
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(shoppingCartInfoRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String appId = shoppingCartInfoRequestVo.getAppId();
        String storeId = this.getBindMallShopId(appId);
        shoppingCartInfoRequestVo.setShopId(storeId);

        List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList = shoppingCartInfoRequestVo.getSendGoods();

        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, "", shoppingCartBaseService);
        if (cartGoodsList == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        // check购物车中所有商品(商品是否存在，价格变动，券是否支持当前点餐方式)
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getOrderType(), "", BusinessTypeEnum.SAAS_MALL.getName() ,shoppingCartBaseService);
        com.freemud.sdk.api.assortment.shoppingcart.domain.ShoppingCartGoodsResponseVo cartGoodsResponseVo = checkCartRequest.getShoppingCartGoodsResponseVo();
        //商品不再售卖状态或价格变动，直接返回报错
        if (cartGoodsResponseVo != null) {
            if (cartGoodsResponseVo.getCartGoodsStates() != null && cartGoodsResponseVo.getCartGoodsStates().isHasInvalidGoods()) {
                return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_INVAILD);
            }
            if (cartGoodsResponseVo.getCartGoodsStates() != null && cartGoodsResponseVo.getCartGoodsStates().isPriceChanged()) {
                return ResponseUtil.error(ResponseResult.SHOPPING_CART_ACTIVITY_CHANGE);
            }
            shoppingCartGoodsResponseVo.setToastMsg(cartGoodsResponseVo.getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

        // 多规格的sku商品计算包装费
        //this.checkSkuOnVersion(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo);
        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService);

        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            processSendGoods(sendGoodsList, partnerId, storeId,BusinessTypeEnum.SAAS_MALL.getName(), shoppingCartBaseService);
        } else {
            //组装加价购商品
            if (null != premiumExchangeActivity && CollectionUtils.isNotEmpty(premiumExchangeActivity.getProducts())) {
                List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = premiumExchangeActivity.getProducts().stream().map(product -> {
                    ShoppingCartInfoRequestVo.SendGoods sendGood = new ShoppingCartInfoRequestVo.SendGoods();
                    sendGood.setGoodsId(product.getSkuId());
                    sendGood.setQty(product.getQty());
                    return sendGood;
                }).collect(toList());
                shoppingCartInfoRequestVo.setSendGoods(sendGoods);
            }
        }
        // 促销活动的优惠金额计算
        updateShoppingCartGoodsDiscount(null, null, null, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto);

        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg());
        //设置均摊信息
        updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, null, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        return ResponseUtil.success(shoppingCartGoodsDto);
    }

    @Override
    public ActivityCalculationDiscountResponseDto.CalculationDiscountResult getActivityCalculationDiscountResponse(
            String partnerId, String storeId, String userId, String appId, Integer orderType, List<CartGoods> cartGoodsList,
            List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons, List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList) {
        return null;
    }


    /**
     * 处理加价购商品
     *
     * @param sendGoodsList
     * @param partnerId
     * @param storeId
     */
    private void processSendGoods(List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList, String partnerId, String storeId,String menuType, ShoppingCartBaseService shoppingCartService) {
        List<String> goodsIds = sendGoodsList.parallelStream().map(ShoppingCartInfoRequestVo.SendGoods::getGoodsId).collect(Collectors.toList());
        List<ProductBeanDTO> productBeanList =
                assortmentSdkService.getProductsInfoSdk(partnerId, storeId, goodsIds,menuType, shoppingCartService);
        // 将productBeanList转换为Map，key为pid，即goodsId
        Map<String, ProductBeanDTO> productBeanMap = productBeanList.parallelStream()
                .collect(Collectors.toMap(ProductBeanDTO::getPid, Function.identity(), (k1, k2) -> k1));
        // 遍历购物车进行加个更新
        for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
            ProductBeanDTO productBean;
            if ((productBean = productBeanMap.get(sendGoods.getGoodsId())) != null) {
                // 设置加价购商品原价
                sendGoods.setOriginalPrice(productBean.getOriginalPrice());
            } else {
                throw new ServiceException(ResponseResult.SHOPPING_CART_SENDGOODS_NOT_EXIST);
            }
        }

    }


    /**
     * 当ToastMsg为空时才赋值
     *
     * @param shoppingCartGoodsResponseVo
     * @param message
     */
    private void setToastMsgIfNotExist(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String message) {
        if (StringUtils.isEmpty(shoppingCartGoodsResponseVo.getToastMsg())) {
            shoppingCartGoodsResponseVo.setToastMsg(message);
        }
    }

    @Data
    static class CartGoodsStates {
        /**
         * 价格变化
         */
        boolean priceChanged;
        /**
         * 非法商品
         */
        boolean hasInvalidGoods;
        /**
         * 点餐方式
         */
        boolean orderWayFlag;

    }

    /**
     * 促销活动的优惠金额计算
     *
     * @param calculationDiscountResult
     * @param cartGoodsList
     * @param shoppingCartGoodsResponseVo
     */
    private void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, UserLoginInfoDto userLoginInfoDto) {

        //默认计算优惠
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        //套餐
        SetMealServiceImpl setMealService = (SetMealServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.SET_MEAL);
        setMealService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

    }

    /**
     * 促销均摊计算
     *
     * @param shoppingCartGoodsResponseVo
     * @param calculationDiscountResult
     * @param shoppingCartGoodsDto
     * @param premiumExchangeActivity
     * @param shoppingCartInfoRequestVo
     */
    private void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //套餐
        SetMealServiceImpl setMealService = (SetMealServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.SET_MEAL);
        setMealService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);
    }

    /**
     * 获取购物车商品,添加商品,校验商品合法性,合并商品行,重新set购物车信息到缓存中
     *
     * @param cartGoods
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param addShoppingCartGoodsRequestVo
     */
    @Override
    public List<CartGoods> updateCartGoodsLegal(CartGoods cartGoods, String userId, ShoppingCartGoodsBaseResponseVo shoppingCartGoodsResponseVo, AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<CartGoods> oldAllCartGoodsList) {
        //存储新添加的购物车信息
        List<CartGoods> nowCartGoodsList = new ArrayList<>();
        oldAllCartGoodsList.add(cartGoods);

        //当商品全部添加完毕,校验购物车商品(是否合法,上下架,点餐方式,是否在当前菜单中...),并移除非法商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(oldAllCartGoodsList, addShoppingCartGoodsRequestVo.getPartnerId(),
                addShoppingCartGoodsRequestVo.getShopId(), shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo.getOrderType(), "",BusinessTypeEnum.SAAS_MALL.getName(), shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
        }
        List<CartGoods> allCartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

        //判断当前商品在购物车是否已存在,存在则数量＋添加的数量,不存在商品行 + 添加的数量
        allCartGoodsList.forEach(oldCartGoods -> {
            int index;
            if ((index = nowCartGoodsList.indexOf(oldCartGoods)) >= 0) {
                nowCartGoodsList.get(index).setQty(nowCartGoodsList.get(index).getQty() + oldCartGoods.getQty());
            } else {
                nowCartGoodsList.add(oldCartGoods);
            }
        });
        // 重新set购物车信息到缓存中
        assortmentSdkService.setShoppingCart(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(),
                userId, nowCartGoodsList, addShoppingCartGoodsRequestVo.getSessionId(), addShoppingCartGoodsRequestVo.getTableNumber(), this.shoppingCartBaseService);
        return nowCartGoodsList;
    }

    /**
     * 添加非商品券商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @param cartGoods
     * @param goodsId
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param allCartGoodsList
     * @param productBeanListSpuClass
     */
    private Map<String, List<CartGoods>> addNotProductGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, CartGoods cartGoods
            , String goodsId, String userId, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, List<CartGoods> allCartGoodsList
            , List<ProductBeanDTO> productBeanListSpuClass) {

        //校验合法性,更新缓存中购物车信息
        allCartGoodsList = updateCartGoodsLegal(cartGoods, userId, shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo, allCartGoodsList);

        // 如果购物车中有商品券，则当前添加的商品是特价商品时，需要提示“已选商品券，与其他优惠商品不同享，商品将恢复原价”
        boolean haveCouponProduct = allCartGoodsList.parallelStream().anyMatch(k -> k.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX));
        if (haveCouponProduct && isSpecialGoods(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(), userId, addShoppingCartGoodsRequestVo.getAppId(), goodsId, addShoppingCartGoodsRequestVo.getOrderType())) {
            // 如果购物车先加入商品券，再加入促销商品，toast提示“已选商品券，与其他优惠商品不同享，商品将恢复原价”
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, ShoppingCartConstant.HAS_GOODS_COUPON_WHEN_ADD_SPECIAL_GOODS);
        }

        Map<String, List<CartGoods>> map = new HashMap<>();
        map.put(productBeanListSpuClass.get(0).getName(), allCartGoodsList);
        return map;
    }


    /**
     * 查询多个商品库存信息
     *
     * @param addShoppingCartGoodsRequestVo
     * @param productIds
     * @param productBeanListSpuClass
     * @param skuId
     */
    private void queryManyGoodsStocks(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<Long> productIds
            , List<ProductBeanDTO> productBeanListSpuClass, String skuId) {
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel("saas");
        requestDto.setPartnerId(addShoppingCartGoodsRequestVo.getPartnerId());
        requestDto.setStoreId(addShoppingCartGoodsRequestVo.getShopId());
        requestDto.setProductIds(productIds);
        GetProductStockResponseDto availableStocks = null;
        if (productBeanListSpuClass.get(0).getType() == ProductType.NOSPEC.getCode()
                && productBeanListSpuClass.get(0).getStockLimit() == 1) {
            availableStocks = stockClient.getAvailableStocks(requestDto);
        } else {
            for (ProductBeanDTO.SkuProductBean skuProductBean : productBeanListSpuClass.get(0).getSkuList()) {
                if (skuId.equals(skuProductBean.getSkuId()) && skuProductBean.getStockLimit() == 1) {
                    availableStocks = stockClient.getAvailableStocks(requestDto);
                    break;
                }
            }
        }
        if (availableStocks != null && !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
        if (availableStocks != null && ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode()) &&
                (CollectionUtils.isEmpty(availableStocks.getResult()) || availableStocks.getResult().get(0).getQty() == null
                        || availableStocks.getResult().get(0).getQty() <= 0)) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
    }

    /**
     * 组装添加商品和更新商品和查询的响应信息
     * <p>
     * 查询购物车计算包装费
     *
     * @param shoppingCartGoodsResponseVo
     * @param cartGoodsList
     * @param toastMsg
     */
    private void setAddAndUpdateResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, List<CartGoods> cartGoodsList, String toastMsg) {
        shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        shoppingCartGoodsResponseVo.setProductsCount(cartGoodsList.size());
        if (StringUtils.isNotEmpty(toastMsg)) {
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, toastMsg);
        }
        shoppingCartGoodsResponseVo.setChanged(false);
    }


    private UserLoginInfoDto convert2UserLoginInfoDto(AssortmentCustomerInfoVo assortmentCustomerInfoVo) {
        if (assortmentCustomerInfoVo == null || assortmentCustomerInfoVo.getMemberId() == null) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        UserLoginInfoDto userLoginInfoDto = new UserLoginInfoDto();
        userLoginInfoDto.setMemberId(assortmentCustomerInfoVo.getMemberId());
        userLoginInfoDto.setOpenId(assortmentCustomerInfoVo.getOpenId());
        userLoginInfoDto.setWxAppid(assortmentCustomerInfoVo.getWxAppId());
        userLoginInfoDto.setSessionKey(assortmentCustomerInfoVo.getSessionKey());
        userLoginInfoDto.setMobile(assortmentCustomerInfoVo.getMobile());
        userLoginInfoDto.setAppsecret(assortmentCustomerInfoVo.getAppSecret());
        userLoginInfoDto.setPartnerId(assortmentCustomerInfoVo.getPartnerId());
        userLoginInfoDto.setNewMemeber(assortmentCustomerInfoVo.getNewMember());
        userLoginInfoDto.setUnionId(assortmentCustomerInfoVo.getUnionId());

        return userLoginInfoDto;
    }

    /**
     * 获取商城门店id
     */
    private String getBindMallShopId(String wxAppId) {
        String shopId = shoppingCartBaseService.getBindMallShopId(wxAppId, LogThreadLocal.getTrackingNo());
        if(StringUtils.isEmpty(shopId)) {
            throw new ServiceException(ResponseResult.STORE_MALL_NOT_FOUND);
        }
        return shopId;
    }

}
