package cn.freemud.service.impl;

import cn.freemud.entities.dto.ActivityCalculationDiscountResponseDto;
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.ActivityTypeEnum;
import cn.freemud.service.IPromotionService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: TimeSalePromotionService
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: jiaxin.liu
 * @date: 2019/4/18 10:58
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public class TimeSalePromotionService implements IPromotionService {

    @Override
    public void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, UserLoginInfoDto userLoginInfoDto, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        if (calculationDiscountResult == null || CollectionUtils.isEmpty(calculationDiscountResult.getDiscounts()) || !calculationDiscountResult.getDiscounts().stream().anyMatch(discount -> ActivityTypeEnum.TYPE_2.getCode().equals(discount.getType()))) {
            return;
        }
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsList = calculationDiscountResult.getGoods();
        if (CollectionUtils.isEmpty(goodsList)) {
            return;
        }
        String toastMsg = null;
        Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsMap = goodsList.parallelStream()
                .collect(Collectors.toMap(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods::getGoodsId, Function.identity(), (k1, k2) -> k1));
        // 存储当前享受限时特价折扣的商品数量
        Map<String, Integer> numberMap = new HashMap<>();
        for (CartGoods cartGoods : cartGoodsList) {
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods goods;
            if ((goods = goodsMap.get(cartGoods.getGoodsId())) == null) {
                continue;
            }
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount = getGoodsDiscount(goods.getDiscounts(), ActivityTypeEnum.TYPE_2);
            if (goodsDiscount == null) {
                continue;
            }
            // 设置商品原价与商品现价的初始值
            cartGoods.setOriginalAmount(goods.getOriginalPrice() * cartGoods.getQty());
            cartGoods.setAmount(goods.getOriginalPrice() * cartGoods.getQty() - goods.getDiscountAmount());
            // 享受限时特价折扣的商品数量
            Integer specialActualGoodsNumber = null;
            // 商品现价
            Long goodsNowPrice = null;
            // 获取享受限时特价折扣的商品数量与商品现价
            if (CollectionUtils.isNotEmpty(calculationDiscountResult.getApportionGoods())) {
                ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods apportionGoods = getApportionGoods(cartGoods, calculationDiscountResult.getApportionGoods(), ActivityTypeEnum.TYPE_2);
                if (apportionGoods != null) {
                    specialActualGoodsNumber = apportionGoods.getGoodsQuantity();
                    ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails apportionDetails = getApportionDetails(apportionGoods.getApportionDetails(), ActivityTypeEnum.TYPE_2);
                    if (apportionDetails != null) {
                        goodsNowPrice = apportionDetails.getGoodsNowPrice();
                    }
                }
            }
            // 获取享受限时特价折扣的商品数量失败，重新计算=商品折扣总金额/(商品原价-商品现价)
            if (specialActualGoodsNumber == null) {
                specialActualGoodsNumber = (int) (goodsDiscount.getDiscount() / (goods.getOriginalPrice() - goods.getNowPrice()));
            }
            // 获取商品现价失败，从优惠信息中获取
            if (goodsNowPrice == null) {
                goodsNowPrice = goods.getNowPrice();
            }
            // Map中存有上次计算剩余的享受限时特价折扣的商品数量
            if (numberMap.get(goods.getGoodsId()) != null) {
                specialActualGoodsNumber = numberMap.get(goods.getGoodsId());
            }
            if (specialActualGoodsNumber >= cartGoods.getQty()) {
                numberMap.put(goods.getGoodsId(), specialActualGoodsNumber - cartGoods.getQty());
                specialActualGoodsNumber = cartGoods.getQty();
            } else {
                numberMap.put(goods.getGoodsId(), 0);
            }
            cartGoods.setAmount(goodsNowPrice * specialActualGoodsNumber + goods.getOriginalPrice() * (cartGoods.getQty() - specialActualGoodsNumber));
            if (StringUtils.isEmpty(toastMsg) && specialActualGoodsNumber < goods.getGoodsQuantity()) {
                // 存在限时特价折扣
                toastMsg = "该商品限" + specialActualGoodsNumber + "份优惠 超出按照原价计算哦";

            }
        }
        if (StringUtils.isNotBlank(toastMsg)) {
            shoppingCartGoodsResponseVo.setToastMsg(toastMsg);
        }
    }

    @Override
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        if (calculationDiscountResult == null || CollectionUtils.isEmpty(calculationDiscountResult.getDiscounts()) || !calculationDiscountResult.getDiscounts().stream().anyMatch(discount -> ActivityTypeEnum.TYPE_2.getCode().equals(discount.getType()))) {
            return;
        }
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsList = calculationDiscountResult.getGoods();
        if (CollectionUtils.isEmpty(goodsList)) {
            return;
        }
        // 商品实际享受优惠的数量：  key:skuId;  value:实际数量
        Map<String, Integer> numberMap = new HashMap<>();
        Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsMap = goodsList.parallelStream()
                .collect(Collectors.toMap(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods::getGoodsId, Function.identity(), (k1, k2) -> k1));


        for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoods : shoppingCartGoodsDto.getProducts()) {
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods goods;
            // 特价商品没有匹配 或 加价购商品 直接跳出循环
            if ((goods = goodsMap.get(cartGoods.getSkuId())) == null || ObjectUtils.equals(ActivityTypeEnum.TYPE_81.getCode(), cartGoods.getActivityType())) {
                continue;
            }
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount = getGoodsDiscount(goods.getDiscounts(), ActivityTypeEnum.TYPE_2);
            if (goodsDiscount == null) {
                continue;
            }

            if (numberMap.get(cartGoods.getSkuId()) == null) {
                numberMap.put(cartGoods.getSkuId(), goods.getActualGoodsNumber());
            }
            Integer actualGoodsNumber = numberMap.get(cartGoods.getSkuId());
            if (actualGoodsNumber > 0) {
                Long totalDiscountAmount = cartGoods.getQty() > actualGoodsNumber ? goods.getDiscountAmount() * actualGoodsNumber / goods.getActualGoodsNumber() : goods.getDiscountAmount() * cartGoods.getQty() / goods.getActualGoodsNumber();
                ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                activityDiscountsDto.setActivityCode(goodsDiscount.getActivityCode());
                activityDiscountsDto.setActivityName(goodsDiscount.getActivityName());
                activityDiscountsDto.setActivityType(ActivityTypeEnum.TYPE_2.getCode());
                activityDiscountsDto.setDiscountAmount(totalDiscountAmount.intValue());
                cartGoods.getActivityDiscountsDtos().add(activityDiscountsDto);
                cartGoods.setTotalDiscountAmount(cartGoods.getTotalDiscountAmount()+ totalDiscountAmount.intValue());
                numberMap.put(cartGoods.getSkuId(), actualGoodsNumber - cartGoods.getQty());
            } else {
                cartGoods.setTotalDiscountAmount(0);
            }

        }
    }

    /**
     * 获取指定促销类型的GoodsDiscount
     *
     * @param goodsDiscountList
     * @param type
     * @return
     */
    private ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount getGoodsDiscount(List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> goodsDiscountList, ActivityTypeEnum type) {
        if (CollectionUtils.isEmpty(goodsDiscountList)) {
            return null;
        }
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount : goodsDiscountList) {
            if (Objects.equals(goodsDiscount.getType(), type.getCode())) {
                return goodsDiscount;
            }
        }
        return null;
    }

    /**
     * 获取指定促销类型的ApportionGoods
     *
     * @param cartGoods
     * @param apportionGoodsList
     * @param type
     * @return
     */
    private ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods getApportionGoods(CartGoods cartGoods, List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoodsList, ActivityTypeEnum type) {
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods apportionGoods : apportionGoodsList) {
            if (!StringUtils.equals(apportionGoods.getGoodsId(), cartGoods.getGoodsId())) {
                continue;
            }
            // 特价均摊信息没有促销类型，以此需要使用详情中促销类型
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails apportionDetails = getApportionDetails(apportionGoods.getApportionDetails(), type);
            if (apportionDetails == null) {
                continue;
            }
            return apportionGoods;
        }
        return null;
    }

    /**
     * 获取指定促销类型的ApportionDetails
     *
     * @param apportionDetailsList
     * @param type
     * @return
     */
    private ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails getApportionDetails(List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails> apportionDetailsList, ActivityTypeEnum type) {
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails apportionDetails : apportionDetailsList) {
            if (Objects.equals(apportionDetails.getActivityType(), ActivityTypeEnum.TYPE_2.getCode())) {
                return apportionDetails;
            }
        }
        return null;
    }
}
