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

import cn.freemud.adapter.ShoppingCartConvertAdapter;
import cn.freemud.adapter.ShoppingCartMccafeAdapter;
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.GoodsTypeEnum;
import org.apache.commons.collections4.CollectionUtils;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

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

    @Autowired
    private ShoppingCartConvertAdapter shoppingCartConvertAdapter;
    @Autowired
    private ShoppingCartMccafeAdapter shoppingCartMccafeAdapter;

    public void updateShoppingCartGoodsDiscount(ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {

        List<CartGoods> setMealProducts = cartGoodsList.stream().filter(cartGoods -> ObjectUtils.equals(GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType(), cartGoods.getGoodsType())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(setMealProducts)) {
            return;
        }
        //套餐可选商品现价
        long productGroupTotalAmount = 0L;
        // 存储当前享受限时特价折扣的商品数量
        Map<String, Integer> numberMap = new HashMap<>();
        // 当前商品行现价
        Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsMap = calculationDiscountResult.getGoods().parallelStream()
                .collect(Collectors.toMap(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods::getGoodsId, Function.identity(), (k1, k2) -> k1));

        // 设置商品原价与商品现价的初始值
        for (CartGoods cartGoods : cartGoodsList) {
            if(!ObjectUtils.equals(GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType(), cartGoods.getGoodsType())){
                continue;
            }
//            cartGoods.setOriginalAmount(cartGoods.getOriginalPrice() * cartGoods.getQty());
            cartGoods.setPackPrice(cartGoods.getPackPrice() * cartGoods.getQty());
            // 可选商品现总价
            productGroupTotalAmount = 0l;
            long productGroupAmount =
                    null == cartGoods.getProductGroupList() ? 0 :
                            cartGoods.getProductGroupList().stream().mapToLong(t -> (null != t.getFinalPrice() ?
                                    t.getFinalPrice():0) * (null != t.getQty() ? t.getQty():0)).sum();
            productGroupTotalAmount += productGroupAmount * cartGoods.getQty();

            // 固定商品现总价
            long productComboAmount = cartGoods.getProductComboList().stream().mapToLong(t -> (null != t.getFinalPrice() ?
                    t.getFinalPrice():0) * (null != t.getQty() ? t.getQty():0)).sum();
            long productComboTotalAmount = productComboAmount * cartGoods.getQty();

            long materialPrice = 0l;
            //套餐固定商品加料
            if(CollectionUtils.isNotEmpty(cartGoods.getProductComboList())){
                for (CartGoods.ComboxGoods comboxGoods : cartGoods.getProductComboList()){
                    Long comboxmaterialPrice = 0L;
                    if(CollectionUtils.isNotEmpty(comboxGoods.getProductMaterialList())){
                        for (CartGoods.MaterialGoods materialGoods : comboxGoods.getProductMaterialList()){
                            comboxmaterialPrice+= null !=  materialGoods.getFinalPrice() ? materialGoods.getFinalPrice() * cartGoods.getQty() : 0;
                        }
                    }
                    comboxGoods.setAmount((null == comboxGoods.getAmount() ? 0 :
                            comboxGoods.getAmount())+comboxmaterialPrice);
                    materialPrice = materialPrice + comboxmaterialPrice;
                }
            }


            Long amount = null != cartGoods.getFinalPrice() ? cartGoods.getFinalPrice()*cartGoods.getQty() + productGroupTotalAmount + materialPrice :
                    productGroupTotalAmount + productComboTotalAmount + materialPrice;
            Long comboOriginalPriceAmount = null != cartGoods.getOriginalAmount() ? cartGoods.getOriginalAmount() :
                    productComboTotalAmount;
            cartGoods.setOriginalAmount(productGroupTotalAmount + comboOriginalPriceAmount + materialPrice);
            cartGoods.setOriginalPrice(null != cartGoods.getOriginalPrice() ? cartGoods.getOriginalPrice() :
                    productComboTotalAmount);
            cartGoods.setAmount(amount);
            cartGoods.setFinalPrice(null != cartGoods.getFinalPrice() ? cartGoods.getFinalPrice() :
                    productComboTotalAmount);

            // 套餐（固定商品）现价
//            String toastMsg = getTotalAmount(cartGoods, productGroupAmount, numberMap, goodsMap);
//            if (StringUtils.isNotEmpty(toastMsg)) {
//                shoppingCartGoodsResponseVo.setToastMsg(toastMsg);
//            }

        }

//        long totalFinalPrice = setMealProducts.stream().mapToLong(product -> product.getFinalPrice() * product.getQty()).sum();
//        long totalOriginalPrice = setMealProducts.stream().mapToLong(product -> product.getOriginalPrice() * product.getQty()).sum();

        //总原价=促销优惠 - 套餐finalPrice + 套餐原价
//        shoppingCartGoodsResponseVo.setOriginalTotalAmount(shoppingCartGoodsResponseVo.getOriginalTotalAmount() - totalFinalPrice + totalOriginalPrice);
        //总现价=促销现总价 + 可选商品现总价
//        shoppingCartGoodsResponseVo.setTotalAmount(shoppingCartGoodsResponseVo.getTotalAmount() + productGroupTotalAmount);
        //总优惠=促销总优惠 + (套餐总原件 - 套餐总finalPrice - 可选商品总售价)
//        shoppingCartGoodsResponseVo.setTotalDiscountAmount(shoppingCartGoodsResponseVo.getTotalDiscountAmount() + totalOriginalPrice - totalFinalPrice - productGroupTotalAmount);
    }


    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto) {
        //套餐商品总优惠
        Integer totalDiscountAmount = 0;
        List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtos = shoppingCartGoodsDto.getProducts();
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoods = calculationDiscountResult == null ? new ArrayList<>()
                : calculationDiscountResult.getApportionGoods();
        // key为：goodsId；value以逗号分割：0为goodsId分组对应的数量，value为已计算的折扣金额
        //此map是为了促销除不尽时，拆商品行所用，例如，3份折扣10元
        Map<String, String> duplicateGoodsMap = new HashMap<>();
        shoppingCartGoodsResponseVo.getProducts().stream().filter(product->ObjectUtils.equals(GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType(), product.getGoodsType())).collect(Collectors.groupingBy(CartGoods::getGoodsId, Collectors.counting())).forEach((goodsId, count) -> {
            duplicateGoodsMap.put(goodsId,String.format("%s,0", count));
        });
        // 套餐优惠明细
        for (CartGoods cartGoods : shoppingCartGoodsResponseVo.getProducts()) {
            if (ObjectUtils.equals(GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType(), cartGoods.getGoodsType())) {
                // discountAmount=(套餐原价-套餐售价)*数量
                // productGroupDiscountAmount=可选商品现价总和
                // discountAmount-productGroupDiscountAmount:  当前商品行套餐商品总优惠= 套餐原总价-套餐现总价-套餐可选商品的现总价
//                int discountAmount = (cartGoods.getOriginalPrice().intValue() - cartGoods.getFinalPrice().intValue()) * cartGoods.getQty();
                int productGroupDiscountAmount = cartGoods.getProductGroupList().stream().mapToInt(t -> t.getFinalPrice().intValue() * t.getQty()).sum();
//                totalDiscountAmount += discountAmount - productGroupDiscountAmount * cartGoods.getQty();
                // 添加套餐父商品
                ShoppingCartGoodsDto.CartGoodsDetailDto parentCartGoods = shoppingCartMccafeAdapter.convertCartGoods2DetailGoods(cartGoods, apportionGoods,duplicateGoodsMap);
//                parentCartGoods.setTotalDiscountAmount(parentCartGoods.getTotalDiscountAmount()+ cartGoods.getOriginalAmount().intValue() - cartGoods.getAmount().intValue());
//                parentCartGoods.getActivityDiscountsDtos().add(getActivityDiscountsDto(discountAmount - productGroupDiscountAmount * cartGoods.getQty()));
                // 添加套餐固定商品&可选商品: 做均摊
                parentCartGoods.setComboProducts(shoppingCartMccafeAdapter.convertComboxGoods2DetailGoods(cartGoods,parentCartGoods.getTotalDiscountAmount()));
                cartGoodsDetailDtos.add(parentCartGoods);
            }
        }

//        //订单级别，套餐优惠活动
//        if (totalDiscountAmount > 0) {
//            shoppingCartGoodsDto.getActivityDiscountsDtos().add(getActivityDiscountsDto(-totalDiscountAmount));
//        }
    }

    private ActivityDiscountsDto getActivityDiscountsDto(Integer totalDiscountAmount) {
        ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
        activityDiscountsDto.setActivityCode("setMeal");
        activityDiscountsDto.setActivityName("套餐商品优惠");
        activityDiscountsDto.setActivityType(211);
        activityDiscountsDto.setDiscountAmount(totalDiscountAmount);
        return activityDiscountsDto;
    }

    /**
     * 促销活动有份数限制时，计算当前商品行总现价
     * 当超出份数限制，提示：该商品限 N 份优惠 超出按照原价计算哦
     *
     * @param cartGoods
     * @param productGroupAmount
     * @param numberMap
     * @param goodsMap
     * @return
     */
    private String getTotalAmount(CartGoods cartGoods, long productGroupAmount, Map<String, Integer> numberMap, Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodsMap) {

        if (goodsMap.isEmpty()||goodsMap.get(cartGoods.getGoodsId()).getDiscountAmount() == 0) {
            cartGoods.setAmount((cartGoods.getFinalPrice() + productGroupAmount) * cartGoods.getQty());
            return "";
        }
        if (numberMap.get(cartGoods.getGoodsId()) == null) {
            int actualGoodsNumber = goodsMap.get(cartGoods.getGoodsId()).getDiscounts().stream().mapToInt(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount::getActualGoodsNumber)
                    .min().orElse(goodsMap.get(cartGoods.getGoodsId()).getGoodsQuantity());
            numberMap.put(cartGoods.getGoodsId(), actualGoodsNumber);
        }
        // 可优惠数量
        Integer number = numberMap.get(cartGoods.getGoodsId());
        if (number > 0) {
            Long nowPrice = goodsMap.get(cartGoods.getGoodsId()).getNowPrice();
            //套餐固定商品价格
            long productComboxAmount = cartGoods.getQty() > number ? number * nowPrice + (cartGoods.getQty() - number) * cartGoods.getFinalPrice() : cartGoods.getQty() * nowPrice;
            cartGoods.setAmount(productComboxAmount + productGroupAmount * cartGoods.getQty());
            //设置剩余优惠数量
            numberMap.put(cartGoods.getGoodsId(), number - cartGoods.getQty());
            return number - cartGoods.getQty() < 0 ? "该商品限" + goodsMap.get(cartGoods.getGoodsId()).getActualGoodsNumber() + "份优惠 超出按照原价计算哦" : "";
        } else {
            cartGoods.setAmount((cartGoods.getFinalPrice() + productGroupAmount) * cartGoods.getQty());
            return "该商品限" + goodsMap.get(cartGoods.getGoodsId()).getActualGoodsNumber() + "份优惠 超出按照原价计算哦";
        }
    }

}
