package cn.freemud.service.impl.calculate.promotion;

import cn.freemud.entities.dto.CheckSpqInfoResponseDto;
import cn.freemud.entities.dto.calculate.CalculationSharingDiscountResponseDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.CouponFlag;
import cn.freemud.enums.GoodsTypeEnum;
import cn.freemud.service.CouponService;
import cn.freemud.service.impl.AssortmentSdkService;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: cn.freemud.service.impl.calculate.coupon PromotionService
 * @Description: TDO 描述....
 * @author: family
 * @date: 2020/9/8
 * @Copyright: www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public class CouponSharingService {

    @Autowired
    private CouponService couponService;

    @Autowired
    private AssortmentSdkService assortmentSdkService;

    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;


    public void updateShoppingCartGoodsDiscount(CalculationSharingDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
            , List<CartGoods> cartGoodsList
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo
            , CouponPromotionVO couponPromotionVO
            ,ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, String userId, String partnerId, String storeId, Integer orderType) {
        // 用户选择了查询优惠券信息
        if (couponPromotionVO != null && ObjectUtils.equals(CouponFlag.YES.getCode(), couponPromotionVO.getFlg())) {
            List<CartGoods> tmpCartGoods = cartGoodsList.parallelStream().filter(k -> (StringUtils.isNotBlank(k.getCouponCode()) || k.getCartGoodsUid()
                    .startsWith(CommonsConstant.COUPON_PREFIX))).collect(Collectors.toList());
            // 是否存在商品券
            boolean hasGoodssCoupon = CollectionUtils.isNotEmpty(tmpCartGoods);
            String chooseCouponCode = "";
            if (StringUtils.isBlank(couponPromotionVO.getUnChooseCouponCode()) && hasGoodssCoupon){
                chooseCouponCode = tmpCartGoods.get(0).getGoodsId().substring(CommonsConstant.COUPON_PREFIX.length());
            }
            // 构建可用不可用优惠券
            ActivityClassifyCouponBean activityClassifyCouponBean = couponService.availableCoupon(cartGoodsList
                    , couponPromotionVO.getPartnerId()
                    , couponPromotionVO.getUserId()
                    , couponPromotionVO.getStoreId()
                    , couponPromotionVO
                    , hasGoodssCoupon
                    , couponPromotionVO.getOrderType()
                    , 1
                    , shoppingCartInfoRequestVo.getAppId()
                    , shoppingCartInfoRequestVo.getMenuType()
                    , chooseCouponCode
            );
            if (Objects.equals(activityClassifyCouponBean, null)) {
                // 构建一个空得订单券信息
                activityClassifyCouponBean = createEmptyActivityCouponBean();
            }
            shoppingCartGoodsResponseVo.setAvailableCoupon(activityClassifyCouponBean);
        } else {
            // 构建一个空得订单券信息
            ActivityClassifyCouponBean activityClassifyCouponBean = createEmptyActivityCouponBean();
            shoppingCartGoodsResponseVo.setAvailableCoupon(activityClassifyCouponBean);
        }

        // 当couponCode不为空时，需计算优惠价格 3代金 31折扣  32商品  33换购券
        long couponDiscount = 0;

        if (couponPromotionVO != null && (StringUtils.isNotEmpty(couponPromotionVO.getCouponCode()) || CollectionUtils.isNotEmpty(couponPromotionVO.getCouponCodes()))
                && calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
            //List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.CouponResults> couponResultsList = calculationDiscountResult.getCouponDiscounts();
            // 需要加上 配送券的  配送券 type = 34
            List<Integer> asList = Arrays.asList( ActivityTypeEnum.TYPE_3.getCode(),  ActivityTypeEnum.TYPE_31.getCode(), ActivityTypeEnum.TYPE_34.getCode());
            List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.Discount> couponResultsList = calculationDiscountResult.getDiscounts();
            couponDiscount = couponResultsList.stream().filter(d -> asList.contains(d.getType())).mapToLong(d -> d.getDiscount().longValue()).sum();
        }
        shoppingCartGoodsResponseVo.setCouponDiscount(couponDiscount);

        Map<String, CheckSpqInfoResponseDto> validCouponMap = calculationDiscountResult == null ? new HashMap<>() : calculationDiscountResult.getValidCouponMap();
        Map<String, List<String>> spqIdToCartUuid = calculationDiscountResult == null ? new HashMap<>() : calculationDiscountResult.getSpqIdToCartUuid();
        if (MapUtils.isNotEmpty(validCouponMap) && MapUtils.isNotEmpty(spqIdToCartUuid) && calculationDiscountResult != null){
            List<String> activityCodeList = calculationDiscountResult.getDiscounts().stream().map(p -> p.getActivityCode()).collect(Collectors.toList());
            for (String spqId : validCouponMap.keySet()) {
                CheckSpqInfoResponseDto sqpInfo = validCouponMap.get(spqId);
                if (!activityCodeList.contains(sqpInfo.getCouponCode())){ // 表示商品券不够启用金额
                    List<String> uuidList = spqIdToCartUuid.get(sqpInfo.getCouponCode());
                    if (CollectionUtils.isNotEmpty(uuidList)){
                        List<CartGoods> newCartList = cartGoodsList.stream().filter(p -> !uuidList.contains(p.getCartGoodsUid())).collect(Collectors.toList());
                        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, newCartList, null, null, this.shoppingCartBaseService);
                        cartGoodsList = newCartList;
                        CheckSpqInfoResponseDto checkSpqInfoResponseDto = validCouponMap.get(spqId);
                        shoppingCartGoodsResponseVo.setChanged(true);
                        shoppingCartGoodsResponseVo.setToastMsg("当前购物车金额低于【" + checkSpqInfoResponseDto.getCouponName() + "】优惠券起用金额门槛，券已自动移除购物车");
                    }
                }
            }
        }

        //循环购物车商品券
        for (CartGoods cartGoods : cartGoodsList) {
            if (StringUtils.isNotBlank(cartGoods.getCouponCode()) || cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)) {
                String couponCode = cartGoods.getCouponCode();
                boolean useCoupon = true; // 优惠券放在coupon字段而不是uuid中
                if (cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)){
                    couponCode = cartGoods.getCartGoodsUid().substring(CommonsConstant.COUPON_PREFIX.length());
                    useCoupon = false;
                }
                List<String> validCouponCodeLis = new ArrayList<>();
                if (couponPromotionVO != null && ObjectUtils.equals(CouponFlag.YES.getCode(), couponPromotionVO.getFlg())){
                    validCouponCodeLis = shoppingCartGoodsResponseVo.getAvailableCoupon().getUsableCoupons().stream().map(ActivityCouponBean::getCouponCode).collect(Collectors.toList());
                } else {
                    couponPromotionVO = new CouponPromotionVO();
                    couponPromotionVO.setUserId(userId);
                    couponPromotionVO.setStoreId(storeId);
                    couponPromotionVO.setPartnerId(partnerId);
                    couponPromotionVO.setOrderType(orderType);
                }
                // couponService.checkValidCoupon(couponPromotionVO, validCouponCodeLis, spqIdToCartUuid, couponCode, cartGoodsList);

                // 计算优惠信息时，已将券校验过，放在map中
                if (MapUtils.isNotEmpty(validCouponMap)) {
                    CheckSpqInfoResponseDto checkSpqInfoResponseDto;
                    if(useCoupon){
                        checkSpqInfoResponseDto = validCouponMap.get(couponCode + cartGoods.getSkuId());
                    } else{
                        checkSpqInfoResponseDto = validCouponMap.get(couponCode);
                    }
                    if (checkSpqInfoResponseDto != null) {
                        cartGoods.setOriginalPrice(checkSpqInfoResponseDto.getPrice());
                        cartGoods.setSpuId(checkSpqInfoResponseDto.getSpuId());
                        cartGoods.setSkuId(StringUtils.isEmpty(checkSpqInfoResponseDto.getSkuId()) ? checkSpqInfoResponseDto.getSpuId() : checkSpqInfoResponseDto.getSkuId());
                        cartGoods.setQty(cartGoods.getQty());
                        cartGoods.setCouponCode(checkSpqInfoResponseDto.getCouponCode());
                        cartGoods.setSpuName(checkSpqInfoResponseDto.getSpuName());
                        List<CartGoods.CartGoodsExtra> extra = cartGoods.getExtra();
                        if (CollectionUtils.isNotEmpty(extra)){
                            List<String> specIdList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeId).collect(Collectors.toList());
                            List<String> specNameList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeName).collect(Collectors.toList());
                            List<String> foreignSpecNameList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeForeignName).collect(Collectors.toList());
                            cartGoods.setSpecProductId(StringUtils.join(specIdList, "/"));
                            cartGoods.setSubName(StringUtils.join(specNameList, "/"));
                            cartGoods.setSubForeignName(StringUtils.join(foreignSpecNameList, "/"));
                        } else {
                            cartGoods.setSpecProductId(checkSpqInfoResponseDto.getDefaultSpecId());
                            cartGoods.setSubName(checkSpqInfoResponseDto.getDefaultSpecName());
                        }
                        cartGoods.setExtra(checkSpqInfoResponseDto.getExtras());
                        if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                            CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods discountGoods = calculationDiscountResult.getGoods()
                                    .stream()
                                    .filter(d -> cartGoods.getCartGoodsUid().equals(d.getCartGoodsUid()))
                                    .findFirst()
                                    .orElse(null);
                            if (discountGoods != null) {
                                cartGoods.setAmount(discountGoods.getRealAmount());
                            } else {
                                cartGoods.setAmount(checkSpqInfoResponseDto.getPrice() * cartGoods.getQty());
                            }
                        }
                        cartGoods.setOriginalAmount(checkSpqInfoResponseDto.getPrice() * cartGoods.getQty());
                    }
                }
            }
        }
    }

    public void equally(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsList, CouponPromotionVO couponPromotionVO) {

        if (CollectionUtils.isEmpty(cartGoodsList)) {
            return;
        }
        //循环购物车商品券
        for (CartGoods cartGoods : cartGoodsList) {
            if (StringUtils.isNotBlank(cartGoods.getCouponCode()) || cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)) {
                String couponCode = cartGoods.getCouponCode();
                boolean useCoupon = true; // 优惠券放在coupon字段而不是uuid中
                if (cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)){
                    couponCode = cartGoods.getCartGoodsUid().substring(CommonsConstant.COUPON_PREFIX.length());
                    useCoupon = false;
                }

                List<String> validCouponCodeLis = new ArrayList<>();
                // 计算优惠信息时，已将券校验过，放在map中
                Map<String, CheckSpqInfoResponseDto> validCouponMap = discountResult == null ? new HashMap<>() : discountResult.getValidCouponMap();
                Map<String, List<String>> spqIdToCartUuid = discountResult == null ? new HashMap<>() : discountResult.getSpqIdToCartUuid();
                couponPromotionVO.setFlg(0);
                // couponService.checkValidCoupon(couponPromotionVO, validCouponCodeLis, spqIdToCartUuid, couponCode, cartGoodsList);


                if (MapUtils.isNotEmpty(validCouponMap)) {
                    CheckSpqInfoResponseDto checkSpqInfoResponseDto;
                    if(useCoupon){
                        checkSpqInfoResponseDto = validCouponMap.get(couponCode + cartGoods.getSkuId());
                    } else{
                        checkSpqInfoResponseDto = validCouponMap.get(couponCode);
                    }
                    if (checkSpqInfoResponseDto != null) {
                        cartGoods.setOriginalPrice(checkSpqInfoResponseDto.getPrice());
                        cartGoods.setSpuId(checkSpqInfoResponseDto.getSpuId());
                        cartGoods.setSkuId(StringUtils.isEmpty(checkSpqInfoResponseDto.getSkuId()) ? checkSpqInfoResponseDto.getSpuId() : checkSpqInfoResponseDto.getSkuId());
                        cartGoods.setQty(cartGoods.getQty());
                        cartGoods.setCouponCode(checkSpqInfoResponseDto.getCouponCode());
                        cartGoods.setSpuName(checkSpqInfoResponseDto.getSpuName());
                        cartGoods.setSpuForeignName(checkSpqInfoResponseDto.getSpuForeignName());
                        List<CartGoods.CartGoodsExtra> extra = cartGoods.getExtra();
                        if (CollectionUtils.isNotEmpty(extra)){
                            List<String> specIdList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeId).collect(Collectors.toList());
                            List<String> specNameList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeName).collect(Collectors.toList());
                            List<String> foreignSpecNameList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeForeignName).collect(Collectors.toList());
                            cartGoods.setSpecProductId(StringUtils.join(specIdList, "/"));
                            cartGoods.setSubName(StringUtils.join(specNameList, "/"));
                            cartGoods.setSubForeignName(StringUtils.join(foreignSpecNameList, "/"));
                        } else {
                            cartGoods.setSpecProductId(checkSpqInfoResponseDto.getDefaultSpecId());
                            cartGoods.setSubName(checkSpqInfoResponseDto.getDefaultSpecName());
                            cartGoods.setSubForeignName(checkSpqInfoResponseDto.getDefaultForeignSpecName());
                            cartGoods.setExtra(checkSpqInfoResponseDto.getExtras());
                        }
                        if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                            CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods discountGoods = discountResult.getGoods()
                                    .stream()
                                    .filter(d -> cartGoods.getCartGoodsUid().equals(d.getCartGoodsUid()))
                                    .findFirst()
                                    .orElse(null);
                            if (discountGoods != null) {
                                cartGoods.setAmount(discountGoods.getRealAmount());
                            } else {
                                cartGoods.setAmount(checkSpqInfoResponseDto.getPrice());
                            }
                        }
                        cartGoods.setOriginalAmount(checkSpqInfoResponseDto.getPrice());
                    }
                }
            }
        }

    }

    public ActivityClassifyCouponBean createEmptyActivityCouponBean() {
        ActivityClassifyCouponBean activityClassifyCouponBean = new ActivityClassifyCouponBean();
        activityClassifyCouponBean.setCouponNum(0);
        activityClassifyCouponBean.setDisableCouponNum(0);
        activityClassifyCouponBean.setUsableCouponNum(0);
        activityClassifyCouponBean.setDisableCoupons(Lists.newArrayList());
        activityClassifyCouponBean.setUsableCoupons(Lists.newArrayList());
        return activityClassifyCouponBean;
    }
}
