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

import cn.freemud.entities.dto.ActivityResponseDto;
import cn.freemud.entities.dto.BenefitBeanDto;
import cn.freemud.entities.dto.PromotionMessageDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.activity.ActivityQueryResponseDto;
import cn.freemud.entities.dto.calculate.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityPromptEnum;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.service.ActivityService;
import cn.freemud.utils.WebUtil;
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.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

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

@Service
public class FullPromotionCalculation {


    @Autowired
    private ActivityService activityService;


    public void updateShoppingCartGoodsDiscount(ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> allCartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {
        shoppingCartGoodsResponseVo.setActivityTip(new ActivityTip());
        List<ActivityTypeEnum> activityTypeEnums = new LinkedList<>();
        activityTypeEnums.add(ActivityTypeEnum.TYPE_11);
        activityTypeEnums.add(ActivityTypeEnum.TYPE_12);
        //调用促销统一活动查询
        //过滤出参与的满减(目前只有每满减和阶梯满减)
        ActivityQueryResponseDto activityQueryResponseDto = activityService.queryActivityByType(activityQueryDto, activityTypeEnums, null);
        if (activityQueryResponseDto == null) {
            return;
        }
        List<ActivityResponseDto> activityQueryDtoList = activityQueryResponseDto.getResult();
        if (CollectionUtils.isEmpty(activityQueryDtoList)) {
            return;
        }

        PromotionMessageDto promotionMessageDto = new PromotionMessageDto();
        ActivityResponseDto activityResponseDto = activityQueryDtoList.get(0);
        promotionMessageDto.setActivityId(activityResponseDto.getActivityCode());
        promotionMessageDto.setActivityName(activityResponseDto.getActivityName());
        promotionMessageDto.setActivityType(activityResponseDto.getActivityType());
        promotionMessageDto.setPromotionAmount(0L);
        StringBuilder messageBuilder = new StringBuilder();
        ArrayList<ActivityList> activityList = new ArrayList<>();
        //没有加入购物车
        if (calculationDiscountResult == null) {
            // 因为没有促销活动的计算信息，所以没有加入购物车内
            List<BenefitBeanDto> benefitBeanDtos = activityResponseDto.getBenefits();
            //调用没有加入购物车的提示语的方法
            setMessageNotInShoppingCart(messageBuilder, activityResponseDto, benefitBeanDtos, activityList);
        } else {
            //促销返回满减提示语
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ActivityPrompt> activityPrompts = calculationDiscountResult.getActivityPrompts();
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discountList1 = calculationDiscountResult.getDiscounts();
            //构建提示语
            if (CollectionUtils.isNotEmpty(activityPrompts)) {
                setMessageSatisfyCart(messageBuilder, activityPrompts, activityResponseDto, activityList);
            } else {
                setMessageNoSatisfyCart(messageBuilder, discountList1, activityList);
            }
        }

        promotionMessageDto.setPromotionMessage(messageBuilder.toString());
        ActivityTip activityTip = new ActivityTip();
        activityTip.setActivityCode(promotionMessageDto.getActivityId());
        activityTip.setActivityType(promotionMessageDto.getActivityType());
        activityTip.setActivityName(promotionMessageDto.getPromotionMessage());
        activityTip.setActivityList(activityList);
        shoppingCartGoodsResponseVo.setActivityTip(activityTip);
        if (calculationDiscountResult == null) {
            return;
        }

        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discountList = calculationDiscountResult.getDiscounts();
        if (CollectionUtils.isEmpty(discountList)) {
            return;
        }

        //过滤出参与的满减(目前只有每满减和阶梯满减)
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> fullDiscountsList = discountList
                .stream().filter(discount -> ActivityTypeEnum.TYPE_11.getCode().equals(discount.getType()) || ActivityTypeEnum.TYPE_12.getCode().equals(discount.getType()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(fullDiscountsList)) {
            return;
        }
        //总的满减优惠金额
        long fullDiscount = 0L;
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount fullDiscounts : fullDiscountsList) {
            fullDiscount = fullDiscount + (fullDiscounts.getDiscount() == null ? 0 : fullDiscounts.getDiscount());
        }
        //设置到响应中
        shoppingCartGoodsResponseVo.setFullDiscount(fullDiscount);
        shoppingCartGoodsResponseVo.setProducts(allCartGoodsList);
        shoppingCartGoodsResponseVo.setProductsCount(allCartGoodsList.size());
    }

    /**
     * 商品均摊
     */
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo){

    }




