package cn.freemud.service.impl.mcoffee.calculation;

import cn.freemud.adapter.CouponAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.ApplicationConstant;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
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.CommonService;
import cn.freemud.service.impl.ItemServiceImpl;
import cn.freemud.service.impl.mcoffee.entity.*;
import cn.freemud.service.thirdparty.CouponClient;
import cn.freemud.service.thirdparty.CustomerExtendClient;
import cn.freemud.utils.BarcodeUtil;
import cn.freemud.utils.ExceptionUtils;
import cn.freemud.utils.LogUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ApiLog;
import com.google.common.collect.Lists;
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.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: CouponDiscountCalculation
 * @Package cn.freemud.service.impl.mcoffee
 * @Description:
 * @author: ping1.wu
 * @date: 2020/8/3 16:02
 * @Copyright: 2020 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
@Slf4j
public class CouponDiscountCalculation {

    @Autowired
    private CustomerExtendClient customerExtendClient;
    @Autowired
    private ItemServiceImpl itemService;

    @Autowired
    private CommonService commonService;
    @Autowired
//    private CouponAvailableService couponAvailableService;
    private CouponClient mCoffeeCouponClient;
    @Autowired
    private CouponAdapter couponAdapter;
//    @Autowired
//    private RedisCache redisCache;
//    @Autowired
//    private CardBinClient cardBinClient;
    @Value("${coupon.app.id}")
    private String appid;
    @Value("${mccafe.universal.coupon.code}")
    private String mccafeUniversalCouponCode;

    private static final String mcafe = "mccafe";

    private static final String mcafePickup ="mccafe_pickup";

