package cn.freemud.service.impl;

import cn.freemud.adapter.PromotionAdapter;
import cn.freemud.entities.dto.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.promotion.*;
import cn.freemud.entities.dto.shoppingCart.ActivityDiscountsDto;
import cn.freemud.entities.vo.CartGoods;
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 updateDiscountApportion(ShoppingCartGoodsResponse shoppingCartGoodsResponse, OrderBeanRequest request, CalculationDiscountResultDto calculationDiscountResult, CouponPromotionDto couponPromotionDto, ActivityQueryDto activityQueryDto,Boolean isApportion) {
        if (calculationDiscountResult == null || CollectionUtils.isEmpty(calculationDiscountResult.getDiscounts())
                || CollectionUtils.isEmpty(shoppingCartGoodsResponse.getProducts())
                || !calculationDiscountResult.getDiscounts().stream().anyMatch(discount -> ActivityTypeEnum.TYPE_2.getCode().equals(discount.getType()))) {
            return;
        }
        List<CalculationDiscountGoodsDto> goodsList = calculationDiscountResult.getGoods();
        if (CollectionUtils.isEmpty(goodsList)) {
            return;
        }
        Map<String, CalculationDiscountGoodsDto> goodsMap = goodsList.parallelStream()
                .collect(Collectors.toMap(CalculationDiscountGoodsDto::getGoodsId, Function.identity(), (k1, k2) -> k1));
        // 存储当前享受限时特价折扣的商品数量，key:goodsId; value:可享受数量
        Map<String, Integer> numberMap = new HashMap<>();
        List<ShoppingCartGoodsResponse.CartGoodsDetailDto> products = shoppingCartGoodsResponse.getProducts();

        this.setToastMsg(shoppingCartGoodsResponse, products, goodsMap);

        for (ShoppingCartGoodsResponse.CartGoodsDetailDto product : products) {
            CalculationDiscountGoodsDto goods;
            if ((goods = goodsMap.get(product.getProductId())) == null) {
                continue;
            }
            CalculationGoodsActivityDto goodsDiscount =null;
            if (isApportion){
                goodsDiscount = getGoodsDiscount(goods.getDiscounts(), ActivityTypeEnum.TYPE_2);
            }
            if (goodsDiscount == null) {
                continue;
            }
            if (numberMap.get(product.getProductId()) == null) {
                numberMap.put(product.getProductId(), goods.getActualGoodsNumber());
            }
            Integer actualGoodsNumber = numberMap.get(product.getProductId());
            if (actualGoodsNumber > 0) {
                // 重新计算单品特价折扣
                List<CalculationGoodsActivityDto> discounts = goods.getDiscounts();
                Integer actual = 0;
                for (CalculationGoodsActivityDto dto: discounts) {
                    if (ObjectUtils.equals(dto.getType(),ActivityTypeEnum.TYPE_2.getCode())){
                        actual += dto.getDiscount();
                    }
                }
                Integer totalDiscountAmount = product.getQty() > actualGoodsNumber ? actual * actualGoodsNumber / goods.getActualGoodsNumber() : actual * product.getQty() / goods.getActualGoodsNumber();
                ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                activityDiscountsDto.setActivityCode(goodsDiscount.getActivityCode());
                activityDiscountsDto.setActivityName(goodsDiscount.getActivityName());
                activityDiscountsDto.setActivityType(ActivityTypeEnum.TYPE_2.getCode());
                activityDiscountsDto.setDiscountAmount(totalDiscountAmount);
                product.getActivityDiscountsDtos().add(activityDiscountsDto);
                PromotionAdapter.updateCartGoodsDetail(product, product.getTotalDiscountAmount() + totalDiscountAmount);
                numberMap.put(product.getProductId(), actualGoodsNumber - product.getQty());
            }
        }
    }

    public void setToastMsg(ShoppingCartGoodsResponse shoppingCartGoodsResponse, List<ShoppingCartGoodsResponse.CartGoodsDetailDto> products, Map<String, CalculationDiscountGoodsDto> goodsMap) {
        String toastMsg = null;
        // 存储当前享受限时特价折扣的商品数量，key:goodsId; value:可享受数量
        Map<String, Integer> numberMap = new HashMap<>();
        for (ShoppingCartGoodsResponse.CartGoodsDetailDto cartGoods : products) {
            CalculationDiscountGoodsDto goods;
            if ((goods = goodsMap.get(cartGoods.getProductId())) == null) {
                continue;
            }
            CalculationGoodsActivityDto goodsDiscount = getGoodsDiscount(goods.getDiscounts(), ActivityTypeEnum.TYPE_2);
            if (goodsDiscount == null) {
                continue;
            }
            if(goodsDiscount.getActualGoodsNumber() < cartGoods.getQty()) {
                if (StringUtils.isEmpty(toastMsg)) {
                    toastMsg = "该商品限" + goodsDiscount.getActualGoodsNumber() + "份优惠 超出按照原价计算哦";
                }
            }
        }
        if (StringUtils.isNotBlank(toastMsg)) {
            shoppingCartGoodsResponse.setToastMsg(toastMsg);
        }
    }

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

}
