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

import cn.freemud.entities.dto.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CartGoods;
import cn.freemud.entities.vo.CreateOrderVo;
import cn.freemud.entities.vo.ShoppingCartGoodsResponseVo;
import cn.freemud.entities.vo.ShoppingCartInfoRequestVo;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
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.*;
import java.util.function.Function;
import java.util.stream.Collectors;

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

@Service
public class TimeSaleCalculation {


    /**
     * 限时特价
     *
     * @return
     */
    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_2.getCode().equals(discount.getType())
                ||(ActivityTypeEnum.TYPE_21.getCode().equals(discount.getType())) || (ActivityTypeEnum.TYPE_23.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));
        // 存储当前享受限时特价折扣的商品数量，key:goodsId; value:可享受数量
        Map<String, Integer> numberMap = new HashMap<>();
        List<Integer> discounts = Arrays.asList(ActivityTypeEnum.TYPE_2.getCode(), ActivityTypeEnum.TYPE_21.getCode(),ActivityTypeEnum.TYPE_23.getCode());
        for (CartGoods cartGoods : cartGoodsList) {
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods goods;
            if ((goods = goodsMap.get(cartGoods.getGoodsId())) == null) {
                continue;
            }
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount = getGoodsDiscount(goods.getDiscounts(), discounts);
            if (goodsDiscount == null) {
                continue;
            }
            // 商品参与限时特价返回，用于前端显示特价标签
            if(discounts.contains(ActivityTypeEnum.TYPE_2.getCode()) || discounts.contains(ActivityTypeEnum.TYPE_21.getCode())){
                cartGoods.setActivityType(ActivityTypeEnum.TYPE_2.getCode());
            }
            cartGoods.setActivityNumber(goodsDiscount.getActualGoodsNumber());
            // 享受限时特价折扣的商品数量
            Integer specialActualGoodsNumber = null;
            // 商品现价
            Long goodsNowPrice = cartGoods.getOriginalPrice() - goodsDiscount.getDiscount() / goodsDiscount.getActualGoodsNumber();
            // numberMap用于暂存当前商品行可享受限时特价折扣的商品数量
            if ((specialActualGoodsNumber = numberMap.get(goods.getGoodsId())) == null) {
                numberMap.put(goods.getGoodsId(), specialActualGoodsNumber = goodsDiscount.getActualGoodsNumber());
            }
            //若可享受数量>=当前商品行的商品数量
            if (specialActualGoodsNumber - cartGoods.getQty() >= 0) {
                cartGoods.setAmount(goodsNowPrice * cartGoods.getQty());
            } else {
                //总价=可享受数量*优惠后单价+（当前商品行的商品数量-可享受数量）*商品原价
                cartGoods.setAmount(specialActualGoodsNumber > 0 ? specialActualGoodsNumber * goodsNowPrice + (cartGoods.getQty() - specialActualGoodsNumber) * cartGoods.getOriginalPrice()
                        : goods.getOriginalPrice() * cartGoods.getQty());
                if (StringUtils.isEmpty(toastMsg)) {
                    toastMsg = "该商品限" + goodsDiscount.getActualGoodsNumber() + "份优惠 超出按照原价计算哦";
                }
            }
            numberMap.put(goods.getGoodsId(), specialActualGoodsNumber - cartGoods.getQty());
        }
        if (StringUtils.isNotBlank(toastMsg)) {
            shoppingCartGoodsResponseVo.setToastMsg(toastMsg);
        }
    }


    /**
     * 商品均摊
     */
    public void updateShoppingCartGoodsApportion(ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto){
        if (calculationDiscountResult == null || CollectionUtils.isEmpty(calculationDiscountResult.getDiscounts()) || !calculationDiscountResult.getDiscounts().stream().anyMatch(discount -> (ActivityTypeEnum.TYPE_2.getCode().equals(discount.getType())
                || ActivityTypeEnum.TYPE_21.getCode().equals(discount.getType()) || ActivityTypeEnum.TYPE_23.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(), Arrays.asList(ActivityTypeEnum.TYPE_2.getCode(), ActivityTypeEnum.TYPE_21.getCode(), ActivityTypeEnum.TYPE_23.getCode()));
            if (goodsDiscount == null) {
                continue;
            }
            //活动商品键位编号为空
            if(CollectionUtils.isNotEmpty(goods.getDiscounts()) && StringUtils.isBlank(goods.getArtNo())){
                throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
            }
            cartGoods.setCustomerCode(goods.getArtNo());
            Long totalDiscountAmount = goodsDiscount.getDiscount();
            ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
            activityDiscountsDto.setActivityCode(goodsDiscount.getActivityCode());
            activityDiscountsDto.setActualActivityGoodsNumber(goodsDiscount.getActualGoodsNumber());
            activityDiscountsDto.setActivityName(goodsDiscount.getActivityName());
            if(ActivityTypeEnum.TYPE_23.getCode() == goodsDiscount.getType()){
                activityDiscountsDto.setActivityType(ActivityTypeEnum.TYPE_23.getCode());
            }else {
                activityDiscountsDto.setActivityType(ActivityTypeEnum.TYPE_2.getCode());
            }
            activityDiscountsDto.setDiscountAmount(totalDiscountAmount.intValue());
            cartGoods.getActivityDiscountsDtos().add(activityDiscountsDto);
            cartGoods.setTotalDiscountAmount(cartGoods.getTotalDiscountAmount() + totalDiscountAmount.intValue());
//            if (numberMap.get(cartGoods.getSkuId()) == null) {
//                numberMap.put(cartGoods.getSkuId(), goodsDiscount.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();
//
//                numberMap.put(cartGoods.getSkuId(), actualGoodsNumber - cartGoods.getQty());
//            } else {
//                cartGoods.setTotalDiscountAmount(0);
//            }

        }
    }



    /**
     * 获取指定促销类型的GoodsDiscount
     *
     * @param goodsDiscountList
     * @param discounts
     * @return
     */
    private ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount getGoodsDiscount(List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount> goodsDiscountList, List<Integer> discounts) {
        if (CollectionUtils.isEmpty(goodsDiscountList)) {
            return null;
        }
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount goodsDiscount : goodsDiscountList) {
            if (discounts.contains(goodsDiscount.getType())) {
                return goodsDiscount;
            }
        }
        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;
    }



}
