package cn.freemud.service.impl;

import cn.freemud.adapter.PromotionAdapter;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.promotion.*;
import cn.freemud.entities.dto.shoppingCart.ActivityDiscountsDto;
import cn.freemud.entities.vo.ActivityDiscountsVo;
import cn.freemud.service.IPromotionService;
import com.freemud.application.sdk.api.ordercenter.enums.ProductTypeEnum;
import com.freemud.application.sdk.api.promotioncenter.dto.promotion.ApportionGoodsDTO;
import com.freemud.application.sdk.api.promotioncenter.dto.promotion.DiscountDTO;
import com.freemud.application.sdk.api.promotioncenter.response.CalculationDiscountResponseDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.com
 *
 * @version V1.0
 * @Title:
 * @Package: com.freemud.sdk.api.assortment.promotion.service.calculationService
 * @Descripttion:
 * @author: shuhu.hou
 * @date: 2019/9/9
 * @Copyright: 2017 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目.
 */
@Service
public class DefaultPromotionService implements IPromotionService {

    @Override
    public void updateDiscountApportion(ShoppingCartGoodsResponse shoppingCartGoodsResponse, OrderBeanRequest request, CalculationDiscountResultDto calculationDiscountResult, CouponPromotionDto couponPromotionDto, ActivityQueryDto activityQueryDto) {
        // 总原价
        Long originalTotalAmount = 0L;
        // 总折扣
        Long totalDiscountAmount = 0L;
        // 总价
        Long totalAmount = 0L;
        // 总打包价
        Long packAmount = 0L;

        for (OrderBeanRequest.ProductBean product : request.getProductList()) {
            if(Objects.equals(ProductTypeEnum.WEIGHT_PRODUCT.getCode(), product.getProductType())) {
                originalTotalAmount += product.getWeight().multiply(new BigDecimal(product.getPrice()+"")).longValue();
            } else {
                originalTotalAmount += product.getNumber() * product.getPrice();
            }
            totalAmount += product.getSettlementPrice();
            packAmount += product.getNumber() * (product.getPackAmount() == null ? 0 : product.getPackAmount());
        }


        List<OrderBeanRequest.ProductBean> productBeanList = request.getProductList().stream().filter(productBean -> {
            if (ProductTypeEnum.WEIGHT_PRODUCT.getCode().equals(productBean.getProductType())) {
                return false;
            }
            if (ProductTypeEnum.SETMEAL_PRODUCT.getCode().equals(productBean.getProductType()) || ProductTypeEnum.SETMEAL_UPPRICE_PRODUCT.getCode().equals(productBean.getProductType())) {
                return false;
            }
            return true;
        }).collect(Collectors.toList());

        List<CalculationApportionGoodsDto> apportionGoodsList = (calculationDiscountResult == null || calculationDiscountResult.getApportionGoods() == null) ? new ArrayList<>() : calculationDiscountResult.getApportionGoods();
        Map<String, String> duplicateGoodsMap = new HashMap<>();
        List<ShoppingCartGoodsResponse.CartGoodsDetailDto> cartGoodsDetailDtoList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(productBeanList)) {
            productBeanList.stream().collect(Collectors.groupingBy(OrderBeanRequest.ProductBean::getProductId, Collectors.counting())).forEach((goodsId, count) -> {
                duplicateGoodsMap.put(goodsId,String.format("%s,0", count));
            });
            for (OrderBeanRequest.ProductBean productBean : productBeanList) {
                Long originalDiscountAmount = productBean.getPrice() * productBean.getNumber() - productBean.getSettlementPrice();
                if (Objects.equals(productBean.getProductType(), ProductTypeEnum.WEIGHT_PRODUCT.getCode())) {
                    originalDiscountAmount = new BigDecimal(productBean.getPrice()+"").multiply(productBean.getWeight()).longValue() - productBean.getSettlementPrice();
                }
                cartGoodsDetailDtoList.add(PromotionAdapter.convertCartGoods2DetailGoods(productBean, originalDiscountAmount.intValue(), apportionGoodsList, duplicateGoodsMap));
            }
        }

        // 设置 订单优惠详情
        List<CalculationGoodsActivityDto> discounts = (calculationDiscountResult == null || calculationDiscountResult.getDiscounts() == null) ? new ArrayList<>() : calculationDiscountResult.getDiscounts();
        List<ActivityDiscountsDto> activityDiscountsDtos = shoppingCartGoodsResponse.getActivityDiscountsDtos() == null ? new ArrayList<>() : shoppingCartGoodsResponse.getActivityDiscountsDtos();
        for (CalculationGoodsActivityDto discount : discounts) {
            Integer 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);
            }
        }

        Long calcTotalDiscountAmount = calculationDiscountResult != null ? calculationDiscountResult.getTotalDiscountAmount() : 0L;

        shoppingCartGoodsResponse.setOriginalTotalAmount(originalTotalAmount);
        shoppingCartGoodsResponse.setTotalAmount(totalAmount - calcTotalDiscountAmount);
        shoppingCartGoodsResponse.setTotalDiscountAmount(calculationDiscountResult != null ? calculationDiscountResult.getTotalDiscountAmount() : totalDiscountAmount);
        shoppingCartGoodsResponse.setPackageAmount(packAmount);
        shoppingCartGoodsResponse.setProducts(cartGoodsDetailDtoList);
        shoppingCartGoodsResponse.setActivityDiscountsDtos(activityDiscountsDtos);
        shoppingCartGoodsResponse.setStocks(calculationDiscountResult != null ? calculationDiscountResult.getStocks() : null);
    }

}
