package cn.freemud.service.impl.calculate;

import cn.freemud.constant.ShoppingCartConstant;
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.calculate.CalculationSharingDiscountResponseDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.service.impl.calculate.promotion.AdditionSharingService;
import cn.freemud.service.impl.calculate.promotion.DeliverySharingService;
import cn.freemud.service.impl.calculate.promotion.GiftSharingService;
import cn.freemud.service.impl.calculate.promotion.ScoreSharingService;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
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
 *
 * @Title: cn.freemud.service.impl.calculate CalculationSharingEquallyService
 * @Description: TDO 描述....
 * @author: family
 * @date: 2020/9/14
 * @Copyright: www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
@Slf4j
public class CalculationSharingEquallyService {

    @Autowired
    private CalculationCommonService calculationCommonService;
    @Autowired
    private GiftSharingService giftSharingService;
    @Autowired
    private ScoreSharingService scoreSharingService;

    @Autowired
    private DeliverySharingService deliverySharingService;

    @Autowired
    private AdditionSharingService additionSharingService;

    /**
     * 均摊服务
     * @param discountResult
     * @param cartGoodsList
     * @param shoppingCartGoodsResponseVo
     * @param shoppingCartInfoRequestVo
     * @param userLoginInfoDto
     * @param couponPromotionVO
     * @param activityQueryDto
     * @param menuType
     * @param deliveryAmount
     * @param shoppingCartGoodsDto
     * @param premiumExchangeActivity
     */
    public void equally(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsList
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo
            , ShoppingCartInfoRequestVo shoppingCartInfoRequestVo
            , UserLoginInfoDto userLoginInfoDto
            , CouponPromotionVO couponPromotionVO
            , ActivityQueryDto activityQueryDto
            , String menuType
            , Long deliveryAmount
            , ShoppingCartGoodsDto shoppingCartGoodsDto
            , CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity) {


        calculationCommonService.initShoppingCart(discountResult, cartGoodsList, shoppingCartGoodsResponseVo);

        List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtoList = CollectionUtils.isEmpty(shoppingCartGoodsDto.getProducts()) ? new ArrayList<>() : shoppingCartGoodsDto.getProducts();
        shoppingCartGoodsDto.setProducts(cartGoodsDetailDtoList);

        /**
         * 组建大的优惠信息
         */
        this.setShoppingCartGoodsDtoActivityDiscounts(discountResult, shoppingCartGoodsDto);
        /**
         * 活动库存
         * 过滤出加价购
         */
        List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.Discount> addMoneyDiscounts = discountResult.getDiscounts()
                .stream()
                .filter(discount -> ActivityTypeEnum.TYPE_81.getCode().equals(discount.getType()))
                .collect(Collectors.toList());
        if (null != discountResult) {
            List<SubtractStockVO> stocks = filterSendGoodsStocks(discountResult.getStocks(), shoppingCartInfoRequestVo, addMoneyDiscounts);
            if (CollectionUtils.isNotEmpty(stocks)) shoppingCartGoodsDto.setStocks(stocks);
        }

        //总计价
        shoppingCartGoodsDto.setPackageAmount(shoppingCartGoodsResponseVo.getNewPackAmount());
        shoppingCartGoodsDto.setOriginalTotalAmount(shoppingCartGoodsResponseVo.getOriginalTotalAmount());
        shoppingCartGoodsDto.setTotalAmount(shoppingCartGoodsResponseVo.getTotalAmount());
        shoppingCartGoodsDto.setTotalDiscountAmount(shoppingCartGoodsResponseVo.getTotalDiscountAmount());

        List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods> goods = discountResult.getGoods();
        /**
         * 利用促销赋值totalDiscountAmount
         */
        shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        for (CartGoods product : shoppingCartGoodsResponseVo.getProducts()) {
            CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods find = goods.stream().filter((k) -> k.getCartGoodsUid().equals(product.getCartGoodsUid())).findFirst().get();
            ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = calculationCommonService.convertCartGoods2DetailGoodsList(find, product);
            cartGoodsDetailDtoList.add(cartGoodsDetailDto);
        }

        /**
         * 赠品
         */
        giftSharingService.equally(discountResult, cartGoodsDetailDtoList, activityQueryDto, menuType);

        /**
         * 加价购商品
         */
        additionSharingService.equally(shoppingCartInfoRequestVo, shoppingCartGoodsDto, discountResult, premiumExchangeActivity);
        /**
         * 积分抵扣
         */
        scoreSharingService.scoreResponse(discountResult, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
        scoreSharingService.equally(shoppingCartGoodsResponseVo, shoppingCartGoodsDto);
        calculationCommonService.getNeedCardAmount(shoppingCartInfoRequestVo, shoppingCartGoodsDto);


        if (BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(menuType)) {
            deliverySharingService.deliveryResponse(discountResult, activityQueryDto, shoppingCartGoodsResponseVo, deliveryAmount);
        }
        shoppingCartGoodsDto.setDeliveryAmount(shoppingCartGoodsResponseVo.getDeliveryAmount());
        shoppingCartGoodsDto.setDiscountDeliveryAmount(shoppingCartGoodsResponseVo.getDiscountDeliveryAmount());
        shoppingCartGoodsDto.setThresholdAmount(shoppingCartGoodsResponseVo.getThresholdAmount());
        shoppingCartGoodsDto.setIsDiscountDelivery(shoppingCartGoodsResponseVo.getIsDiscountDelivery());
        shoppingCartGoodsDto.setDiscountDeliveryActivityCode(shoppingCartGoodsResponseVo.getDiscountDeliveryActivityCode());
    }

    /**
     * 设置购物车整体享受的活动集合
     *
     * @param discountResult
     * @param shoppingCartGoodsDto
     */
    private void setShoppingCartGoodsDtoActivityDiscounts(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult
            , ShoppingCartGoodsDto shoppingCartGoodsDto) {

        List<ActivityDiscountsDto> activityDiscountsDtos = new ArrayList<>();
        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
        if (discountResult == null) return;
        List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.Discount> discounts = discountResult.getDiscounts();
        for (CalculationSharingDiscountResponseDto.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);
            }
        }
        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
    }


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

}
