package cn.freemud.service.impl;

import cn.freemud.adapter.ShoppingCartConvertAdapter;
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.activity.ShareDiscountActivityDto;
import cn.freemud.entities.dto.calculate.*;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.handle.PromotionCommonMethodHandle;
import cn.freemud.service.IPromotionService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
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.com
 *
 * @version V1.0
 * @Title:
 * @Package: cn.freemud.service.impl
 * @Descripttion:
 * @author: shuhu.hou
 * @date: 2019/4/19
 * @Copyright: 2017 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目.
 */
@Service
public class DefaultPromotionService implements IPromotionService {
    @Autowired
    private ShoppingCartConvertAdapter shoppingCartConvertAdapter;

    @Autowired
    private PromotionCommonMethodHandle promotionCommonMethodHandle;

    @Override
    public void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, UserLoginInfoDto userLoginInfoDto, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        long totalOriginalAmount = 0L;
        long totalAmount = 0L;
        long totalPackgeAmount = 0L;

        Integer totalScore = 0;
        Integer isScoreLimit = 0;
        Map<String, Goods> map = new HashMap<>();
        if(calculationDiscountResult !=null){
            map = calculationDiscountResult.getGoods().stream().collect(Collectors.toMap(Goods :: getCartGoodsUid,Function.identity(), (k1, k2) -> k1));
            totalScore = calculationDiscountResult.getTotalScore();
            isScoreLimit = calculationDiscountResult.getIsScoreLimit();
        }
        for (CartGoods cartGoods : cartGoodsList) {
            // 设置商品原价与商品现价的初始值
            long originalAmount = cartGoods.getOriginalPrice() * cartGoods.getQty();
            long amount = cartGoods.getOriginalPrice() * cartGoods.getQty();
            long packAmount = cartGoods.getPackPrice() * cartGoods.getQty();
            totalOriginalAmount += originalAmount;
            totalAmount += amount;
            totalPackgeAmount += packAmount;
            cartGoods.setOriginalAmount(originalAmount);
            cartGoods.setAmount(amount);
            cartGoods.setPackPrice(packAmount);
            if(map.get(cartGoods.getCartGoodsUid()) != null ){
                if(CollectionUtils.isNotEmpty(map.get(cartGoods.getCartGoodsUid()).getDiscounts())){
                    for (GoodsDiscount goodsDiscount : map.get(cartGoods.getCartGoodsUid()).getDiscounts()){
                        //积分商品活动处理
                        if(Objects.equals(goodsDiscount.getType(),ActivityTypeEnum.TYPE_28.getCode())){
                            cartGoods.setScore(map.get(cartGoods.getCartGoodsUid()).getScore()*map.get(cartGoods.getCartGoodsUid()).getActualGoodsNumber());
                            cartGoods.setAmount(map.get(cartGoods.getCartGoodsUid()).getRealAmount());
                        }
                    }
                }
            }
        }
        shoppingCartGoodsResponseVo.setOriginalTotalAmount(calculationDiscountResult == null ? totalOriginalAmount : calculationDiscountResult.getOriginalTotalAmount());
        shoppingCartGoodsResponseVo.setTotalAmount(calculationDiscountResult == null ? totalAmount : calculationDiscountResult.getTotalAmount());
        shoppingCartGoodsResponseVo.setNewPackAmount(totalPackgeAmount);
        shoppingCartGoodsResponseVo.setTotalScore(totalScore != null ? totalScore.longValue() : 0L );
        shoppingCartGoodsResponseVo.setIsInsufficientScore(isScoreLimit != 0);
        if (calculationDiscountResult == null) {
            shoppingCartGoodsResponseVo.setTotalDiscountAmount(0L);
        }else {
            // 需要算上配送券的优惠金额
            Integer discountAmount = 0;
            if (CollectionUtils.isNotEmpty(calculationDiscountResult.getCouponDiscounts())) {
                // 过滤出配送券金额 和 满减配送费活动金额
                CouponResults couponResults = calculationDiscountResult.getCouponDiscounts().stream().filter(c -> c.getActivityType() != null
                        && (c.getActivityType().compareTo(ActivityTypeEnum.TYPE_34.getCode()) == 0 || c.getActivityType().compareTo(ActivityTypeEnum.TYPE_14.getCode()) == 0)).findFirst().orElse(null);
                if (couponResults != null) {
                    discountAmount = couponResults.getDiscountAmount();
                }
            }
            shoppingCartGoodsResponseVo.setTotalDiscountAmount(calculationDiscountResult.getTotalDiscountAmount() + discountAmount);
        }
    }

    @Override
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {

        List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtoList = CollectionUtils.isEmpty(shoppingCartGoodsDto.getProducts()) ? new ArrayList<>() : shoppingCartGoodsDto.getProducts();
        List<ShareDiscountActivityDto> shareDiscountActivityDtoList = CollectionUtils.isEmpty(shoppingCartGoodsDto.getShareDiscountActivityDtos()) ? new ArrayList<>() : shoppingCartGoodsDto.getShareDiscountActivityDtos();
        shoppingCartGoodsDto.setProducts(cartGoodsDetailDtoList);
        shoppingCartGoodsDto.setShareDiscountActivityDtos(shareDiscountActivityDtoList);
        shoppingCartGoodsDto.setOriginalTotalAmount(shoppingCartGoodsResponseVo.getOriginalTotalAmount());
        shoppingCartGoodsDto.setTotalAmount(shoppingCartGoodsResponseVo.getTotalAmount());
        shoppingCartGoodsDto.setTotalDiscountAmount(shoppingCartGoodsResponseVo.getTotalDiscountAmount());
        // todo 包装费
        shoppingCartGoodsDto.setPackageAmount(shoppingCartGoodsResponseVo.getNewPackAmount());
        shoppingCartGoodsDto.setPackageAmountCollectType(shoppingCartGoodsResponseVo.getPackageAmountCollectType());
        //快递费
        shoppingCartGoodsDto.setDeliveryAmount(shoppingCartGoodsResponseVo.getDeliveryAmount());
        shoppingCartGoodsDto.setDiscountDeliveryAmount(shoppingCartGoodsResponseVo.getDiscountDeliveryAmount());
        shoppingCartGoodsDto.setIsDiscountDelivery(shoppingCartGoodsResponseVo.getIsDiscountDelivery());
        shoppingCartGoodsDto.setDiscountDeliveryActivityCode(shoppingCartGoodsResponseVo.getDiscountDeliveryActivityCode());
        shoppingCartGoodsDto.setDeliveryDiscountDesc(shoppingCartGoodsResponseVo.getDeliveryDiscountDesc());
        shoppingCartGoodsDto.setTotalScore(shoppingCartGoodsResponseVo.getTotalScore());
        List<CartGoods> cartGoodsList = shoppingCartGoodsResponseVo.getProducts();
        List<ApportionGoods> apportionGoodsList =
                calculationDiscountResult == null ? new ArrayList<>() : calculationDiscountResult.getApportionGoods();
        Map<String, String> duplicateGoodsMap = new HashMap<>();

        cartGoodsList.stream().collect(Collectors.groupingBy(CartGoods::getCartGoodsUid, Collectors.counting())).forEach((goodsId, count) -> {
            duplicateGoodsMap.put(goodsId,String.format("%s,0", count));
        });
        for (int i = 0, len = cartGoodsList.size(); i < len; i++) {
            CartGoods cartGoods = cartGoodsList.get(i);
            List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtos = shoppingCartConvertAdapter.convertCartGoods2DetailGoodsList(cartGoods, apportionGoodsList,duplicateGoodsMap);
            cartGoodsDetailDtoList.addAll(cartGoodsDetailDtos);
        }
        List<Discount> discounts = calculationDiscountResult == null ? new ArrayList<>() : calculationDiscountResult.getDiscounts();
        List<ActivityDiscountsDto> activityDiscountsDtos = shoppingCartGoodsDto.getActivityDiscountsDtos() == null ? new ArrayList<>() : shoppingCartGoodsDto.getActivityDiscountsDtos();
        for (Discount discount : discounts) {
            int discountAmount = (discount.getDiscount() == null) ? 0 : discount.getDiscount();
            Integer discountType = discount.getType();
            if (discountType != null && discountAmount > 0) {
                ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                activityDiscountsDto.setActivityCode(discount.getActivityCode());
                activityDiscountsDto.setActivityName(discount.getActivityName());
                activityDiscountsDto.setActivityType(discountType);
                activityDiscountsDto.setDiscountAmount(0 - discountAmount);
                activityDiscountsDtos.add(activityDiscountsDto);
            }
        }
        //过滤出加价购
        List<Discount> addMoneyDiscounts = discounts.stream().filter(discount -> ActivityTypeEnum.TYPE_81.getCode().equals(discount.getType())).collect(Collectors.toList());


        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
        if (null != calculationDiscountResult) {
            //处理加价购
            List<SubtractStockVO> stocks = filterSendGoodsStocks(calculationDiscountResult.getStocks(), shoppingCartInfoRequestVo, addMoneyDiscounts);
            if (CollectionUtils.isNotEmpty(stocks)) {
                shoppingCartGoodsDto.setStocks(stocks);
            }
        }
    }

    /**
     * 库存扣减加价购商品 要过滤掉没有换购的商品
     *
     * @param stocks                    扣减库存
     * @param shoppingCartInfoRequestVo 购物车请求信息
     * @param addMoneyDiscounts         加价购活动
     * @return 返回应该扣减的加价购商品库存
     */
    private List<SubtractStockVO> filterSendGoodsStocks(List<SubtractStockVO> stocks, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, List<Discount> addMoneyDiscounts) {
        return promotionCommonMethodHandle.filterSendGoodsStocks(stocks, shoppingCartInfoRequestVo, addMoneyDiscounts);
    }
}
