package com.freemud.sdk.api.assortment.shoppingcart.service;

import ch.qos.logback.classic.Level;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.redis.RedisCache;
import com.alibaba.fastjson.JSON;
import com.freemud.application.sdk.api.base.SDKCommonBaseContextWare;
import com.freemud.application.sdk.api.constant.ResponseResultEnum;
import com.freemud.application.sdk.api.couponcenter.online.domain.*;
import com.freemud.application.sdk.api.couponcenter.online.request.CouponDetailRequest;
import com.freemud.application.sdk.api.couponcenter.online.request.PartnerRequest;
import com.freemud.application.sdk.api.couponcenter.online.response.CouponDetailResponse;
import com.freemud.application.sdk.api.couponcenter.online.service.FMActiveSdkService;
import com.freemud.application.sdk.api.couponcenter.online.service.OnlineCouponSdkService;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.application.sdk.api.productcenter.domain.ProductInfosDTO;
import com.freemud.application.sdk.api.productcenter.request.menu.GetMenuCategoryByIdsRequest;
import com.freemud.application.sdk.api.productcenter.request.product.GetProductRequest;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ProductAttributeValueType;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductRequest;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductType;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateSkuProductType;
import com.freemud.application.sdk.api.productcenter.response.menu.GetMenuCategoryByIdsResponse;
import com.freemud.application.sdk.api.productcenter.response.valid.ValiadShopProductResponse;
import com.freemud.application.sdk.api.productcenter.response.valid.ValiadShopProductResult;
import com.freemud.application.sdk.api.productcenter.service.MenuService;
import com.freemud.application.sdk.api.productcenter.service.ProductService;
import com.freemud.application.sdk.api.storecenter.request.vo.GetOrgTreeListRequest;
import com.freemud.application.sdk.api.storecenter.response.vo.GetOrgTreeListResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.shoppingcart.adapter.ShoppingCartAdapter;
import com.freemud.sdk.api.assortment.shoppingcart.constant.*;
import com.freemud.sdk.api.assortment.shoppingcart.domain.*;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import com.freemud.sdk.api.assortment.shoppingcart.request.CheckCartRequest;
import com.freemud.sdk.api.assortment.shoppingcart.request.GetProductInfoRequest;
import com.freemud.sdk.api.assortment.shoppingcart.util.CartResponseUtil;
import com.freemud.sdk.api.assortment.shoppingcart.util.DateTimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

