package cn.freemud.service.impl;

import cn.freemud.adapter.ShoppingCartConvertAdapter;
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.activity.ShareDiscountActivityDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CartGoods;
import cn.freemud.entities.vo.CouponPromotionVO;
import cn.freemud.entities.vo.CreateOrderVo;
import cn.freemud.entities.vo.ShoppingCartGoodsResponseVo;
import cn.freemud.entities.vo.ShoppingCartInfoRequestVo;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.GoodsTypeEnum;
import cn.freemud.service.IPromotionService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
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;
import java.util.stream.Stream;

/**
 * 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;

    @Override
    public void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, UserLoginInfoDto userLoginInfoDto, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        long totalOriginalAmount = 0L;
        long totalAmount = 0L;
        long totalPackgeAmount = 0L;
        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);
        }
        shoppingCartGoodsResponseVo.setOriginalTotalAmount(calculationDiscountResult == null ? totalOriginalAmount : calculationDiscountResult.getOriginalTotalAmount());
        shoppingCartGoodsResponseVo.setTotalAmount(calculationDiscountResult == null ? totalAmount : calculationDiscountResult.getTotalAmount());
        shoppingCartGoodsResponseVo.setPackAmount(totalPackgeAmount);
        shoppingCartGoodsResponseVo.setNewPackAmount(totalPackgeAmount);
        shoppingCartGoodsResponseVo.setTotalDiscountAmount(calculationDiscountResult == null ? 0L : calculationDiscountResult.getTotalDiscountAmount());
    }

    @Override
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.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());
        shoppingCartGoodsDto.setPackageAmount(shoppingCartGoodsResponseVo.getPackAmount());
        List<CartGoods> cartGoodsList = shoppingCartGoodsResponseVo.getProducts();
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoodsList =
                calculationDiscountResult == null ? new ArrayList<>() : calculationDiscountResult.getApportionGoods();
        Map<String, String> duplicateGoodsMap = new HashMap<>();

        cartGoodsList.stream().collect(Collectors.groupingBy(CartGoods::getGoodsId, 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<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discounts = calculationDiscountResult == null ? new ArrayList<>() : calculationDiscountResult.getDiscounts();
        List<ActivityDiscountsDto> activityDiscountsDtos = shoppingCartGoodsDto.getActivityDiscountsDtos() == null ? new ArrayList<>() : shoppingCartGoodsDto.getActivityDiscountsDtos();
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.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<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> addMoneyDiscounts = discounts.stream().filter(discount -> ActivityTypeEnum.TYPE_81.getCode().equals(discount.getType())).collect(Collectors.toList());


        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
        if (null != calculationDiscountResult && ((CollectionUtils.isNotEmpty(activityDiscountsDtos) || CollectionUtils.isNotEmpty(addMoneyDiscounts)))) {
            //处理加价购
            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<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> addMoneyDiscounts) {
        if (CollectionUtils.isEmpty(stocks) || CollectionUtils.isEmpty(addMoneyDiscounts)) {
            return stocks;
        }
        List<SubtractStockVO> subtractStockVOs = stocks.stream().filter(subtractStockVO -> ActivityTypeEnum.TYPE_81.getCode().equals(subtractStockVO.getActivityType())).collect(Collectors.toList());
        List<SubtractStockVO.SubtractStockGoodsVO> goodsStock = null;
        if (CollectionUtils.isNotEmpty(subtractStockVOs)) {
            SubtractStockVO subtractStockVO = subtractStockVOs.get(0);
            goodsStock = subtractStockVO.getGoodsStock();
        }
        if (null == goodsStock) {
            return stocks;
        }
        Map<String, SubtractStockVO.SubtractStockGoodsVO> mapSubstractStocks = new HashMap<>();
        if (CollectionUtils.isNotEmpty(goodsStock)) {
            mapSubstractStocks = goodsStock.stream().collect(Collectors.toMap(SubtractStockVO.SubtractStockGoodsVO::getGoodsId, Function.identity(), (k1, k2) -> k1));
        }
        //获取加价购商品
        List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = shoppingCartInfoRequestVo.getSendGoods();
        if (CollectionUtils.isNotEmpty(sendGoods)) {
            List<String> needSendGoodsId = sendGoods.stream().map(ShoppingCartInfoRequestVo.SendGoods::getGoodsId).collect(Collectors.toList());
            goodsStock.clear();
            for (String goodId : needSendGoodsId) {
                SubtractStockVO.SubtractStockGoodsVO subtractStockGoodsVO = mapSubstractStocks.get(goodId);
                if (null != mapSubstractStocks.get(goodId)) {
                    goodsStock.add(subtractStockGoodsVO);
                }
            }
        } else {
            return stocks.stream().filter(subtractStockVO -> !ActivityTypeEnum.TYPE_81.getCode().equals(subtractStockVO.getActivityType())).collect(Collectors.toList());
        }
        return stocks;
    }
}