    /**
     * 优惠计算
     */
    public void updateShoppingCartGoodsDiscount(ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {

        if (calculationDiscountResult == null || CollectionUtils.isEmpty(calculationDiscountResult.getDiscounts())
                || !calculationDiscountResult.getDiscounts().stream().anyMatch(discount -> (ActivityTypeEnum.TYPE_3.getCode().equals(discount.getType())
                || (ActivityTypeEnum.TYPE_31.getCode().equals(discount.getType()))
                || (ActivityTypeEnum.TYPE_32.getCode().equals(discount.getType()))
                || (ActivityTypeEnum.TYPE_35.getCode().equals(discount.getType()))
                || (ActivityTypeEnum.TYPE_37.getCode().equals(discount.getType()))
                || (ActivityTypeEnum.TYPE_38.getCode().equals(discount.getType()))
                || (ActivityTypeEnum.TYPE_39.getCode().equals(discount.getType()))))){
            return;
        }
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsList = calculationDiscountResult.getGoods();
        if (CollectionUtils.isEmpty(goodsList)) {
            return;
        }

        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discounts =  calculationDiscountResult.getDiscounts();
        if (CollectionUtils.isEmpty(discounts)) {
            return;
        }
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> couponDiscounts =
                discounts.stream().filter(discount -> (ActivityTypeEnum.TYPE_3.getCode().equals(discount.getType())
                        || (ActivityTypeEnum.TYPE_31.getCode().equals(discount.getType()))
                        || (ActivityTypeEnum.TYPE_32.getCode().equals(discount.getType()))
                        || (ActivityTypeEnum.TYPE_35.getCode().equals(discount.getType()))
                        || (ActivityTypeEnum.TYPE_37.getCode().equals(discount.getType()))
                        || (ActivityTypeEnum.TYPE_38.getCode().equals(discount.getType()))
                        || (ActivityTypeEnum.TYPE_39.getCode().equals(discount.getType())))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(couponDiscounts)) {
            return;
        }

        /**
         * 月享卡2.0 促销单独返回 月享卡优惠
         */
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.MonthCardDiscount monthCardDiscount = calculationDiscountResult.getMonthlyEnjoyCardDiscount();
        if (null != monthCardDiscount){
            //月享卡2.0 信息回填
            for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods goods : goodsList) {
                Optional<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> optional = goods.getDiscounts().stream().filter(goodsDiscount -> ActivityTypeEnum.TYPE_38.getCode() == goodsDiscount.getType()).findFirst();
                if(CollectionUtils.isNotEmpty(goods.getDiscounts()) && optional.isPresent()){
                    ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount card2Discount = optional.get();
                    for (CartGoods cartGoods : cartGoodsList) {
                        //比較商品ID 以及 商品行UID 防止篡改了其他商品券的券号
                        if (StringUtils.equals(cartGoods.getGoodsId(),card2Discount.getGoodsId()) && goods.getCartGoodsUid().equals(cartGoods.getCartGoodsUid())){
                            cartGoods.setIsMonthCardGoods(1);
                            cartGoods.setCouponName("");
                            cartGoods.setCouponCode(card2Discount.getActivityCode());
                            cartGoods.setActivityType(card2Discount.getType());
                        }
                    }
                }
            }
            Boolean hasMonCardDiscountVirtualProduct = false;
            //如果购物车列表已有优惠项，则更新促销返回的优惠信息
            for (CartGoods cartGoods : cartGoodsList) {
                if (StringUtils.equals(cartGoods.getSkuId(),"9999")){
                    cartGoods.setSkuName(monthCardDiscount.getDiscountDesc());
                    cartGoods.setSpuName(monthCardDiscount.getDiscountDesc());
                    cartGoods.setPic(monthCardDiscount.getDiscountLogo());
                    cartGoods.setQty(1);
                    cartGoods.setAmount(monthCardDiscount.getDiscountAmount());
                    hasMonCardDiscountVirtualProduct = true;
                }
            }
            //如果是菜单页加购月享卡商品.促销返回月享卡优惠后 虚拟一个 优惠项返回给前端
            if (!hasMonCardDiscountVirtualProduct){
                CartGoods virtualProduct = new CartGoods();
                virtualProduct.setSkuId("9999");
                virtualProduct.setSpuId("9999");
                virtualProduct.setSkuName(monthCardDiscount.getDiscountDesc());
                virtualProduct.setSpuName(monthCardDiscount.getDiscountDesc());
                virtualProduct.setPic(monthCardDiscount.getDiscountLogo());
                virtualProduct.setQty(1);
                virtualProduct.setAmount(monthCardDiscount.getDiscountAmount());
                cartGoodsList.add(virtualProduct);
            }
        }

        Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsMap = goodsList.parallelStream()
                .collect(Collectors.toMap(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods::getCartGoodsUid, Function.identity(), (k1, k2) -> k1));

        // 匹配随单购悦享卡
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount discountMon = couponDiscounts.stream().filter(t -> (
                (ActivityTypeEnum.TYPE_37.getCode().equals(t.getType()) || ActivityTypeEnum.TYPE_38.getCode().equals(t.getType()))
                                                && mccafeUniversalCouponCode.equals(t.getActivityCode()))).findFirst().orElse(null);


        List<CartGoods> newCartGoodsList = new ArrayList<>();
        boolean haveB3S1Fav = false;
        Optional<CartGoods> cartGoodsOptional = cartGoodsList.stream().filter(o -> o.getIsB3S1Coupon() == 1).findFirst();
        String b3S1SeedCode = "";
        if(cartGoodsOptional.isPresent()) {
            b3S1SeedCode = cartGoodsOptional.get().getB3S1CouponGoodsInfo().getCardCode();
        }
        Integer useTimes = 0;
        for (int i = 0; i < cartGoodsList.size(); i++) {
            CartGoods cartGoods = cartGoodsList.get(i);
            cartGoods.setIsB3S1CouponGoods(0);
            boolean useCoupon = false;
            if("9998".equals(cartGoods.getSkuId())) {
                continue;
            }
            if (goodsMap.get(cartGoods.getCartGoodsUid()) == null) {
                continue;
            }
            //商品券商品
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> discountsNew = goodsMap.get(cartGoods.getCartGoodsUid()).getDiscounts();
            if (StringUtils.isNotBlank(cartGoods.getCouponCode()) || discountMon != null) {
                //先将商品券商品最终售价设置为 原价
                if (!StringUtils.equals("9999",cartGoods.getSkuId())){
                    cartGoods.setAmount(cartGoods.getOriginalAmount());
                }
                if (CollectionUtils.isNotEmpty(discountsNew)) {
                    useCoupon = true;
//                    ApiLog.debug("couponDiscountCalculation:{}",discountsNew);
                    if(ApplicationConstant.printDebug){
                        ApiLog.printLog("couponDiscountCalculation:{}",JSON.toJSONString(discountsNew),null,null);
                    }
                    //这里过滤掉了 月享卡2.0，因为月享卡2.0商品不用展示划线价，故显示原价
                    Optional<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> targetDiscount =  discountsNew.stream()
                            .filter(t -> ActivityTypeEnum.TYPE_32.getCode().equals(t.getType())
                                    || ActivityTypeEnum.TYPE_37.getCode().equals(t.getType())
                                    || ActivityTypeEnum.TYPE_39.getCode().equals(t.getType())).findFirst();
                    if (null != targetDiscount && targetDiscount.isPresent()) {
                        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount = targetDiscount.get();
                        cartGoods.setCouponName(goodsDiscount.getActivityName());
                        //普通商品券 和月享卡1.0的 商品最终售价更新为促销返回价格
                        cartGoods.setAmount(goodsMap.get(cartGoods.getCartGoodsUid()).getRealAmount());
                    }
                }
            }

            Optional<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> b3S1DiscountOptional =  discountsNew.stream()
                    .filter(t -> ActivityTypeEnum.TYPE_35.getCode().equals(t.getType())).findFirst();
            if(b3S1DiscountOptional.isPresent()) {
                haveB3S1Fav = true;
                if(b3S1DiscountOptional.get().getActivityCode().equals(b3S1SeedCode)) {
                    useTimes += b3S1DiscountOptional.get().getActualGoodsNumber();
                }
                if(cartGoods.getQty() > b3S1DiscountOptional.get().getActualGoodsNumber()) {
                    int newNum = cartGoods.getQty() - b3S1DiscountOptional.get().getActualGoodsNumber();
                    Long materialAmount = cartGoods.getMaterialAmount() == null ? 0l : cartGoods.getMaterialAmount();
                    Long materialPrice = materialAmount/cartGoods.getQty();
                    CartGoods cartGoodsNew = new CartGoods();
                    BeanUtils.copyProperties(cartGoods, cartGoodsNew);
                    cartGoods.setQty(b3S1DiscountOptional.get().getActualGoodsNumber());
                    cartGoods.setCouponCode(b3S1DiscountOptional.get().getActivityCode());
                    cartGoods.setCouponName(b3S1DiscountOptional.get().getActivityName());
                    cartGoods.setOriginalAmount(cartGoods.getOriginalPrice() * cartGoods.getQty() + materialPrice * cartGoods.getQty());
                    cartGoods.setAmount(0 + materialPrice * cartGoods.getQty());
                    cartGoods.setIsB3S1CouponGoods(1);
                    cartGoodsNew.setCartGoodsUid(UUID.randomUUID().toString());
                    cartGoodsNew.setQty(newNum);
                    cartGoodsNew.setCouponCode(null);
                    cartGoodsNew.setCouponName(null);
                    cartGoodsNew.setOriginalAmount(cartGoods.getOriginalPrice() * newNum + materialPrice * newNum);
                    cartGoodsNew.setAmount(cartGoods.getOriginalPrice() * newNum + materialPrice * newNum);
                    newCartGoodsList.add(cartGoodsNew);
                } else if(cartGoods.getQty() == b3S1DiscountOptional.get().getActualGoodsNumber()) {
                    cartGoods.setCouponCode(b3S1DiscountOptional.get().getActivityCode());
                    cartGoods.setCouponName(b3S1DiscountOptional.get().getActivityName());
                    cartGoods.setIsB3S1CouponGoods(1);
                    Long materialAmount = cartGoods.getMaterialAmount() == null ? 0l : cartGoods.getMaterialAmount();
                    cartGoods.setAmount(goodsMap.get(cartGoods.getCartGoodsUid()).getRealAmount() + materialAmount);
                }
            } else {
                if(!useCoupon) {
                    cartGoods.setCouponCode(null);
                    cartGoods.setCouponName(null);
                }
            }

        }
        cartGoodsList.addAll(newCartGoodsList);
        if(useTimes != 0) {
            cartGoodsList.stream().filter(o -> o.getIsB3S1Coupon() == 1).findFirst().get().getB3S1CouponGoodsInfo().setUseTimes(useTimes);
        }

        if(haveB3S1Fav) {

            int index = 0;
            for (int i = 0; i < cartGoodsList.size(); i++) {
                if(cartGoodsList.get(i).getIsB3S1Coupon() == 1) {
                    index++;
                } else {
                    break;
                }
            }
            for (int i = index+1; i < cartGoodsList.size(); i++) {
                CartGoods cartGoods = cartGoodsList.get(i);
                if(cartGoods.getIsB3S1CouponGoods() == 1) {
                    cartGoodsList.remove(i);
                    cartGoodsList.add(index, cartGoods);
                    index++;
                }
            }


            List<CartGoods> nowCartGoodsList = new ArrayList<>();
            nowCartGoodsList.addAll(cartGoodsList);
            AtomicBoolean changed = new AtomicBoolean();
            changed.set(false);
            if(CollectionUtils.isNotEmpty(cartGoodsList)){
//                ApiLog.debug("合并买3赠1商品券 【merge-before】 : {} ", JSONObject.toJSONString(nowCartGoodsList));
                if(ApplicationConstant.printDebug){
                    ApiLog.printLog("合并买3赠1商品券 【merge-before】 : {} ", JSONObject.toJSONString(nowCartGoodsList),null,null);
                }
                for (int i = cartGoodsList.size() - 1; i >= 1; i--) {
                    CartGoods cartGoods = cartGoodsList.get(i);
                    int index2 = nowCartGoodsList.indexOf(cartGoods);
                    if(index2 < i) {
                        changed.set(true);
                        CartGoods cartGoodsNow = nowCartGoodsList.get(index2);
                        cartGoodsNow.setQty(cartGoodsNow.getQty() + cartGoods.getQty());
                        cartGoodsNow.setAmount(cartGoodsNow.getAmount() + cartGoods.getAmount());
                        cartGoodsNow.setMaterialAmount(cartGoodsNow.getMaterialAmount() + cartGoods.getMaterialAmount());
                        cartGoodsNow.setOriginalAmount(cartGoodsNow.getOriginalAmount() + cartGoods.getOriginalAmount());
                        nowCartGoodsList.remove(i);
                    }
//                    ApiLog.debug("合并买3赠1商品券 【merge-ing】 : {} ", JSONObject.toJSONString(nowCartGoodsList));
                    if(ApplicationConstant.printDebug){
                        ApiLog.printLog("合并买3赠1商品券 【merge-ing】 : {} ", JSONObject.toJSONString(nowCartGoodsList),null,null);
                    }
                }
//                ApiLog.debug("合并买3赠1商品券 【merge-after】 : {} ", JSONObject.toJSONString(nowCartGoodsList));
                if(ApplicationConstant.printDebug){
                    ApiLog.printLog("合并买3赠1商品券 【merge-after】 : {} ", JSONObject.toJSONString(nowCartGoodsList),null,null);
                }
            }
            if(changed.get()) {
                cartGoodsList.clear();
                cartGoodsList.addAll(nowCartGoodsList);
            }
        }

        // 当couponCode不为空时，需计算优惠价格
        long couponDiscount = 0;
        if (CollectionUtils.isNotEmpty(couponDiscounts)) {
            for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount couponResults : couponDiscounts) {
                couponDiscount = couponDiscount + (couponResults.getDiscount() == null ? 0 : couponResults.getDiscount());
            }
        }
        shoppingCartGoodsResponseVo.setCouponDiscount(couponDiscount);
    }

    /**
     * 商品均摊
     */
    public void updateShoppingCartGoodsApportion(ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo){

        if (calculationDiscountResult == null
                || CollectionUtils.isEmpty(calculationDiscountResult.getDiscounts())
                || !calculationDiscountResult.getDiscounts().stream().anyMatch(
                        discount -> ActivityTypeEnum.TYPE_3.getCode().equals(discount.getType())
                                || ActivityTypeEnum.TYPE_31.getCode().equals(discount.getType())
                                || ActivityTypeEnum.TYPE_32.getCode().equals(discount.getType())
                                || ActivityTypeEnum.TYPE_35.getCode().equals(discount.getType())
                                || ActivityTypeEnum.TYPE_37.getCode().equals(discount.getType())
                                || ActivityTypeEnum.TYPE_38.getCode().equals(discount.getType())
                                || ActivityTypeEnum.TYPE_39.getCode().equals(discount.getType()))) {
            return;
        }
        Map<String, Integer> extendTypeMap = calculationDiscountResult.getDiscounts().stream().filter(o -> o.getExtendType() != null)
                .collect(Collectors.toMap(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount::getActivityCode
                        , ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount::getExtendType, (k1, k2) -> k1));
        //订单级别券优惠
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> couponDiscounts =  calculationDiscountResult.getDiscounts();
        if (CollectionUtils.isEmpty(couponDiscounts)) {
            return;
        }
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discounts = couponDiscounts.stream().filter(
                discount -> (ActivityTypeEnum.TYPE_3.getCode().equals(discount.getType())
                        || ActivityTypeEnum.TYPE_31.getCode().equals(discount.getType())
                        || ActivityTypeEnum.TYPE_32.getCode().equals(discount.getType())
                        || ActivityTypeEnum.TYPE_35.getCode().equals(discount.getType())
                        || ActivityTypeEnum.TYPE_37.getCode().equals(discount.getType())
                        || ActivityTypeEnum.TYPE_38.getCode().equals(discount.getType())
                        || ActivityTypeEnum.TYPE_39.getCode().equals(discount.getType()))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(discounts)) {
            return;
        }

        /**
         * 月享卡2.0 促销单独返回 月享卡优惠
         */
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.MonthCardDiscount monthCardDiscount = calculationDiscountResult.getMonthlyEnjoyCardDiscount();
        if (calculationDiscountResult.getDiscounts().stream().anyMatch(discount -> ActivityTypeEnum.TYPE_38.getCode().equals(discount.getType())) && null == monthCardDiscount){
            return;
        }
        shoppingCartGoodsDto.setMonthCardDiscount(monthCardDiscount);

        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsList = calculationDiscountResult.getGoods();
        if (CollectionUtils.isEmpty(goodsList)) {
            return;
        }

        Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsMap = goodsList.parallelStream()
                .collect(Collectors.toMap(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods::getCartGoodsUid, Function.identity(), (k1, k2) -> k1));

        // 匹配随单购悦享卡
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount discount = discounts.stream()
                .filter(t -> ((ActivityTypeEnum.TYPE_32.getCode().equals(t.getType()) || ActivityTypeEnum.TYPE_37.getCode().equals(t.getType())
                        || ActivityTypeEnum.TYPE_38.getCode().equals(t.getType())) && mccafeUniversalCouponCode.equals(t.getActivityCode()))).findFirst().orElse(null);

        for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoods : shoppingCartGoodsDto.getProducts()) {
            if (goodsMap.get(cartGoods.getCartGoodsUid()) == null) {
                continue;
            }
            //商品券商品
            if (StringUtils.isNotEmpty(cartGoods.getCouponCode()) ) {
                List<ActivityDiscountsDto> productActivityDiscountsDtos = new ArrayList<>();
                if(CollectionUtils.isNotEmpty(calculationDiscountResult.getGoods())) {
                    for(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods goods : calculationDiscountResult.getGoods()) {
                        if(cartGoods.getCartGoodsUid().equals(goods.getCartGoodsUid())) {
                            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> goodsDiscounts = goods.getDiscounts();
                            if(CollectionUtils.isNotEmpty(goodsDiscounts)) {
                                for(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount : goodsDiscounts) {
                                    if(goodsDiscount.getActivityCode().equals(cartGoods.getCouponCode())) {
                                        ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                                        activityDiscountsDto.setActivityCode(goodsDiscount.getActivityCode());
                                        activityDiscountsDto.setActivityName(goodsDiscount.getActivityName());
                                        activityDiscountsDto.setActivityType(goodsDiscount.getType());
                                        activityDiscountsDto.setDiscountAmount(0 - goodsDiscount.getDiscount().intValue());
                                        Integer extendType = extendTypeMap.get(goodsDiscount.getActivityCode());
                                        activityDiscountsDto.setExtendType(extendType);
                                        activityDiscountsDto.setTenderId(goodsMap.get(cartGoods.getCartGoodsUid()).getArtNo());
                                        productActivityDiscountsDtos.add(activityDiscountsDto);
                                        cartGoods.setTotalDiscountAmount(-activityDiscountsDto.getDiscountAmount());
                                        cartGoods.setSalePrice(0L);
                                        cartGoods.setActivityDiscountsDtos(productActivityDiscountsDtos);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            cartGoods.setCustomerCode(goodsMap.get(cartGoods.getCartGoodsUid()).getArtNo());
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> list = goodsMap.get(cartGoods.getCartGoodsUid()).getDiscounts();
            if (CollectionUtils.isNotEmpty(list) && discount != null) {
                ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount = list.stream()
                        .filter(t -> ((ActivityTypeEnum.TYPE_32.getCode().equals(t.getType()) || ActivityTypeEnum.TYPE_37.getCode().equals(t.getType())
                                || ActivityTypeEnum.TYPE_38.getCode().equals(t.getType())) && mccafeUniversalCouponCode.equals(t.getActivityCode()))).findFirst().orElse(null);
                if (goodsDiscount != null){
                    List<ActivityDiscountsDto> productActivityDiscountsDtos = new ArrayList<>();
                    ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                    activityDiscountsDto.setActivityCode(goodsDiscount.getActivityCode());
                    activityDiscountsDto.setActivityName(goodsDiscount.getActivityName());
                    activityDiscountsDto.setActivityType(goodsDiscount.getType());
                    activityDiscountsDto.setDiscountAmount(0 - goodsDiscount.getDiscount().intValue());
                    activityDiscountsDto.setExtendType(discount.getExtendType());
                    activityDiscountsDto.setTenderId(goodsMap.get(cartGoods.getCartGoodsUid()).getArtNo());
                    productActivityDiscountsDtos.add(activityDiscountsDto);
                    cartGoods.setTotalDiscountAmount(-activityDiscountsDto.getDiscountAmount());
                    cartGoods.setSalePrice(0L);
                    cartGoods.setActivityDiscountsDtos(productActivityDiscountsDtos);
                }
            }
        }
    }




    /**
     * 可选优惠券
     */
    public ActivityClassifyCouponBean availableCoupon( String partnerId, String storeId,String userId,String thirdPartyMemberId,String unionId,String appId
            ,  String couponCode, Integer orderType,String menuType,List<CartGoods> cartGoods) {

//        List<CartGoods> tmpCartGoods = cartGoods.parallelStream().filter(k -> StringUtils.isBlank(k.getCouponCode())).collect(Collectors.toList());
        boolean hasGoodsCoupon = false;

        // 获取会员服务的优惠券列表
        GetMemberCouponListRequestDto getMemberCouponListRequestDto = new GetMemberCouponListRequestDto(partnerId, userId);
        getMemberCouponListRequestDto.setStatusFlags(Arrays.asList(CouponStatus.STATUS_0.getCode()));
        getMemberCouponListRequestDto.setAppId(appId);
        getMemberCouponListRequestDto.setThirdPartyMemberId(thirdPartyMemberId);
        getMemberCouponListRequestDto.setUnionId(unionId);
        String tag = mcafe;
        if("saas".equals(menuType)){
            tag = mcafePickup;
        }
        getMemberCouponListRequestDto.setTag(tag);
        getMemberCouponListRequestDto.setPageNum(1);
        getMemberCouponListRequestDto.setPageSize(Integer.MAX_VALUE);
        GetMemberCouponListResponseDto.Result result = getMemberCouponList(getMemberCouponListRequestDto);
        LogUtil.debug("CouponServiceImpl_getMemberCouponList", JSON.toJSONString(getMemberCouponListRequestDto), JSON.toJSONString(result));
        if (result == null || CollectionUtils.isEmpty(result.getMemberCoupons())) {
            return null;
        }
        ActivityClassifyCouponBean availableCouponResponseVo = new ActivityClassifyCouponBean();
        // 可用优惠券信息
        List<ActivityCouponBean> usableCoupons = Lists.newArrayList();
        // 不可用优惠券信息
        List<ActivityCouponBean> disableCoupons = Lists.newArrayList();

        List<GetMemberCouponListResponseDto.Result.MemberCoupon> memberCoupons = result.getMemberCoupons();
        // 对象转map
        Map<String, GetMemberCouponListResponseDto.Result.MemberCoupon> memberCouponMap = memberCoupons.stream().collect(
                Collectors.toMap(GetMemberCouponListResponseDto.Result.MemberCoupon::getCouponCode, a -> a, (k1, k2) -> k1));
        List<String> couponCodes = Lists.newArrayList();
        memberCoupons.forEach(memberCoupon -> {
            // 只筛选小于结束时间得券
//            if (Objects.equals(memberCoupon.getCouponType(), CouponTypeEnum.TYPE_1.getCode())
//                    || Objects.equals(memberCoupon.getCouponType(), CouponTypeEnum.TYPE_3.getCode())) {
            // 只筛选小于结束时间得券
//            if (System.currentTimeMillis() < DateUtil.convert2Date(memberCoupon.getEndTime(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS).getTime()) {
//
//            }
            couponCodes.add(memberCoupon.getCouponCode());
//            }
        });

        //券码可用券校验
        List<CouponState> couponStateList = buildAvailableCoupons(cartGoods, partnerId, storeId, couponCodes);
        if (CollectionUtils.isEmpty(couponStateList)) {
            return null;
        }
        return returnSuccessAvailableCoupons(couponCode, hasGoodsCoupon, availableCouponResponseVo, usableCoupons, disableCoupons, memberCouponMap, couponStateList);
    }

    /**
     * 获取会员服务的优惠券列表
     *
     * @param getMemberCouponListRequestDto
     * @return
     */
    public GetMemberCouponListResponseDto.Result getMemberCouponList(GetMemberCouponListRequestDto getMemberCouponListRequestDto) {
        GetMemberCouponListResponseDto getMemberCouponListResponseDto = null;
        try {
            getMemberCouponListResponseDto = customerExtendClient.getMemberCouponListRequestDto(getMemberCouponListRequestDto);
        } catch (Exception ex) {
            LogUtil.error("会员服务优惠券接口调用失败","","", ex);
        }
        if (getMemberCouponListResponseDto != null && Objects.equals(getMemberCouponListResponseDto.getCode(), ResponseResult.SUCCESS.getCode())) {
            return getMemberCouponListResponseDto.getData();
        }
        return null;
    }




    public List<CouponState> buildAvailableCoupons(List<CartGoods> cartGoods, String partnerId, String storeId, List<String> couponCodes) {
//        String appSecret = getAppSecret(partnerId);
        // 最大15一提交
        int maxNum = 15;
        int count = couponCodes.size() / maxNum;
        // 计算可用不可用券
        CouponAvailableReq couponAvailableReqVo = new CouponAvailableReq();
        couponAvailableReqVo.setProviderId(partnerId);
        couponAvailableReqVo.setMerchantId(partnerId);
        couponAvailableReqVo.setStoreId(storeId);
        List<CouponProductVo> productList = Lists.newArrayList();
        // 优惠券优先级最高，根据商品原价做计算
        // 订单金额
        Long totalAmount = createProductRequest(cartGoods, productList);
        couponAvailableReqVo.setTotalAmount(Integer.valueOf(totalAmount + ""));
        couponAvailableReqVo.setProductList(productList);
        couponAvailableReqVo.setChannelCodeList(commonService.getOrgCodes(partnerId, storeId));
//        couponAvailableReqVo.setChannelIdList(commonService.getOrgIdsForCoupon(partnerId, storeId));
        couponAvailableReqVo.setStationId("999");
        couponAvailableReqVo.setOperatorId("999");
        // 构建计算SDK
        List<CouponState> couponStateList = Lists.newArrayList();
        for (int j = 0; j <= count; j++) {
            List calCouponCodes = null;
            if (j == count) {
                calCouponCodes = couponCodes.subList(maxNum * j, couponCodes.size());
            } else {
                calCouponCodes = couponCodes.subList(maxNum * j, maxNum * j + maxNum);
            }
            // 书写逻辑
            couponAvailableReqVo.setCouponCodes(calCouponCodes);
            CouponAvailableResp couponsAvailable = null;
            try {
                couponsAvailable = mCoffeeCouponClient.getCouponsAvailable(couponAvailableReqVo);
            }catch (Exception e){
                LogUtil.error("getCouponsAvailable_error",JSON.toJSONString(couponAvailableReqVo),null,e);
                throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR);
            }
            LogUtil.info("getCouponsAvailable", JSON.toJSONString(couponAvailableReqVo), JSON.toJSONString(couponsAvailable));
            if (couponsAvailable != null && Objects.equals(String.valueOf(couponsAvailable.getResult()), ResponseResult.SUCCESS.getCode())
                    && CollectionUtils.isNotEmpty(couponsAvailable.getCouponStateList())) {
                couponStateList.addAll(couponsAvailable.getCouponStateList());
            }
        }
        return couponStateList;
    }


    public List<CouponAvailableReqByCart> buildAvailableCoupons(QueryCartInfoRequestVo requestVo, List<CartGoods> cartGoods,
                                                                List<String> couponCodes){
        List<CouponAvailableReqByCart> resList = new ArrayList<>();
        CouponAvailableReqByCart res = new CouponAvailableReqByCart();
        res.setProviderId(requestVo.getPartnerId());
        res.setMerchantId(requestVo.getPartnerId());
        res.setStoreId(requestVo.getStoreId());
        res.setChannelIdList(commonService.getOrgCodes(requestVo.getPartnerId(), requestVo.getStoreId()));
//        res.setChannelIdList(commonService.getOrgIdsForCoupon(requestVo.getPartnerId(), requestVo.getStoreId()));
//        res.setChannelCodeList(commonService.getOrgCodes(requestVo.getPartnerId(), requestVo.getStoreId()));

        res.setCouponCodes(couponCodes);
        List<CouponProductVo> calculAmountProductList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(cartGoods)) {
            cartGoods.forEach(cartGood -> {
                if (!StringUtils.equals(cartGood.getSkuId(),"9999") && StringUtils.isNotEmpty(cartGood.getCouponCode())) {
                    CouponProductVo couponProductVo = new CouponProductVo();
                    couponProductVo.setAmount(cartGood.getAmount().intValue());
                    couponProductVo.setKeyProductCode(cartGood.getCustomerCode());
                    couponProductVo.setQuantity(cartGood.getQty());
                    couponProductVo.setProductId(cartGood.getGoodsId());
                    couponProductVo.setCouponCode(cartGood.getCouponCode());
                    couponProductVo.setCategoryCode(null);
                    calculAmountProductList.add(couponProductVo);
                }
            });
            res.setProductList(cartGoods);
            Long totalAmount = createProductRequest(cartGoods, calculAmountProductList);
            res.setTotalAmount(Integer.valueOf(totalAmount.toString()));
            resList.add(res);
        }
        return resList;
    }


//    public String getAppSecret(String partnerId) {
//        // 获取券服务的密钥
//        String couponAppSecret = RedisUtil.getCouponAppSecret(partnerId);
//        String appSecret = redisCache.getValue(couponAppSecret);
//        if (StringUtils.isBlank(appSecret)) {
//            GetAppKeyResponseDto getAppKeyResponseDto = cardBinClient.getAppKey(GetAppKeyRequestDto.builder().partnerId(partnerId).appId(appid).build());
//            if (Objects.equals(String.valueOf(getAppKeyResponseDto.getStatusCode()), ResponseResult.SUCCESS.getCode())
//                    && getAppKeyResponseDto.getData() != null) {
//                redisCache.save(couponAppSecret, getAppKeyResponseDto.getData().getAppKey());
//                appSecret = getAppKeyResponseDto.getData().getAppKey();
//            }
//        }
//        return appSecret;
//    }

    private ActivityClassifyCouponBean returnEmptyAvailableCoupon(ActivityClassifyCouponBean availableCouponResponseVo, List<ActivityCouponBean> usableCoupons, List<ActivityCouponBean> disableCoupons) {
        availableCouponResponseVo.setCouponNum(0);
        availableCouponResponseVo.setDisableCouponNum(0);
        availableCouponResponseVo.setUsableCouponNum(0);
        availableCouponResponseVo.setDisableCoupons(disableCoupons);
        availableCouponResponseVo.setUsableCoupons(usableCoupons);
        return availableCouponResponseVo;
    }

    private Long createProductRequest(List<CartGoods> cartGoods, List<CouponProductVo> productList) {
        Long totalAmount = 0L;
        try {
            for (CartGoods cartGood : cartGoods) {
                // 剔除商品券得商品
                if (StringUtils.isEmpty(cartGood.getSkuId()) && StringUtils.isEmpty(cartGood.getSpuId())
                        || StringUtils.equals("9999",cartGood.getSkuId())
                        || StringUtils.equals("9998",cartGood.getSkuId())) {
                    continue;
                }
                // 剔除商品券得商品,麦咖啡逻辑
                if(StringUtils.isNotEmpty(cartGood.getCouponCode())){
                    continue;
                }
                CouponProductVo product = new CouponProductVo();
                product.setKeyProductCode(cartGood.getCustomerCode());
                product.setProductId(StringUtils.isEmpty(cartGood.getSkuId()) ? cartGood.getSpuId() : cartGood.getSkuId());
                // 普通商品价格
                product.setAmount(Integer.valueOf(cartGood.getOriginalPrice() + ""));
                // 套餐价格为： 套餐价+可选商品总价格
                if (ObjectUtils.equals(GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType(), cartGood.getGoodsType())) {
                    Long finalPrice = cartGood.getFinalPrice();
                    if (CollectionUtils.isNotEmpty(cartGood.getProductGroupList())){
                        finalPrice+=cartGood.getProductGroupList().stream().mapToLong(group->group.getFinalPrice()*group.getQty()).sum();
                    }
                    product.setAmount(finalPrice.intValue());
                }
                // 数量
                product.setQuantity(cartGood.getQty());
                productList.add(product);
                totalAmount = totalAmount +product.getAmount() * cartGood.getQty();
            }
        } catch (NumberFormatException e) {
            log.error("数字转换异常:" + JSON.toJSONString(cartGoods) + ExceptionUtils.getExceptionInfo(e));
            throw new ServiceException(ResponseResult.SYSTEM_ERROR);
        }
        return totalAmount;
    }



    private ActivityClassifyCouponBean returnSuccessAvailableCoupons(String couponCode, boolean hasGoodsCoupon, ActivityClassifyCouponBean availableCouponResponseVo, List<ActivityCouponBean> usableCoupons, List<ActivityCouponBean> disableCoupons, Map<String, GetMemberCouponListResponseDto.Result.MemberCoupon> memberCouponMap, List<CouponState> couponStateList) {
        int disableCouponNum = 0;
        int usableCouponNum = 0;
        for (CouponState couponStateVo : couponStateList) {
            // 过滤0得代金券
            if (Objects.equals(couponStateVo.getType(), CouponTypeEnum.TYPE_0.getCode())) {
                continue;
            }
            // 过滤0得代金券
//            if (Objects.equals(couponStateVo.getType(), CouponTypeEnum.TYPE_1.getCode())
//                    && (couponStateVo.getOriginalPrice() == null
//                    || couponStateVo.getOriginalPrice() == 0)) {
//                continue;
//            }

            // 过滤折扣券为0折得
            if (Objects.equals(couponStateVo.getType(), CouponTypeEnum.TYPE_3.getCode())
                    && (couponStateVo.getDiscount() == null
                    || couponStateVo.getDiscount() == 0)) {
                continue;
            }
            ActivityCouponBean activityCouponBean = new ActivityCouponBean();
            activityCouponBean.setCouponCode(couponStateVo.getCouponCode());
            GetMemberCouponListResponseDto.Result.MemberCoupon memberCoupon = memberCouponMap.get(couponStateVo.getCouponCode());
            if (memberCoupon != null) {
                activityCouponBean.setCouponName(couponStateVo.getActName());
                activityCouponBean.setEndTime(memberCoupon.getEndTime());
                if (Objects.equals(couponStateVo.getType(), CouponTypeEnum.TYPE_1.getCode())) {
                    activityCouponBean.setDiscountAmount(couponStateVo.getOriginalPrice() + "");
                } else if (Objects.equals(couponStateVo.getType(), CouponTypeEnum.TYPE_3.getCode())) {
                    // TODO 折扣券 百分值10 乘以10   前端统一除以100作为操作依据
                    activityCouponBean.setDiscountAmount(couponStateVo.getDiscount() != null ? couponStateVo.getDiscount() * 10 + "" : "0");
                }
                activityCouponBean.setThresholdDesc("满" + formatAmount((couponStateVo.getMinAmount() == null ? 0 : couponStateVo.getMinAmount()) * 1.00 / 100) + "元可用");
                activityCouponBean.setActivityDesc("不与其他活动优惠同时享受。");
                activityCouponBean.setUnusedReason(couponStateVo.getMessage());
                // 详情
                GetMemberCouponListResponseVo.MemberCouponDetail detail = new GetMemberCouponListResponseVo.MemberCouponDetail();
                detail.setActivityName(memberCoupon.getCouponName());
                String startDate = "";
                String endDate = "";
                if(couponStateVo.getValidStartTime() != null && couponStateVo.getValidEndTime() != null){
                    startDate = DateUtil.convert2String(DateUtil.convert2Date(couponStateVo.getValidStartTime(), DateUtil.FORMAT_yyyyMMdd_date), DateUtil.FORMAT_yyyyMMdd_date).replace("-", ".");
                    endDate = DateUtil.convert2String(DateUtil.convert2Date(couponStateVo.getValidEndTime(), DateUtil.FORMAT_yyyyMMdd_date), DateUtil.FORMAT_yyyyMMdd_date).replace("-", ".");
                }
                detail.setEndTime(endDate);
                detail.setStartTime(startDate);
                String remark = couponStateVo.getActDesc();
                detail.setRemark(couponAdapter.getDescribeText(remark));
                if (Objects.equals(couponStateVo.getType(), CouponTypeEnum.TYPE_1.getCode())) {
                    detail.setAmountDesc("满" + formatAmount((couponStateVo.getMinAmount() == null ? 0 : couponStateVo.getMinAmount()) * 1.00 / 100) + "元减" + formatAmount((couponStateVo.getOriginalPrice() == null ? 0 : couponStateVo.getOriginalPrice()) * 1.00 / 100) + "元");
                } else if (Objects.equals(couponStateVo.getType(), CouponTypeEnum.TYPE_3.getCode())) {
                    detail.setAmountDesc("满" + formatAmount((couponStateVo.getMinAmount() == null ? 0 : couponStateVo.getMinAmount()) * 1.00 / 100) + "元" + formatAmount((couponStateVo.getDiscount() == null ? 0 : couponStateVo.getDiscount()) * 1.00 / 10) + "折");
                }
                // 设置条形码
                GetCouponBarCodeResponseVo responseVo = this.getCouponBarCode(couponStateVo.getCouponCode());
                detail.setCouponBarCode(responseVo.getBase64Image());

                activityCouponBean.setDetail(detail);
                activityCouponBean.setActivityCode(memberCoupon.getActivityCode());
                activityCouponBean.setCouponType(couponStateVo.getType());
                activityCouponBean.setDateDescribe(couponAdapter.getDateDescribe(memberCoupon.getStatus(), memberCoupon.getStartTime(), memberCoupon.getEndTime()));
                // 券状态 0 可用 1 不可用 2 限制可用
                if (Objects.equals(activityCouponBean.getCouponCode(), couponCode)) {
                    activityCouponBean.setSelected(YesOrNoEnum.YES.getCode());
                } else {
                    activityCouponBean.setSelected(YesOrNoEnum.NO.getCode());
                }
                if (hasGoodsCoupon) {
                    disableCoupons.add(activityCouponBean);
                    disableCouponNum = disableCouponNum + 1;
                } else {
                    if (Objects.equals(couponStateVo.getState(), CouponStateEnum.STATE_1.getCode())) {
                        disableCoupons.add(activityCouponBean);
                        disableCouponNum = disableCouponNum + 1;
                    } else {
                        usableCoupons.add(activityCouponBean);
                        usableCouponNum = usableCouponNum + 1;
                    }
                }
            }

        }
        availableCouponResponseVo.setCouponNum(disableCouponNum + usableCouponNum);
        availableCouponResponseVo.setDisableCouponNum(disableCouponNum);
        availableCouponResponseVo.setUsableCouponNum(usableCouponNum);
        availableCouponResponseVo.setDisableCoupons(disableCoupons);
        availableCouponResponseVo.setUsableCoupons(usableCoupons);
        return availableCouponResponseVo;
    }

    public GetCouponBarCodeResponseVo getCouponBarCode(String couponCode) {
        byte[] bytes = BarcodeUtil.generateBarCode128(couponCode, 6D, null, true, false);
        String base64Image = Base64.getEncoder().encodeToString(bytes);
        String base64Prefix = "data:image/png;base64,";
        GetCouponBarCodeResponseVo getCouponBarCodeResponseVo = new GetCouponBarCodeResponseVo();
        getCouponBarCodeResponseVo.setBase64Image(base64Prefix + base64Image);
        return getCouponBarCodeResponseVo;
    }

    private static Object formatAmount(Double amount) {
        if (amount % (amount.intValue()) == 0.0) {
            return amount.intValue();
        } else {
            return amount;
        }
    }

    public CouponPromotionVO getCouponPromotionVO(String partnerId, String storeId, String userId, String couponCode, Integer orderType){
        CouponPromotionVO couponPromotionVO = new CouponPromotionVO();
        couponPromotionVO.setPartnerId(partnerId);
        couponPromotionVO.setUserId(userId);
        couponPromotionVO.setStoreId(storeId);
        couponPromotionVO.setCouponCode(couponCode);
        couponPromotionVO.setOrderType(orderType);
        couponPromotionVO.setFlg(CouponFlag.YES.getCode());
        return couponPromotionVO;
    }

}