    //设置没有加入购物车的提示语
    private void setMessageNotInShoppingCart(StringBuilder messageBuilder, ActivityResponseDto activityResponseDto,
                                             List<BenefitBeanDto> benefitBeanDtos, ArrayList<ActivityList> activityList) {
        if(CollectionUtils.isEmpty(benefitBeanDtos)){
            return;
        }
        BenefitBeanDto benefitBeanDto = benefitBeanDtos.get(0);
        if (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityResponseDto.getActivityType())) {
            cn.freemud.entities.vo.ActivityList notInShopping = new ActivityList();
            if(ActivityPromptEnum.PreferentialTypeEnum.TO_ORDER_ITEM_QUANTITY.getCode().equals(activityResponseDto.getCouponType())) {
                messageBuilder.append("每满 <span style=\"color:#fa5555\">")
                        .append(benefitBeanDto.getBenefitNumber())
                        .append("</span> 减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100))
                        .append("</span> ")
                        .append("最高减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(activityResponseDto.getMaxMoney() * 1.00 / 100))
                        .append("</span> 元");

                //满足  x 元 减 Y 元 ，最高 减 Z元
                notInShopping.setTipType(15);
                notInShopping.setSatisfy(benefitBeanDto.getBenefitNumber().toString());
                notInShopping.setDeduct(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100).toString());
                notInShopping.setMaxDeduct(WebUtil.formatAmount(activityResponseDto.getMaxMoney() * 1.00 / 100).toString());
                notInShopping.setInvokeAmount(WebUtil.formatAmount(activityResponseDto.getDelayTimes() * 1.00 / 100).toString());
            }else{
                messageBuilder.append("每满 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(benefitBeanDto.getThresholdAmount() * 1.00 / 100))
                        .append("</span> 减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100))
                        .append("</span> ")
                        .append("最高减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(activityResponseDto.getMaxMoney() * 1.00 / 100))
                        .append("</span> 元");

                //满足  x 元 减 Y 元 ，最高 减 Z元
                notInShopping.setTipType(1);
                notInShopping.setSatisfy(WebUtil.formatAmount(benefitBeanDto.getThresholdAmount() * 1.00 / 100).toString());
                notInShopping.setDeduct(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100).toString());
                notInShopping.setMaxDeduct(WebUtil.formatAmount(activityResponseDto.getMaxMoney() * 1.00 / 100).toString());
            }
            activityList.add(notInShopping);
        }
        if (Objects.equals(ActivityTypeEnum.TYPE_12.getCode(), activityResponseDto.getActivityType())) {
            int len = benefitBeanDtos.size();
            // // 购物车中无商品或者存在与满减互斥的活动
            for (int i = len - 1; i >= 0; i--) {
                benefitBeanDto = benefitBeanDtos.get(i);
                messageBuilder.append("满 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(benefitBeanDto.getThresholdAmount() * 1.00 / 100))
                        .append("</span> 减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100))
                        .append("</span> 元");
                if (i > 0) messageBuilder.append("，");
            }
            //  阶梯满减：满足 X 元 减 Y 元,
            for (int j = len - 1; j >= 0; j--) {
                benefitBeanDto = benefitBeanDtos.get(j);
                cn.freemud.entities.vo.ActivityList notInShopping = new ActivityList();
                if(ActivityPromptEnum.PreferentialTypeEnum.TO_ORDER_ITEM_QUANTITY.getCode().equals(activityResponseDto.getCouponType())) {
                    notInShopping.setTipType(16);
                    notInShopping.setSatisfy(benefitBeanDto.getBenefitNumber().toString());
                    notInShopping.setDeduct(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100).toString());
                    notInShopping.setInvokeAmount(WebUtil.formatAmount(activityResponseDto.getDelayTimes() * 1.00 / 100).toString());
                }else{
                    notInShopping.setTipType(2);
                    notInShopping.setSatisfy(WebUtil.formatAmount(benefitBeanDto.getThresholdAmount() * 1.00 / 100).toString());
                    notInShopping.setDeduct(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100).toString());
                }
                activityList.add(notInShopping);
            }
        }
    }


    /**
     * 设置加入商品满足购物车时的提示语
     *
     * @param messageBuilder
     * @param activityPrompts
     * @param activityResponseDto
     */
    private void setMessageSatisfyCart(StringBuilder messageBuilder, List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ActivityPrompt> activityPrompts
            , ActivityResponseDto activityResponseDto, ArrayList<ActivityList> activityList) {

        ActivityList satisfyList = new ActivityList();
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ActivityPrompt activityPrompt = activityPrompts.get(0);
        if (activityPrompt.getAlreadyDiscountAmount() == null
                || activityPrompt.getAlreadyDiscountAmount() == 0) {

            if(ActivityPromptEnum.PreferentialTypeEnum.TO_ORDER_ITEM_QUANTITY.getCode().equals(activityResponseDto.getCouponType())) {
                messageBuilder.append("满 <span style=\"color:#fa5555\">")
                        .append(activityPrompt.getThresholdQuantity())
                        .append("</span>件 减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(activityPrompt.getDiscountAmout() * 1.00 / 100))
                        .append("</span> ")
                        .append("还差 <span style=\"color:#fa5555\">")
                        .append((activityPrompt.getThresholdQuantity() - activityPrompt.getTotalQuantity()))
                        .append("</span> 件");
                // 满足 X 元 减 Y 元 还差 Z元
                satisfyList.setTipType(ActivityPromptEnum.TipTypeEnum.ELEVEN.getCode());
                satisfyList.setSatisfy(activityPrompt.getThresholdQuantity().toString());
                satisfyList.setDeduct(WebUtil.formatAmount(activityPrompt.getDiscountAmout() * 1.00 / 100).toString());
                satisfyList.setMissing((activityPrompt.getThresholdQuantity() - activityPrompt.getTotalQuantity()) + "");
                satisfyList.setInvokeAmount(WebUtil.formatAmount(activityResponseDto.getDelayTimes() * 1.00 / 100).toString());
            }else{
                messageBuilder.append("满 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(activityPrompt.getThresholdAmount() * 1.00 / 100))
                        .append("</span> 减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(activityPrompt.getDiscountAmout() * 1.00 / 100))
                        .append("</span> ")
                        .append("还差 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100))
                        .append("</span> 元");
                // 满足 X 元 减 Y 元 还差 Z元
                satisfyList.setTipType(3);
                satisfyList.setSatisfy(WebUtil.formatAmount(activityPrompt.getThresholdAmount() * 1.00 / 100).toString());
                satisfyList.setDeduct(WebUtil.formatAmount(activityPrompt.getDiscountAmout() * 1.00 / 100).toString());
                satisfyList.setMissing(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100).toString());

            }

                   } else {
            Long toDiscountAmout;
            if (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityResponseDto.getActivityType())) {
                toDiscountAmout = activityPrompt.getDiscountAmout() + activityPrompt.getAlreadyDiscountAmount();
            } else {
                toDiscountAmout = activityPrompt.getDiscountAmout();
            }
            //已减 X 元 再买 Y 元 减 Z 元
            if(ActivityPromptEnum.PreferentialTypeEnum.TO_ORDER_ITEM_QUANTITY.getCode().equals(activityResponseDto.getCouponType())) {
                messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(activityPrompt.getAlreadyDiscountAmount() * 1.00 / 100))
                        .append("</span> 元 再买 <span style=\"color:#fa5555\">")
                        .append(activityPrompt.getThresholdQuantity() - activityPrompt.getTotalQuantity())
                        .append("</span> 件减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(toDiscountAmout * 1.00 / 100))
                        .append("</span> 元");
                satisfyList.setTipType(ActivityPromptEnum.TipTypeEnum.TWELVE.getCode());
                satisfyList.setDeduct(WebUtil.formatAmount(activityPrompt.getAlreadyDiscountAmount() * 1.00 / 100).toString());
                satisfyList.setAgainBuy((activityPrompt.getThresholdQuantity() - activityPrompt.getTotalQuantity()) + "");
                satisfyList.setAgianDeduct(WebUtil.formatAmount(toDiscountAmout * 1.00 / 100).toString());
                satisfyList.setInvokeAmount(WebUtil.formatAmount(activityResponseDto.getDelayTimes() * 1.00 / 100).toString());
            }
            else{
                messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(activityPrompt.getAlreadyDiscountAmount() * 1.00 / 100))
                        .append("</span> 元 再买 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100))
                        .append("</span> 元减 <span style=\"color:#fa5555\">")
                        .append(WebUtil.formatAmount(toDiscountAmout * 1.00 / 100))
                        .append("</span> 元");
                satisfyList.setTipType(4);
                satisfyList.setDeduct(WebUtil.formatAmount(activityPrompt.getAlreadyDiscountAmount() * 1.00 / 100).toString());
                satisfyList.setAgainBuy(WebUtil.formatAmount((activityPrompt.getThresholdAmount() - activityPrompt.getTotalAmount()) * 1.00 / 100).toString());
                satisfyList.setAgianDeduct(WebUtil.formatAmount(toDiscountAmout * 1.00 / 100).toString());
            }
        }
        activityList.add(satisfyList);
    }

    /**
     * 设置加入商品不满足购物车时的提示语
     *
     * @param messageBuilder
     * @param discountList
     */
    private void setMessageNoSatisfyCart(StringBuilder messageBuilder, List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discountList, ArrayList<ActivityList> activityList) {
        discountList = discountList.parallelStream().filter(k -> (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), k.getType())
                || Objects.equals(ActivityTypeEnum.TYPE_12.getCode(), k.getType()))).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(discountList)) {
            return;
        }
        //已减 X 元
        messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                .append(WebUtil.formatAmount(discountList.get(0).getDiscount() * 1.00 / 100))
                .append("</span> 元");
        ActivityList noSatisfy = new ActivityList();
        noSatisfy.setTipType(5);
        noSatisfy.setDeduct(WebUtil.formatAmount(discountList.get(0).getDiscount() * 1.00 / 100).toString());
        activityList.add(noSatisfy);
    }

    public ActivityQueryDto getActivityQueryDto(String partnerId, String storeId, String userId, String appId, Integer orderType) {
        return ActivityQueryDto.builder()
                .partnerId(partnerId)
                .storeId(storeId)
                .userId(userId)
                .appId(appId)
                .orderType(orderType)
                .build();
    }



}