import static com.freemud.sdk.api.assortment.shoppingcart.constant.ShoppingCartConstant.*;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: ShoppingCartBaseService
 * @Package cn.freemud.service
 * @Description:
 * @author: liming.guo
 * @date: 2018/6/28 19:47
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public interface ShoppingCartBaseService {

    /**
     * 查询购物车详情
     */
    BaseResponse<List<CartAddItem>> detailCart(CartParamDto cartParamDto, String trackingNo);

    /**
     * 获取购物车商品行集合
     *
     * @param cartParamDto
     * @return
     */
    BaseResponse<List<CartGoods>> getCartGoodsList(CartParamDto cartParamDto, String trackingNo);

    /**
     * 设置购物车商品行集合信息
     *
     * @param cartParamDto
     * @return
     */
    BaseResponse<List<CartGoods>> setCartGoodsList(CartParamDto cartParamDto, String trackingNo);

    /**
     * 设置购物车代金券信息
     *
     * @param cartParamDto
     * @return
     */
    default BaseResponse<String> setCartCouponCode(CartParamDto cartParamDto, String trackingNo) {
        return null;
    }

    default boolean addCartGoodList(CartParamDto cartParamDto) {
        return true;
    }

    /**
     * 清除购物车商品行信息
     *
     * @param cartParamDto
     */
    BaseResponse clear(CartParamDto cartParamDto, String trackingNo);


    /**
     * 获取购物车商品代金券
     *
     * @param cartParamDto
     * @return
     */
    default BaseResponse<String> getCartCouponCode(CartParamDto cartParamDto, String trackingNo) {
        return null;
    }

    /**
     * 清除麦咖啡购物车商品行信息
     *
     * @param cartParamDto
     */
    default BaseResponse clearMCCafe(CartParamDto cartParamDto, String trackingNo) {
        return null;
    }
    /**
     * 获取商品详细信息
     *
     * @param getProductInfoRequest
     * @return
     */
    default BaseResponse<List<ProductBeanDTO>> getProductsInfo(GetProductInfoRequest getProductInfoRequest) {
        try {
            List<String> goodsIds = getProductInfoRequest.getGoodsIds();
            if (CollectionUtils.isEmpty(goodsIds)) {
                return CartResponseUtil.error("goodsIds为空");
            }

            //移除空的goodsId及spq的商品券
            goodsIds = goodsIds.parallelStream().filter(StringUtils::isNotEmpty).filter(goodsId -> !goodsId.startsWith(CommonsConstant.COUPON_PREFIX)).collect(Collectors.toList());

            GetProductRequest getProductInfoDto = new GetProductRequest();
            getProductInfoDto.setPartnerId(getProductInfoRequest.getPartnerId());
            getProductInfoDto.setShopId(getProductInfoRequest.getStoreId());
            getProductInfoDto.setProductInfoType(2);
            getProductInfoDto.setProductIds(goodsIds);
            getProductInfoDto.setChannel(getProductInfoRequest.getMenuType());
            ProductService productService = SDKCommonBaseContextWare.getBean(ProductService.class);
            com.freemud.application.sdk.api.base.BaseResponse<ProductInfosDTO> productInfosDTOBaseResponse = productService.listProductInfoByIdList(getProductInfoDto, LogThreadLocal.getTrackingNo());
            if (!Objects.equals(ResponseResultEnum.SUCCESS.getCode(), productInfosDTOBaseResponse.getCode()) || productInfosDTOBaseResponse.getData() == null) {
                return CartResponseUtil.error(productInfosDTOBaseResponse.getMessage());
            }
            return CartResponseUtil.success(productInfosDTOBaseResponse.getData().getProducts());
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", getProductInfoRequest.getTrackingNo(), e.getMessage(), "getProductsInfo", getProductInfoRequest, e, Level.ERROR);
            return null;
        }
    }


    default BaseResponse<CheckCartRequest> checkAllCartGoodsNew(CheckCartRequest checkCartRequest) {
        ShoppingCartAdapter shoppingCartAdapter = SDKCommonBaseContextWare.getBean(ShoppingCartAdapter.class);
        ProductService productService = SDKCommonBaseContextWare.getBean(ProductService.class);
        try {
            ValidateShopProductRequest validateShopProductRequest = shoppingCartAdapter.getValidateShopProductRequest(checkCartRequest);
            com.freemud.application.sdk.api.base.BaseResponse<ValiadShopProductResponse> valiadResponse = productService.validateShopProduct(validateShopProductRequest);
            if (valiadResponse == null || !CartResponseConstant.SUCCESS.getCode().equals(valiadResponse.getCode()) || valiadResponse.getData()==null) {
                checkCartRequest.getCartGoodsList().clear();
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
                return CartResponseUtil.error(valiadResponse.getMessage(),checkCartRequest);
            }
            ValiadShopProductResponse valiadResult = valiadResponse.getData();
            //非法商品（商品是否存在、商品是否处于上架状态）自动移除，返回前端提示
            if (CollectionUtils.isNotEmpty(valiadResult.getFailureList())){
                setToastMsgIfNotExist(checkCartRequest.getShoppingCartGoodsResponseVo(), ShoppingCartConstant.SHOPPING_CART_GOODS_CHANGE);
                for (CartGoods cartGoods :checkCartRequest.getCartGoodsList()) {
                    if (valiadResult.getFailureList().stream().anyMatch(f->cartGoods.getCartGoodsUid().equals(f.getUuid()))){
                        cartGoods.setCartGoodsUid(null);
                        checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                        checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
                    }
                }
                checkCartRequest.getCartGoodsList().removeIf(k ->  StringUtils.isEmpty(k.getCartGoodsUid()));
            }
            // Todo : 验证的商品信息
            List<ProductBeanDTO> productList = valiadResult.getSuccessList().stream().map(ValiadShopProductResult::getProductType).collect(Collectors.toList());
            CartGoodsStates cartGoodsStates = new CartGoodsStates();
            for (CartGoods cartGoods : checkCartRequest.getCartGoodsList()) {
                // 当goodsId为空或商品是商品券时直接跳过
                if (StringUtils.isEmpty(cartGoods.getGoodsId()) || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.COUPON_GOODS.getGoodsType()) || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType())) {
                    continue;
                }
                shoppingCartAdapter.updateCartGoodsInfoNew(cartGoods, productList);
            }
            //校验商品券是否有当前点餐方式
            cartGoodsStates = updateSpqCartGoodsInfo(checkCartRequest.getCartGoodsList(), checkCartRequest.getOrderWay(), checkCartRequest.getPartnerId(), checkCartRequest.getTrackingNo(), cartGoodsStates
                    , checkCartRequest.getStoreId());

            // 点餐方式改变商品券发生变动
            if (cartGoodsStates != null && cartGoodsStates.isOrderWayFlag()) {
                setToastMsgIfNotExist(checkCartRequest.getShoppingCartGoodsResponseVo(), ShoppingCartConstant.ORDER_WAY_CHANGE);
            }
            //若商品详情赋值有异常，直接移除购物车
            if (checkCartRequest.getCartGoodsList().stream().anyMatch(cart -> StringUtils.isEmpty(cart.getCartGoodsUid()))) {
                checkCartRequest.getCartGoodsList().removeIf(k -> StringUtils.isEmpty(k.getCartGoodsUid()));
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
            }
            //todo 小料
            if (checkCartRequest.getCartGoodsList().stream().anyMatch(cart -> cart.getGoodsType().equals(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType()))) {
                checkCartRequest.getCartGoodsList().removeIf(k -> k.getGoodsType().equals(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType()));
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_MATERIAL_ERROR);
            }
            return CartResponseUtil.success(checkCartRequest);
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", checkCartRequest.getTrackingNo(), e.getMessage(), "checkAllCartGoods", checkCartRequest, e, Level.ERROR);
            checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
            checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
            return CartResponseUtil.error(e.getMessage(),checkCartRequest);
        }
    }

    default BaseResponse<CheckCartRequest> checkAllCartGoodsForMCoffee(CheckCartRequest checkCartRequest) {
        ShoppingCartAdapter shoppingCartAdapter = SDKCommonBaseContextWare.getBean(ShoppingCartAdapter.class);
        ProductService productService = SDKCommonBaseContextWare.getBean(ProductService.class);
        try {
            ValidateShopProductRequest validateShopProductRequest = shoppingCartAdapter.getValidateShopProductRequest(checkCartRequest);
            com.freemud.application.sdk.api.base.BaseResponse<ValiadShopProductResponse> valiadResponse = productService.validateShopProductAboutReason(validateShopProductRequest);

            if (valiadResponse == null || !CartResponseConstant.SUCCESS.getCode().equals(valiadResponse.getCode()) || valiadResponse.getData()==null) {
                checkCartRequest.getCartGoodsList().clear();
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
                return CartResponseUtil.error(valiadResponse.getMessage(),checkCartRequest);
            }
            ValiadShopProductResponse validateResult = valiadResponse.getData();
            CartGoodsStates cartGoodsStates = new CartGoodsStates();

            //非法商品（商品是否存在、商品是否处于上架状态）自动移除，返回前端提示
            if (CollectionUtils.isNotEmpty(validateResult.getFailureList())){
                List<String> invalidSpu = new ArrayList<>();
                List<String> notFoundSpu = new ArrayList<>();
                List<String> changePriceSpu = new ArrayList<>();
                for (int i = 0; i < validateResult.getFailureList().size(); i++) {
                    ValiadShopProductResult validaProduct = validateResult.getFailureList().get(i);
                    for (CartGoods cartGoods : checkCartRequest.getCartGoodsList()) {
                        checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                        if (cartGoods.getSkuId().equals(validaProduct.getSkuId())) {
                            String spuName = null == validaProduct.getProductType() ? (StringUtils.isNotEmpty(cartGoods.getSkuName()) ? cartGoods.getSkuName() :
                                            StringUtils.isNotEmpty(cartGoods.getName()) ? cartGoods.getName() : "") : validaProduct.getProductType().getName();
                            if (PRODUCT_DOWN == validaProduct.getCode()) {
                                if (StringUtils.isNotEmpty(spuName)){
                                    invalidSpu.add(spuName);
                                }
                                cartGoodsStates.setHasInvalidGoods(true);
                                cartGoods.setCartGoodsUid(null);
                                break;
                            }
                            if (PRODUCT_NOTFOUND == validaProduct.getCode()) {
                                if (StringUtils.isNotEmpty(spuName)) {
                                    notFoundSpu.add(spuName);
                                }
                                cartGoodsStates.setHasInvalidGoods(true);
                                cartGoods.setCartGoodsUid(null);
                                break;
                            }
                            if (PRODUCT_PRICE_CHANGE == validaProduct.getCode()) {
                                if (StringUtils.isNotEmpty(spuName)) {
                                    changePriceSpu.add(spuName);
                                }
                                List<ProductBeanDTO> productList = validateResult.getFailureList().stream().filter(f-> f.getCode() == PRODUCT_PRICE_CHANGE).map(ValiadShopProductResult::getProductType).collect(Collectors.toList());

                                shoppingCartAdapter.updateCartGoodsInfoNew(cartGoods, productList);
                                break;
                            }
                        }
                    }
                }

                String toastMsg = "";
                if (CollectionUtils.isNotEmpty(invalidSpu)){
                    toastMsg = toastMsg.concat(CART_PRODUCT_INVALID_STATE.replace("$spuName",StringUtils.join(invalidSpu,",")));
                }
                if (CollectionUtils.isNotEmpty(notFoundSpu)){
                    toastMsg = toastMsg.concat(CART_PRODUCT_NOT_FOUND.replace("$spuName",StringUtils.join(notFoundSpu,",")));
                }

                if (CollectionUtils.isNotEmpty(changePriceSpu)){
                    toastMsg = toastMsg.concat(CART_PRODUCT_PRICE_CHANGE.replace("$spuName",StringUtils.join(changePriceSpu,",")));
                }
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(toastMsg);

                setToastMsgIfNotExist(checkCartRequest.getShoppingCartGoodsResponseVo(), ShoppingCartConstant.SHOPPING_CART_GOODS_CHANGE);
                checkCartRequest.getCartGoodsList().removeIf(k ->  StringUtils.isEmpty(k.getCartGoodsUid()));
            }
            List<ProductBeanDTO> productList = validateResult.getSuccessList().stream().map(ValiadShopProductResult::getProductType).collect(Collectors.toList());

            for (CartGoods cartGoods : checkCartRequest.getCartGoodsList()) {
                // 当goodsId为空或商品是商品券时直接跳过
                if (StringUtils.isEmpty(cartGoods.getGoodsId()) || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.COUPON_GOODS.getGoodsType())) {
                    continue;
                }
                shoppingCartAdapter.updateCartGoodsInfoNew(cartGoods, productList);
            }
            //校验商品券是否有当前点餐方式
            cartGoodsStates = updateSpqCartGoodsInfo(checkCartRequest.getCartGoodsList(), checkCartRequest.getOrderWay(), checkCartRequest.getPartnerId(), checkCartRequest.getTrackingNo(), cartGoodsStates
                    , checkCartRequest.getStoreId());

            // 点餐方式改变商品券发生变动
            if (cartGoodsStates != null && cartGoodsStates.isOrderWayFlag()) {
                setToastMsgIfNotExist(checkCartRequest.getShoppingCartGoodsResponseVo(), ShoppingCartConstant.ORDER_WAY_CHANGE);
            }
            //若商品详情赋值有异常，直接移除购物车
            if (checkCartRequest.getCartGoodsList().stream().anyMatch(cart -> StringUtils.isEmpty(cart.getCartGoodsUid()))) {
                checkCartRequest.getCartGoodsList().removeIf(k -> StringUtils.isEmpty(k.getCartGoodsUid()));
                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
            }
//            if (checkCartRequest.getCartGoodsList().stream().anyMatch(cart -> cart.getGoodsType().equals(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType()))) {
//                checkCartRequest.getCartGoodsList().removeIf(k -> k.getGoodsType().equals(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType()));
//                checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
//                checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_MATERIAL_ERROR);
//            }
            return CartResponseUtil.success(checkCartRequest);
        } catch (Exception e) {
            ErrorLog.printErrorLog("assortment-shoppingcart-sdk", checkCartRequest.getTrackingNo(), e.getMessage(), "checkAllCartGoods", checkCartRequest, e, Level.ERROR);
            checkCartRequest.getShoppingCartGoodsResponseVo().setChanged(true);
            checkCartRequest.getShoppingCartGoodsResponseVo().setToastMsg(ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS);
            return CartResponseUtil.error(e.getMessage(),checkCartRequest);
        }
    }

    /**
     * 更新购物车详细信息
     * 并check购物车中商品是否价格变更、是否非法（例如商品下架）
     * 若购物车中商品非法，自动移除当前商品行
     *
     * @param checkCartRequest
     * @param cartGoodsStates
     */
    default void getProductInfoAndVerifyNew(CheckCartRequest checkCartRequest, CartGoodsStates cartGoodsStates) {
        if (CollectionUtils.isEmpty(checkCartRequest.getCartGoodsList())) {
            return;
        }
        // 获取购物车中所有的商品详情
        // 包含：1、普通商品 2、套餐内的固定商品和可选商品
        ShoppingCartAdapter shoppingCartAdapter = SDKCommonBaseContextWare.getBean(ShoppingCartAdapter.class);
        GetProductInfoRequest getSpuProductInfoRequest = shoppingCartAdapter.convertGetProductInfoRequest(checkCartRequest);
        getSpuProductInfoRequest.setMenuType(checkCartRequest.getMenuType());
        BaseResponse<List<ProductBeanDTO>> productInfo = getProductsInfo(getSpuProductInfoRequest);
        if ((productInfo == null) || (!CartResponseConstant.SUCCESS.getCode().equals(productInfo.getCode()))) {
            return;
        }
        //更新购物车详细信息
        updateCartGoodsListInfoNew(checkCartRequest.getCartGoodsList(), productInfo.getResult(), cartGoodsStates, checkCartRequest.getPartnerId(), checkCartRequest.getStoreId(), checkCartRequest.getTableNumber());
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = checkCartRequest.getShoppingCartGoodsResponseVo();
        // 有非法商品
        if (cartGoodsStates.isHasInvalidGoods()) {
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, ShoppingCartConstant.SHOPPING_CART_INVALID_GOODS_EXIST);
        }
        // 价格发生变化时返回
        if (cartGoodsStates.isPriceChanged()) {
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, ShoppingCartConstant.SHOPPING_CART_ACTIVITY_CHANGE);
        }
        checkCartRequest.setShoppingCartGoodsResponseVo(shoppingCartGoodsResponseVo);
    }

    /**
     * 根据点餐方式、校验商品券是否满足
     *
     * @param cartGoodsList
     * @param orderWay
     * @return
     */
    default CartGoodsStates updateSpqCartGoodsInfo(List<CartGoods> cartGoodsList, Integer orderWay, String partnerId,String trackingNo, CartGoodsStates goodsStates, String storeId) {
        //获取所有商品券cartGoodsUid=sqp+code
        List<String> couponIds = cartGoodsList.parallelStream()
                .filter(k ->StringUtils.isNotEmpty(k.getCartGoodsUid())&& k.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)).map(CartGoods::getSpuId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(couponIds)) {
            return goodsStates;
        }
        List<DetailVO> detailVOList = getCouponsDetail(partnerId, storeId, couponIds, trackingNo);
        if (CollectionUtils.isEmpty(detailVOList)) {
            return goodsStates;
        }

        Map<String, DetailVO> detailsMap;
        List<String> activityCode;
        Map<String, Boolean> couponOrderWayMap;

        detailsMap = detailVOList.stream().collect(Collectors.toMap(p -> p.getCode(), (p) -> p));
        activityCode = detailVOList.stream().map(p -> p.getActiveCode()).collect(Collectors.toList());
        couponOrderWayMap = getCouponOrderWay(partnerId, activityCode, orderWay, trackingNo);
        //遍历商品券是否有当前点餐方式点餐
        boolean orderWayFlag = false;
        if (CollectionUtils.isNotEmpty(cartGoodsList)) {
            orderWayFlag = checkProductOrderWay(cartGoodsList, detailsMap, couponOrderWayMap);
        }
        if (orderWayFlag) {
            goodsStates.setOrderWayFlag(true);
            cartGoodsList.removeIf(k -> k.getCartGoodsUid() == null);
        }
        return goodsStates;
    }

    /**
     * 商品券是否有当前点餐方式点餐
     *
     * @param cartGoodsList
     * @param detailsMap
     * @param couponOrderWayMap
     * @return
     */
    default boolean checkProductOrderWay(List<CartGoods> cartGoodsList, Map<String, DetailVO> detailsMap, Map<String, Boolean> couponOrderWayMap) {
        boolean orderWayFlag = false;
        List<CartGoods> cartGoodsByProduct = cartGoodsList.stream()
                .filter(cartGoods -> cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX))
                .collect(Collectors.toList());
        for (CartGoods cartGoods : cartGoodsByProduct) {
            DetailVO detail = detailsMap.get(cartGoods.getSpuId());
            String activeCode = detail != null ? detail.getActiveCode() : "";
            if (couponOrderWayMap == null || couponOrderWayMap.isEmpty() || !couponOrderWayMap.get(activeCode)) {
                orderWayFlag = true;
                cartGoods.setCartGoodsUid(null);
            }
        }

        return orderWayFlag;
    }


    /**
     * 修正购物车中的商品信息
     *
     * @param cartGoodsList   购物车list
     * @param productBeans    购物车中所有的商品详情，包含套餐内的固定商品和可选商品
     * @param cartGoodsStates 购物车状态
     */
    default void updateCartGoodsListInfoNew(List<CartGoods> cartGoodsList, List<ProductBeanDTO> productBeans, CartGoodsStates cartGoodsStates, String partnerId, String storeId, String tableNumber) {
        if ((cartGoodsList == null) || (productBeans == null)) {
            return;
        }
        // 将productBeanList转换为Map，key为pid，即goodsId
        Map<String, ProductBeanDTO> productBeanMap = productBeans.parallelStream().collect(Collectors.toMap(ProductBeanDTO::getPid, Function.identity(), (k1, k2) -> k1));
        List<String> invalidGoodsIdList = new ArrayList<>();
        for (CartGoods cartGoods : cartGoodsList) {
            // 当goodsId为空或商品是商品券时直接跳过
            if (StringUtils.isEmpty(cartGoods.getGoodsId()) || Objects.equals(cartGoods.getGoodsType(), GoodsTypeEnum.COUPON_GOODS.getGoodsType())) {
                continue;
            }
            ProductBeanDTO productBean;
            // 判断商品是否合法（商品是否存在、商品是否处于上架状态）
            if (((productBean = productBeanMap.get(cartGoods.getGoodsId())) != null) && (StoreItemStatus.PUT_ON_SALE.getCode().equals(productBean.getStatus()))) {
                ShoppingCartAdapter shoppingCartAdapter = SDKCommonBaseContextWare.getBean(ShoppingCartAdapter.class);
                shoppingCartAdapter.updateCartGoodsInfo(cartGoods, productBeans, cartGoodsStates, invalidGoodsIdList);
            } else {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            }
        }
        if (CollectionUtils.isNotEmpty(invalidGoodsIdList)) {
            cartGoodsStates.setHasInvalidGoods(true);
            this.removeInvalidGoods(partnerId, storeId, tableNumber, cartGoodsList, invalidGoodsIdList);
        }
    }

    default void removeInvalidGoods(String partnerId, String storeId, String tableNumber, List<CartGoods> cartGoodsList, List<String> invalidGoodsIdList) {
        cartGoodsList.removeIf(k -> invalidGoodsIdList.contains(k.getCartGoodsUid()) || StringUtils.isEmpty(k.getCartGoodsUid()));
    }

    default Map<String, GetMenuByIdsResponseDto.DataBean.MenuDetailDto> checkMenuProducts(String partnerId,
                                                                                          String shopId,
                                                                                          List<String> productIds, String trackingNo,String menuType) {

        Map<String, GetMenuByIdsResponseDto.DataBean.MenuDetailDto> menuDetailDtosMap = new HashMap<>();

        //查询spu商品是否在菜单
        GetMenuCategoryByIdsRequest getMenuCategoryByIdsDto = GetMenuCategoryByIdsRequest.builder()
                .businessDate(DateTimeUtils.getCurrentDateTimeStr())
                .channelType(menuType)
                .partnerId(partnerId)
                .shopId(shopId)
                .productIds(productIds).build();
        MenuService menuService = SDKCommonBaseContextWare.getBean(MenuService.class);
        com.freemud.application.sdk.api.base.BaseResponse<GetMenuCategoryByIdsResponse> getMenuCategoryByIdsResponse = menuService.getMenuCategoryByIds(getMenuCategoryByIdsDto, trackingNo);

        if (getMenuCategoryByIdsResponse == null || !CartResponseConstant.SUCCESS.getCode().equals(getMenuCategoryByIdsResponse.getCode())
                || getMenuCategoryByIdsResponse.getData() == null || CollectionUtils.isEmpty(getMenuCategoryByIdsResponse.getData().getMenuDetailDtos())) {
            return null;
        }

        Map<String, GetMenuCategoryByIdsResponse.MenuDetailDto> menuDetailDtosMapTemp = getMenuCategoryByIdsResponse.getData().getMenuDetailDtos().parallelStream()
                .collect(Collectors.toMap(GetMenuCategoryByIdsResponse.MenuDetailDto::getProductId, Function.identity(), (k1, k2) -> k1));

        for (Map.Entry<String, GetMenuCategoryByIdsResponse.MenuDetailDto> entry : menuDetailDtosMapTemp.entrySet()) {
            GetMenuByIdsResponseDto.DataBean.MenuDetailDto menuDetailDto = new GetMenuByIdsResponseDto.DataBean.MenuDetailDto();
            BeanUtils.copyProperties(entry.getValue(), menuDetailDto);
            menuDetailDtosMap.put(entry.getKey(), menuDetailDto);
        }

        return menuDetailDtosMap;
    }

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

    /**
     * 检查不是商品券的商品是否存在菜单中
     *
     * @param checkCartRequest
     * @param keySet
     */
    default void checkNoProductExistMenu(CheckCartRequest checkCartRequest, Set<String> keySet) {
        // 当商品不存在于菜单中且不是商品券时，需置空，待移除
        for (CartGoods cartGoods : checkCartRequest.getCartGoodsList()) {
            if (keySet == null
                    || (!keySet.contains(cartGoods.getSpuId())
                    && !cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX))) {
                cartGoods.setCartGoodsUid(null);
            }
        }
    }


    /**
     * 查询券详情
     *
     * @param partnerId
     * @param codes
     * @param trackingNo
     * @return
     */
    default List<DetailVO> getCouponsDetail(String partnerId, String storeId, List<String> codes, String trackingNo) {
        String appKey = getAppKey(partnerId, trackingNo);
        if (StringUtils.isEmpty(appKey)) {
            return null;
        }
        CouponDetailRequest couponDetailRequest = new CouponDetailRequest();
        couponDetailRequest.setCodes(codes);
        couponDetailRequest.setMerchantId(partnerId);
        couponDetailRequest.setPartnerId(partnerId);
        // 券码新增参数：组织机构
        couponDetailRequest.setChannelCodeList(this.getOrgIds(partnerId, storeId));
        OnlineCouponSdkService onlineCouponSdkService = SDKCommonBaseContextWare.getBean(OnlineCouponSdkService.class);
        com.freemud.application.sdk.api.base.BaseResponse<CouponDetailResponse> couponDetailResponse = onlineCouponSdkService.allDetail(couponDetailRequest, appKey, trackingNo);
        if (couponDetailResponse == null || !CartResponseConstant.SUCCESS.getCode().equals(couponDetailResponse.getCode()) || couponDetailResponse.getData() == null || CollectionUtils.isEmpty(couponDetailResponse.getData().getDetails())) {
            return null;
        }

        return couponDetailResponse.getData().getDetails();
    }

    /**
     * 获取商户秘钥
     *
     * @param partnerId
     * @param trackingNo
     * @return
     */
    default String getAppKey(String partnerId, String trackingNo) {
        RedisCache redisCache = SDKCommonBaseContextWare.getBean(RedisCache.class);
        String appKey = redisCache.getValue(CouponConstant.COUPON_PARTNER_APP_KEY + partnerId);
        if (StringUtils.isEmpty(appKey)) {
            PartnerRequest partnerRequest = new PartnerRequest();
            partnerRequest.setPartnerId(Integer.parseInt(partnerId));
            partnerRequest.setAppId(getCouponAppId());
            FMActiveSdkService fmActiveSdkService = SDKCommonBaseContextWare.getBean(FMActiveSdkService.class);
            com.freemud.application.sdk.api.base.BaseResponse<AppKeyVO> appKeyVOBaseResponse = fmActiveSdkService.getAppKey(partnerRequest, trackingNo);
            if (appKeyVOBaseResponse == null || !CartResponseConstant.SUCCESS.getCode().equals(appKeyVOBaseResponse.getCode())
                    || appKeyVOBaseResponse.getData() == null || StringUtils.isEmpty(appKeyVOBaseResponse.getData().getAppKey())) {
                return null;
            }
            appKey = appKeyVOBaseResponse.getData().getAppKey();
            redisCache.save(CouponConstant.COUPON_PARTNER_APP_KEY + partnerId, appKey);
        }
        return appKey;
    }

    /**
     * 券码提供查询秘钥的appId
     *
     * @return
     */
    String getCouponAppId();

    /**
     * 校验点餐方式
     * key = 活动code , value = 返回是否匹配点餐方式
     *
     * @param partnerId
     * @param activityCodes
     * @param orderTye
     * @param trackingNo
     * @return
     */
    Map<String, Boolean> getCouponOrderWay(String partnerId, List<String> activityCodes, Integer orderTye, String trackingNo);

    /**
     * 获取可用优惠券信息
     *
     * @param couponAvailableReqVo
     * @param appSecret
     * @return
     */
    default BaseResponse<CouponAvailableRespVo> getCouponsAvailable(CouponAvailableReqVo couponAvailableReqVo, String appSecret, String trackingNo) {
        OnlineCouponSdkService onlineCouponSdkService = SDKCommonBaseContextWare.getBean(OnlineCouponSdkService.class);
        CouponDetailRequest couponDetailRequest = getCouponAvailableReqVo(couponAvailableReqVo);
        com.freemud.application.sdk.api.base.BaseResponse<CouponDetailResponse> baseResponse = onlineCouponSdkService.allDetail(couponDetailRequest, appSecret, trackingNo);
        if ((baseResponse == null) || (CartResponseConstant.SUCCESS.getCode().equals(baseResponse.getCode())) || (baseResponse.getData() == null)) {
            return CartResponseUtil.error("批量券详情查询失败");
        }
        CouponDetailResponse couponDetailResponse = baseResponse.getData();
        if (!CartResponseConstant.SUCCESS.getCode().equals(couponDetailResponse.getResult() + "")) {
            CouponAvailableRespVo couponAvailableRespVo = new CouponAvailableRespVo(Integer.valueOf(CartResponseConstant.FAIL.getCode()), JSON.toJSONString(couponDetailResponse.getErrors()));
            return CartResponseUtil.success(couponAvailableRespVo);
        }
        CouponAvailableRespVo couponAvailableRespVo = calculation(couponAvailableReqVo, couponDetailResponse.getDetails(), couponDetailResponse.getStoreInfo());
        return CartResponseUtil.success(couponAvailableRespVo);
    }

    default CouponDetailRequest getCouponAvailableReqVo(CouponAvailableReqVo couponAvailableReqVo) {
        CouponDetailRequest couponDetailRequest = new CouponDetailRequest();
        couponDetailRequest.setPartnerId(couponAvailableReqVo.getPartnerId());
        couponDetailRequest.setMerchantId(couponAvailableReqVo.getMerchantId());
        couponDetailRequest.setStoreId(couponAvailableReqVo.getStoreId());
        couponDetailRequest.setCodes(couponAvailableReqVo.getCouponCodes());
        couponDetailRequest.setChannelCodeList(this.getOrgCodes(couponAvailableReqVo.getPartnerId(), couponAvailableReqVo.getStoreId()));
        return couponDetailRequest;
    }

    /**
     * 根据购物车商品，金额计算券是否可用
     *
     * @param couponAvailableReqVo
     * @param details
     * @param storeInfo
     * @return
     */
    default CouponAvailableRespVo calculation(CouponAvailableReqVo couponAvailableReqVo, List<DetailVO> details, StoreInfoVO storeInfo) {
        Date now = new Date();
        if (CollectionUtils.isEmpty(details)) {
            return new CouponAvailableRespVo(Integer.valueOf(CartResponseConstant.FAIL.getCode()), "查询券信息列表为空");
        }
        List<CouponStateVo> couponStateVoList = new ArrayList<>(details.size());
        details.parallelStream().forEach(couponDetail -> {
            CouponStateVo couponState = calculation(couponAvailableReqVo, couponDetail, now, storeInfo);
            couponStateVoList.add(couponState);
        });
        CouponAvailableRespVo couponAvailableRespVo = new CouponAvailableRespVo();
        couponAvailableRespVo.setResult(Integer.valueOf(CartResponseConstant.SUCCESS.getCode()));
        couponAvailableRespVo.setCouponStateList(couponStateVoList);
        return couponAvailableRespVo;
    }


    /**
     * 计算是卡券是否可用
     *
     * @param couponAvailableReqVo
     * @param detail
     * @param now
     * @param storeInfo
     * @return
     */
    default CouponStateVo calculation(CouponAvailableReqVo couponAvailableReqVo, DetailVO detail, Date now, StoreInfoVO storeInfo) {
        //券基础校验 状态、时间
        CouponStateVo couponStateVo = getCouponStateVo(detail, now);
        if (couponStateVo != null) return couponStateVo;
        couponStateVo = new CouponStateVo();
        couponStateVo.setCouponCode(detail.getCode());
        couponStateVo.setType(detail.getType());
        //门店白名单校验
        String storeId = couponAvailableReqVo.getStoreId();
        boolean isStoreMap = false;
        if (!CollectionUtils.isEmpty(detail.getActiveRestrictionVOS()) && StringUtils.isNotEmpty(storeId)) {
            if (storeInfo == null) {
                couponStateVo.setMessage("为查到该门店");
                couponStateVo.setState(CouponConstant.CAN_NOT_USE);
                return couponStateVo;
            }
            String city = StringUtils.isEmpty(couponAvailableReqVo.getCity()) ? storeInfo.getLocation() : couponAvailableReqVo.getCity();
            List<ActiveRestrict> activeRestrictionVOS = detail.getActiveRestrictionVOS();
            for (ActiveRestrict eachRestrict : activeRestrictionVOS) {
                if (eachRestrict != null) {
                    if (StringUtils.isNotEmpty(eachRestrict.getCity()) && StringUtils.isNotEmpty(city)) {
                        if (city.equals(eachRestrict.getCity()))
                            isStoreMap = true;
                        break;
                    }
                    //判断活动门店是否满足要求
                    if (eachRestrict.getStoreIDPartner() != null && eachRestrict.getStoreIDPartner().equals(storeId)) {
                        isStoreMap = true;
                        break;
                    }
                }
            }
        }
        if (CollectionUtils.isEmpty(detail.getActiveRestrictionVOS())) {
            // 全部门店
            isStoreMap = true;
        }

        if (!isStoreMap) {
            couponStateVo.setMessage("当前门店不可用");
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
        } else {
            couponStateVo.setState(CouponConstant.CAN_USE);
        }
        Integer type = detail.getType();
        switch (type) {
            case 0://商品券
                productCoupon(couponAvailableReqVo, detail, couponStateVo);
                break;
            case 1://代金券
                cashCoupon(couponAvailableReqVo, detail, couponStateVo);
                break;
            case 3://折扣券
                elseCoupon(couponAvailableReqVo, detail, couponStateVo);
                break;
            default:
                couponStateVo.setMessage("不识别的券类别");
                couponStateVo.setState(CouponConstant.CAN_NOT_USE);
                return couponStateVo;
        }
        String valid = detail.getValid_start();
        Date validDate = DateTimeUtils.parseDate(valid, DateTimeUtils.FORMAT_YYYY_MM_DD_HHMMSS);
        if (validDate == null || now.before(validDate)) {
            //当前时间早于开始时间
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
            couponStateVo.setMessage("券使用有效期尚未开始");
        }
        return couponStateVo;
    }

    default CouponStateVo getCouponStateVo(DetailVO detail, Date now) {
        CouponStateVo couponStateVo = new CouponStateVo();
        if (detail == null) {
            couponStateVo.setMessage("未查到code详情");
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
            return couponStateVo;
        }
        couponStateVo.setType(detail.getType());
        couponStateVo.setState(CouponConstant.CAN_NOT_USE);
        couponStateVo.setCouponCode(detail.getCode());
        if (detail.getStatus() == null || !CouponConstant.CAN_USE.equals(detail.getStatus())) {
            couponStateVo.setMessage("该券已核销或作废");
            return couponStateVo;
        }
        String valid = detail.getValid_ends();
        Date validDate = DateTimeUtils.parseDate(valid, DateTimeUtils.FORMAT_YYYY_MM_DD_HHMMSS);
        if (validDate == null || now.after(validDate)) {
            //当前时间早于开始时间
            couponStateVo.setMessage("券已过期");
            return couponStateVo;
        }
        return null;
    }

    /**
     * 商品券计算
     * 没有多次核销 没有 M 选 N
     *
     * @param couponAvailableReqVo
     * @param detail
     * @param couponStateVo
     */
    default void productCoupon(CouponAvailableReqVo couponAvailableReqVo, DetailVO detail, CouponStateVo couponStateVo) {
        List<ActiveProduct> activeProductVOS = detail.getActiveProduct();
        if (CollectionUtils.isEmpty(activeProductVOS)) {
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
            couponStateVo.setMessage("该商品券没有配置商品");
            return;
        }
        List<CouponProductVO> couponProductList = detail.getCouponProductList();
        if (CollectionUtils.isEmpty(couponProductList)) {
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
            couponStateVo.setMessage("该商品券没有配置商品");
            return;
        }

        //activeProductVOS 商品券商品集合
        List<Product> productList = couponProductList.stream().map(this::getProductByCouponProduct).collect(Collectors.toList());
        //购物车商品集合
        List<Product> orderProductList = couponAvailableReqVo.getProductList();
        Map<String, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getProductId, product -> product));
        productList.clear();
        orderProductList.forEach(eachProduct -> {
            if (productMap.containsKey(eachProduct.getProductId())) {
                Product product = productMap.get(eachProduct.getProductId());
                Integer quantity = product.getQuantity();
                if (eachProduct.getQuantity() < product.getQuantity()) {
                    quantity = eachProduct.getQuantity();
                }
                product.setQuantity(quantity);
                productList.add(product);
            }
        });
        if (CollectionUtils.isEmpty(productList)) {
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
        } else {
            couponStateVo.setLimitType(CouponConstant.PRODUCT_WHITE);
            couponStateVo.setState(CouponConstant.LIMIT_USE);
            couponStateVo.setProductList(productList);
        }

    }

    default Product getProductByCouponProduct(CouponProductVO couponProduct) {
        Product product = new Product();
        product.setProductId(couponProduct.getMerchantproductid());
        product.setQuantity(couponProduct.getAmountleft().intValue());
        return product;
    }

    /**
     * 代金券计算
     *
     * @param couponAvailableReqVo
     * @param detail
     * @param couponStateVo
     */
    default void cashCoupon(CouponAvailableReqVo couponAvailableReqVo, DetailVO detail, CouponStateVo couponStateVo) {
        //判断是否有商品限制if (doCheckProduct(detail, couponStateVo)) return;

        calculateProductSetting(couponAvailableReqVo, detail, couponStateVo);
        calculatedAmount(couponAvailableReqVo, detail, couponStateVo);
    }

    /**
     * 计算商品黑白名单
     *
     * @param couponAvailableReqVo
     * @param detail
     * @param couponStateVo
     */
    default void calculateProductSetting(CouponAvailableReqVo couponAvailableReqVo, DetailVO detail, CouponStateVo couponStateVo) {
        List<ActiveProduct> activeProductVOS = detail.getActiveProduct();
        ActiveProduct activeProduct = activeProductVOS.stream().filter(product -> CouponConstant.VIRTUAL_PRODUCT.equals(product.getProductID_Partner())).findFirst().orElse(null);
        if (activeProduct == null) {
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
            couponStateVo.setMessage("券优惠金额没有配置");
            return;
        }
        //获取折扣或代金券优惠金额
        Integer amount = activeProduct.getAmount();
        BigDecimal price_discount = CouponConstant.HUNDRED.multiply(activeProduct.getPrice_Discount());
        BigDecimal price_original = CouponConstant.HUNDRED.multiply(activeProduct.getPrice_Original());
        couponStateVo.setOriginalPrice(price_original.intValue());
        couponStateVo.setPriceDiscount(price_discount.intValue());
        couponStateVo.setAmount(amount);

        List<ActiveProductSetting> activeProduceSettings = detail.getActiveProductSetting();
        if (CollectionUtils.isEmpty(activeProduceSettings)) {
            return;
        }
        Map<String, List<ActiveProductSetting>> activeProductSettingMap = new HashMap<>(2);
        activeProductSettingMap(activeProductSettingMap, activeProduceSettings);
        List<ActiveProductSetting> whiteList = activeProductSettingMap.get(CouponConstant.PRODUCT_WHITE);
        List<Product> productList = couponAvailableReqVo.getProductList();
        if (!CollectionUtils.isEmpty(whiteList)) {
            //白名单计算
            Map<String, ActiveProductSetting> productSettingMap = whiteList.stream().collect(Collectors.toMap(product -> product.getProductCode() == null ? product.getCategoryCode() : product.getProductCode(), product -> product));
            calculationProduct(productSettingMap, productList, couponStateVo, detail, couponAvailableReqVo.getTotalAmount(), CouponConstant.PRODUCT_WHITE);
        }
        List<ActiveProductSetting> blackList = activeProductSettingMap.get(CouponConstant.PRODUCT_BLACK);
        if (!CollectionUtils.isEmpty(blackList)) {
            //黑名单计算
            Map<String, ActiveProductSetting> productSettingMap = blackList.stream().collect(Collectors.toMap(product -> product.getProductCode() == null ? product.getCategoryCode() : product.getProductCode(), product -> product));
            calculationProduct(productSettingMap, productList, couponStateVo, detail, couponAvailableReqVo.getTotalAmount(), CouponConstant.PRODUCT_BLACK);
        }
    }

    default void calculationProduct(Map<String, ActiveProductSetting> productSettingMap, List<Product> productList, CouponStateVo couponStateVo, DetailVO detail, Integer cartTotalAmount, String productType) {

        //限制商品集合
        List<Product> couponProductList = productList.stream().filter(eachProduct -> productSettingMap.containsKey(eachProduct.getProductId()) || productSettingMap.containsKey(eachProduct.getCategoryCode())).collect(Collectors.toList());

        couponStateVo.setProductList(couponProductList);
        //获取券使用最小金额 元转为分做计算
        Integer minAmount = detail.getMinAmount();
        couponStateVo.setLimitType(productType);
        int totalAmount = couponProductList.stream().mapToInt(product -> product.getAmount() * product.getQuantity()).sum();
        if (productType.equals(CouponConstant.PRODUCT_WHITE)) {
            //白名单商品集合
            if (CollectionUtils.isEmpty(couponProductList)) {
                couponStateVo.setState(CouponConstant.CAN_NOT_USE);
                couponStateVo.setMessage("当前商品集合不满足该券使用商品条件");
                return;
            }

            //白名单内总金额
            if (minAmount != null && minAmount > totalAmount) {
                couponStateVo.setState(CouponConstant.CAN_NOT_USE);
                couponStateVo.setMessage("券最小使用金额大于当前订单总金额");
                return;
            }
        } else {
            //黑名单商品集合
            //计算剩余商品金额
            totalAmount = cartTotalAmount - totalAmount;
            if (minAmount != null && minAmount > totalAmount) {
                couponStateVo.setState(CouponConstant.CAN_NOT_USE);
                couponStateVo.setMessage("券最小使用金额大于当前订单总金额");
                return;
            }
        }
        couponStateVo.setState(CouponConstant.LIMIT_USE);
        couponStateVo.setMinAmount(minAmount);

    }

    default void activeProductSettingMap(Map<String, List<ActiveProductSetting>> activeProductSettingMap, List<ActiveProductSetting> activeProductSettingList) {
        List<ActiveProductSetting> whiteList = new ArrayList<>();
        List<ActiveProductSetting> blackList = new ArrayList<>();
        activeProductSettingMap.put(CouponConstant.PRODUCT_BLACK, blackList);
        activeProductSettingMap.put(CouponConstant.PRODUCT_WHITE, whiteList);
        if (CollectionUtils.isEmpty(activeProductSettingList)) {
            return;
        }
        activeProductSettingList.forEach(eachProduct -> {
            if (CouponConstant.PRODUCT_BLACK.equals(eachProduct.getType().toString())) {
                blackList.add(eachProduct);
            } else {
                whiteList.add(eachProduct);
            }
        });
    }

    /**
     * 计算订单总金额是否达到使用券金额标准
     *
     * @param couponAvailableReqVo
     * @param detail
     * @param couponStateVo
     */
    default void calculatedAmount(CouponAvailableReqVo couponAvailableReqVo, DetailVO detail, CouponStateVo couponStateVo) {
        Integer totalAmount = couponAvailableReqVo.getTotalAmount();
        Integer minAmount = detail.getMinAmount();
        couponStateVo.setMinAmount(minAmount);
        if (totalAmount == null || totalAmount <= 0) {
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
            couponStateVo.setMessage("订单总金额不能为空或小于等于0");
        }
        if (minAmount > totalAmount) {
            couponStateVo.setState(CouponConstant.CAN_NOT_USE);
            couponStateVo.setMessage("不满足券得指定消费金额");
        }
    }

    /**
     * 折扣券计算
     *
     * @param couponAvailableReqVo
     * @param detail
     * @param couponStateVo
     */
    default void elseCoupon(CouponAvailableReqVo couponAvailableReqVo, DetailVO detail, CouponStateVo couponStateVo) {
        Active active = detail.getActive();
        if (active != null) {
            couponStateVo.setDiscount(active.getPercentDiscount().intValue());
        }
        //判断是否有商品限制 if (doCheckProduct(detail, couponStateVo)) return;
        calculateProductSetting(couponAvailableReqVo, detail, couponStateVo);
        calculatedAmount(couponAvailableReqVo, detail, couponStateVo);
    }

    /**
     * 获取缓存中单个商品行信息
     *
     * @param cartParamDto
     * @param trackingNo
     * @return
     */
    BaseResponse<CartGoods> getCartGoods(CartParamDto cartParamDto, String trackingNo);

    /**
     * 更新商品行数量
     *
     * @param cartParamDto
     * @param trackingNo
     * @return
     */
    BaseResponse<List<CartGoods>> updateGoodsQty(CartParamDto cartParamDto, String trackingNo);

    /**
     * 查询组织机构
     * @param partnerId
     * @param storeId
     * @return
     */
    default List<String> getOrgIds(String partnerId, String storeId) {
        GetOrgTreeListRequest request = new GetOrgTreeListRequest();
        request.setPartnerId(partnerId);
        request.setStoreCode(storeId);
        StoreCenterService storeCenterService = SDKCommonBaseContextWare.getBean(StoreCenterService.class);
        com.freemud.application.sdk.api.base.BaseResponse<List<String>> orgList = storeCenterService.getOrgList(request, LogThreadLocal.getTrackingNo());
        if (orgList != null && CartResponseConstant.SUCCESS.getCode().equals(orgList.getCode())) {
            return orgList.getData();
        }
        return Collections.EMPTY_LIST;
    }
    /**
     * 查询门店服务 - 获取组织code集合
     *
     * @param partnerId
     * @param storeCode
     * @return
     */
    default List<String> getOrgCodes(String partnerId, String storeCode) {
        GetOrgTreeListRequest request = new GetOrgTreeListRequest();
        request.setPartnerId(partnerId);
        request.setStoreCode(storeCode);
        StoreCenterService storeCenterService = SDKCommonBaseContextWare.getBean(StoreCenterService.class);
        com.freemud.application.sdk.api.base.BaseResponse<GetOrgTreeListResponse> orgList = storeCenterService.getOrgTreeList(request, LogThreadLocal.getTrackingNo());
        if (orgList != null && CartResponseConstant.SUCCESS.getCode().equals(orgList.getCode())) {
            List<GetOrgTreeListResponse.OrgList> orgResponseList = orgList.getData().getOrgList();
            if (CollectionUtils.isEmpty(orgResponseList)){
                return null;
            }
            return orgResponseList.stream().map(org -> org.getOrganizationCode()).collect(Collectors.toList());
        }
        return null;
    }




}
