package cn.freemud.service.impl;

import cn.freemud.entities.dto.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.CheckSpqInfoResponseDto;
import cn.freemud.entities.dto.UserLoginInfoDto;
import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.CouponFlag;
import cn.freemud.enums.GoodsTypeEnum;
import cn.freemud.service.CouponService;
import cn.freemud.service.IPromotionService;
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.BeanUtils;
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
 *
 * @version V1.0
 * @Title: CouponPromotionService
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: jiaxin.liu
 * @date: 2019/4/18 10:59
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public class CouponPromotionService implements IPromotionService {
    @Autowired
    private CouponService couponService;

    @Autowired
    private AssortmentSdkService assortmentSdkService;

    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;

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

        // 当couponCode不为空时，需计算优惠价格
        long couponDiscount = 0;
        if (couponPromotionVO != null && StringUtils.isNotEmpty(couponPromotionVO.getCouponCode())
                && calculationDiscountResult != null) {
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults> couponResultsList = calculationDiscountResult.getCouponDiscounts();
            if (CollectionUtils.isNotEmpty(couponResultsList)) {
                for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponResults : couponResultsList) {
                    couponDiscount = couponDiscount + (couponResults.getDiscountAmount() == null ? 0 : couponResults.getDiscountAmount());
                }
            }
        }
        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.getCouponDiscounts().stream().map(p -> p.getCouponCode()).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(activityQueryDto.getPartnerId(), activityQueryDto.getStoreId(), userLoginInfoDto.getMemberId(), newCartList, null, null, this.shoppingCartBaseService);
                        cartGoodsList = newCartList;
                        CheckSpqInfoResponseDto checkSpqInfoResponseDto = validCouponMap.get(spqId);
                        shoppingCartGoodsResponseVo.setChanged(true);
                        shoppingCartGoodsResponseVo.setToastMsg("当前购物车金额低于【" + checkSpqInfoResponseDto.getCouponName() + "】优惠券起用金额门槛，券已自动移除购物车");
                    }
                }
            }
        }


        //循环购物车商品券
        for (CartGoods cartGoods : cartGoodsList) {
            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;
            }
            if (StringUtils.isNotBlank(couponCode)) {
                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(userLoginInfoDto.getMemberId());
                    couponPromotionVO.setStoreId(activityQueryDto.getStoreId());
                    couponPromotionVO.setPartnerId(activityQueryDto.getPartnerId());
                    couponPromotionVO.setOrderType(activityQueryDto.getOrderType());
                }
                // couponService.checkValidCoupon(couponPromotionVO, validCouponCodeLis, spqIdToCartUuid, couponCode, cartGoodsList);

                // 计算优惠信息时，已将券校验过，放在map中
                if (MapUtils.isNotEmpty(validCouponMap)) {
                    CheckSpqInfoResponseDto checkSpqInfoResponseDto = null;
                    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());
                            cartGoods.setSpecProductId(StringUtils.join(specIdList, "/"));
                            cartGoods.setSubName(StringUtils.join(specNameList, "/"));
                        } else {
                            cartGoods.setSpecProductId(checkSpqInfoResponseDto.getDefaultSpecId());
                            cartGoods.setSubName(checkSpqInfoResponseDto.getDefaultSpecName());
                            cartGoods.setExtra(checkSpqInfoResponseDto.getExtras());
                        }
                        if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                            ActivityCalculationDiscountResponseDto.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());
                    }
                }
            }
        }
    }


    @Override
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults> couponDiscounts = calculationDiscountResult == null ? new ArrayList<>() : calculationDiscountResult.getCouponDiscounts();
        List<ActivityDiscountsDto> activityDiscountsDtos = shoppingCartGoodsDto.getActivityDiscountsDtos() == null ? new ArrayList<>() : shoppingCartGoodsDto.getActivityDiscountsDtos();

        for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoods : shoppingCartGoodsDto.getProducts()) {
            if (StringUtils.isNotEmpty(cartGoods.getCouponCode())) {
                for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponDiscount : couponDiscounts) {
                    ActivityDiscountsDto activityDiscountsDto = getActivityDiscountDto(calculationDiscountResult.getApportionGoods(), couponDiscount);
                    if (activityDiscountsDto != null) {
                        ActivityDiscountsDto activityDiscountsDto1 = new ActivityDiscountsDto();
                        BeanUtils.copyProperties(activityDiscountsDto, activityDiscountsDto1);
                        activityDiscountsDto1.setDiscountAmount(-activityDiscountsDto.getDiscountAmount());

                        cartGoods.setTotalDiscountAmount(-activityDiscountsDto.getDiscountAmount());
                        cartGoods.setSalePrice(0L);
                        cartGoods.setActivityDiscountsDtos(Arrays.asList(activityDiscountsDto1));
                    }
                }
            }
        }

        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponDiscount : couponDiscounts) {
            ActivityDiscountsDto activityDiscountsDto = getActivityDiscountDto(calculationDiscountResult.getApportionGoods(), couponDiscount);
            if (activityDiscountsDto != null) {
                activityDiscountsDtos.add(activityDiscountsDto);
            }
        }
        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
    }

    private ActivityDiscountsDto getActivityDiscountDto(List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoods, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponDiscount) {
        String couponCode = couponDiscount.getCouponCode();
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods apportionGood : apportionGoods) {
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails> list = apportionGood.getApportionDetails().stream().filter(detail -> ObjectUtils.equals(couponCode, detail.getActivityCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(list)) {
                ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails apportionDetails = list.get(0);
                ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                activityDiscountsDto.setActivityCode(apportionDetails.getActivityCode());
                activityDiscountsDto.setActivityName(apportionDetails.getActivityName());
                activityDiscountsDto.setActivityType(this.convent2ActivityType(apportionDetails.getActivityType()));
                activityDiscountsDto.setDiscountAmount(0 - couponDiscount.getDiscountAmount());
                return activityDiscountsDto;
            }
        }
        return null;
    }


    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;
    }

    private Integer convent2ActivityType(Integer type) {
        Integer Hg = 33;
        if (type != null && Hg.equals(type)) {
            type = 32;
        }
        return type;
    }
}
