package cn.freemud.service.impl;

import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.activity.ActivityQueryResponseDto;
import cn.freemud.entities.vo.ActivityList;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.GiftTypeEnum;
import cn.freemud.service.ActivityService;
import cn.freemud.utils.LogUtil;
import cn.freemud.utils.WebUtil;
import com.google.gson.Gson;
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.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 满减活动
 */
@Service
@Slf4j
public class FullSubtractionActivityServiceImpl {

    private final static Gson gson = new Gson();

    @Autowired
    private ActivityService activityService;


    /**
     * 获取满减活动
     *
     * @param activityQueryDto
     * @param totalAmount      处理过了的总价
     * @return
     */
    public PromotionMessageDto getFullPromotionActivityInfo(ActivityQueryDto activityQueryDto, Long totalAmount, boolean hasOtherDiscount) {
        totalAmount = totalAmount == null ? 0L : totalAmount;
        LogUtil.info("getFullPromotionActivityInfo", gson.toJson(activityQueryDto) + "_" + totalAmount + "_" + hasOtherDiscount, null);
        ActivityQueryResponseDto activityQueryResponseDto = activityService.queryActivitys(activityQueryDto, null, null);
        if (activityQueryResponseDto == null) {
            LogUtil.info("queryActivitys is error", gson.toJson(activityQueryDto), gson.toJson(activityQueryResponseDto));
            return null;
        }
        PromotionMessageDto promotionMessageDto = new PromotionMessageDto();
        List<ActivityResponseDto> activityQueryDtoList = activityQueryResponseDto.getResult();
        if (CollectionUtils.isNotEmpty(activityQueryDtoList)) {
            activityQueryDtoList = activityQueryDtoList.parallelStream().filter(k -> {
                Integer activityType = k.getActivityType();
                return Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityType)
                        || Objects.equals(ActivityTypeEnum.TYPE_12.getCode(), activityType);
            }).limit(1).collect(Collectors.toList());
            // 存在满减活动
            if (CollectionUtils.isNotEmpty(activityQueryDtoList)) {
                totalAmount = totalAmount == null ? 0L : totalAmount;

                StringBuilder messageBuilder = new StringBuilder();

                ActivityResponseDto activityResponseDto = activityQueryDtoList.get(0);
                promotionMessageDto.setActivityId(activityResponseDto.getActivityCode());
                promotionMessageDto.setActivityName(activityResponseDto.getActivityName());
                promotionMessageDto.setActivityType(activityResponseDto.getActivityType());
                promotionMessageDto.setPromotionAmount(0L);
                // 每满减
                List<BenefitBeanDto> benefitBeanDtos = activityResponseDto.getBenefits();
                if (CollectionUtils.isNotEmpty(benefitBeanDtos)) {
                    if (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityResponseDto.getActivityType())) {
                        BenefitBeanDto benefitBeanDto = benefitBeanDtos.get(0);
                        Integer thresholdAmount = benefitBeanDto.getThresholdAmount();
                        Integer discountAmount = benefitBeanDto.getDiscountAmount();
                        // 购物车中无商品或者存在与满减互斥的活动
                        if (totalAmount == 0
                                || (hasOtherDiscount && Objects.equals(activityResponseDto.getIsShared(), 0))) {
                            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> ");
                        }
                        // 购物车中有商品但还不够满减
                        else if (totalAmount < thresholdAmount) {
                            messageBuilder.append("满 <span style=\"color:#fa5555\">")
                                    .append(WebUtil.formatAmount(thresholdAmount * 1.00 / 100))
                                    .append("</span> 减 <span style=\"color:#fa5555\">")
                                    .append(WebUtil.formatAmount(discountAmount * 1.00 / 100))
                                    .append("</span> ")
                                    .append("还差 <span style=\"color:#fa5555\">")
                                    .append(WebUtil.formatAmount((thresholdAmount - totalAmount) * 1.00 / 100))
                                    .append("</span> 元");
                        }
                        // 已够满减
                        else if (totalAmount >= thresholdAmount) {
                            // 最大阶级
                            Long maxLevel = activityResponseDto.getMaxMoney() / discountAmount;
                            Long currentLevel = totalAmount / thresholdAmount;
                            if (currentLevel > maxLevel || currentLevel * discountAmount == activityResponseDto.getMaxMoney()) {
                                Long diccountAmount = activityResponseDto.getMaxMoney() < currentLevel * discountAmount ? activityResponseDto.getMaxMoney() : maxLevel * discountAmount;
                                messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                                        .append(WebUtil.formatAmount(diccountAmount * 1.00 / 100))
                                        .append("</span> 元");
                            } else {
                                Long maxDiscountAmount = activityResponseDto.getMaxMoney() < (discountAmount * (currentLevel + 1)) ? activityResponseDto.getMaxMoney() : (discountAmount * (currentLevel + 1));
                                messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                                        .append(WebUtil.formatAmount(discountAmount * currentLevel * 1.00 / 100))
                                        .append("</span> 元 再买 <span style=\"color:#fa5555\">")
                                        .append(WebUtil.formatAmount((thresholdAmount * (currentLevel + 1) - totalAmount) * 1.00 / 100))
                                        .append("</span> 元减 <span style=\"color:#fa5555\">")
                                        .append(WebUtil.formatAmount(maxDiscountAmount * 1.00 / 100))
                                        .append("</span> 元");
                            }
                        }
                    }
                    // 阶梯满减
                    else if (Objects.equals(ActivityTypeEnum.TYPE_12.getCode(), activityResponseDto.getActivityType())) {
                        int len = benefitBeanDtos.size();
                        BenefitBeanDto minBenefitBeanDto = benefitBeanDtos.get(len - 1);
                        // // 购物车中无商品或者存在与满减互斥的活动
                        if (totalAmount == 0
                                || (hasOtherDiscount && Objects.equals(activityResponseDto.getIsShared(), 0))) {
                            for (int i = len - 1, j = 0; i >= 0 && j < 2; i--, j++) {
                                BenefitBeanDto 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> ");
                            }
                        }
                        // 购物车中有商品但还不够满减
                        else if (totalAmount < minBenefitBeanDto.getThresholdAmount()) {
                            messageBuilder.append("满 <span style=\"color:#fa5555\">")
                                    .append(WebUtil.formatAmount(minBenefitBeanDto.getThresholdAmount() * 1.00 / 100))
                                    .append("</span> 减 <span style=\"color:#fa5555\">")
                                    .append(WebUtil.formatAmount(minBenefitBeanDto.getDiscountAmount() * 1.00 / 100))
                                    .append("</span> ")
                                    .append("还差 <span style=\"color:#fa5555\">")
                                    .append(WebUtil.formatAmount((minBenefitBeanDto.getThresholdAmount() - totalAmount) * 1.00 / 100))
                                    .append("</span> 元");
                        }
                        // 已够满减
                        else {
                            for (int i = 0; i < len; i++) {
                                BenefitBeanDto benefitBeanDto = benefitBeanDtos.get(i);
                                int thresholdAmount = benefitBeanDto.getThresholdAmount();
                                // 最高阶
                                if (i == 0 && totalAmount >= thresholdAmount) {
                                    messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                                            .append(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100))
                                            .append("</span> 元");
                                    break;
                                } else {
                                    if (i > 0 && totalAmount >= thresholdAmount) {
                                        int lastThresholdAmount = benefitBeanDtos.get(i - 1).getThresholdAmount();
                                        int lastDiscountAmount = benefitBeanDtos.get(i - 1).getDiscountAmount();
                                        messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                                                .append(WebUtil.formatAmount(benefitBeanDto.getDiscountAmount() * 1.00 / 100))
                                                .append("</span> 元 再买 <span style=\"color:#fa5555\">")
                                                .append(WebUtil.formatAmount((lastThresholdAmount - totalAmount) * 1.00 / 100))
                                                .append("</span> 元减 <span style=\"color:#fa5555\">")
                                                .append(WebUtil.formatAmount(lastDiscountAmount * 1.00 / 100))
                                                .append("</span> 元");
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    promotionMessageDto.setPromotionMessage(messageBuilder.toString());
                    return promotionMessageDto;
                }
            }
        }
        return null;
    }

    /**
     * 获取满减活动信息_新方法
     *
     * @param activityQueryDto
     * @param calculationDiscountResult
     * @return
     */
    public PromotionMessageDto getFullPromotionActivityInfo(ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult,
                                                            ArrayList<ActivityList> activityList) {

        ActivityQueryResponseDto activityQueryResponseDto = activityService.queryActivityByType(activityQueryDto, Arrays.asList(ActivityTypeEnum.TYPE_11, ActivityTypeEnum.TYPE_12,ActivityTypeEnum.TYPE_230), null);
        if (activityQueryResponseDto == null) {
            return null;
        }
        PromotionMessageDto promotionMessageDto = new PromotionMessageDto();
        List<ActivityResponseDto> activityQueryDtoList = activityQueryResponseDto.getResult();

        StringBuilder messageBuilder = new StringBuilder();
        if (CollectionUtils.isNotEmpty(activityQueryDtoList)) {
            activityQueryDtoList = activityQueryDtoList.parallelStream().filter(k -> {
                Integer activityType = k.getActivityType();
                return Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityType)
                        || Objects.equals(ActivityTypeEnum.TYPE_12.getCode(), activityType)
                        || Objects.equals(ActivityTypeEnum.TYPE_230.getCode(), activityType);
            }).limit(1).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(activityQueryDtoList)) {
                return promotionMessageDto;
            }
            ActivityResponseDto activityResponseDto = activityQueryDtoList.get(0);
            promotionMessageDto.setActivityId(activityResponseDto.getActivityCode());
            promotionMessageDto.setActivityName(activityResponseDto.getActivityName());
            promotionMessageDto.setActivityType(activityResponseDto.getActivityType());
            promotionMessageDto.setPromotionAmount(0L);
            // 没有加入购物车
            if (calculationDiscountResult == null) {
                List<BenefitBeanDto> benefitBeanDtos = activityResponseDto.getBenefits();
                BenefitBeanDto benefitBeanDto = benefitBeanDtos.get(0);
                // 每满减
                if (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityResponseDto.getActivityType())) {
                    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元
                    cn.freemud.entities.vo.ActivityList notInShopping = new ActivityList();
                    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, j = 0; i >= 0 && j < 2; i--, j++) {
                        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> 元");
                    }

                    //  阶梯满减：满足 X 元 减 Y 元,
                    for (int j = len - 1; j >= 0; j--) {
                        benefitBeanDto = benefitBeanDtos.get(j);
                        cn.freemud.entities.vo.ActivityList notInShopping = new ActivityList();
                        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);
                    }
                }
                if (Objects.equals(ActivityTypeEnum.TYPE_230.getCode(), activityResponseDto.getActivityType())) {
                    ActivityList notInShopping = new ActivityList();
                    // 规则:满5赠奶茶2件，炸鸡1件，满10赠布丁3件，牛奶1份，鸡翅2份，
                    // 提示语：满5元可获赠奶茶*2，炸鸡*1
                    //阶梯满赠
                    notInShopping.setSatisfy(WebUtil.formatAmount(benefitBeanDto.getThresholdAmount() * 1.00 / 100).toString());
                    if (GiftTypeEnum.TYPE_1.equals(activityResponseDto.getActivitySubType())) {
                        notInShopping.setTipType(6);
                    }
                    //每满赠
                    else if (GiftTypeEnum.TYPE_2.equals(activityResponseDto.getActivitySubType())) {
                        notInShopping.setTipType(7);
                    }
                    for (BenefitBeanDto beanDto : benefitBeanDtos) {
                        notInShopping.setSatisfy(WebUtil.formatAmount(beanDto.getThresholdAmount() * 1.00 / 100).toString());
                        int len = beanDto.getSendGoodsList().size();
                        List<ActivityList.SendGoods> sends = new ArrayList();
                        for (int i = len - 1; i >= 0; i--) {
                            ActivityList.SendGoods goods = new ActivityList.SendGoods();
                            goods.setQty(goods.getQty());
                            goods.setGoodsName(goods.getGoodsName());
                            sends.add(goods);
                        }
                        notInShopping.setSends(sends);
                        break;
                    }
                }
            }
            // 有商品在购物车
            else {
                List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ActivityPrompt> activityPrompts = calculationDiscountResult.getActivityPrompts();
                List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discountList = calculationDiscountResult.getDiscounts();
                //加入商品满足购物车  还差多少提示
                if (CollectionUtils.isNotEmpty(activityPrompts)) {
                    ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ActivityPrompt activityPrompt = activityPrompts.get(0);
                    ActivityList satisfyList = new ActivityList();
                    if (activityPrompt.getAlreadyDiscountAmount() == null  || activityPrompt.getAlreadyDiscountAmount() == 0) {
                        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()) || GiftTypeEnum.TYPE_2.equals(activityResponseDto.getActivitySubType())) {

                            if (Objects.equals(ActivityTypeEnum.TYPE_11.getCode(), activityResponseDto.getActivityType())
                                    || GiftTypeEnum.TYPE_2.equals(activityResponseDto.getActivitySubType())) {
                                toDiscountAmout = activityPrompt.getDiscountAmout() + activityPrompt.getAlreadyDiscountAmount();
                            } else {
                                toDiscountAmout = activityPrompt.getDiscountAmout();
                            }
                            //已减 X 元 再买 Y 元 减 Z 元
                            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());
                        }
                        if (Objects.equals(ActivityTypeEnum.TYPE_230.getCode(), activityResponseDto.getActivityType()) && CollectionUtils.isNotEmpty(activityPrompt.getSendGoods())) {

                            satisfyList.setTipType(10);
                            ActivityList.SendGoods send = new ActivityList.SendGoods();
                            send.setQty(activityPrompt.getSendGoods().get(0).getSendNumber());
                            send.setGoodsName(activityPrompt.getSendGoods().get(0).getGoodsName());
                            List<ActivityList.SendGoods> sends = new ArrayList();
                            sends.add(send);
                            satisfyList.setSends(sends);
                            if (GiftTypeEnum.TYPE_1.equals(activityResponseDto.getActivitySubType())) {
                                satisfyList.setTipType(8);
                            } else {
                                satisfyList.setTipType(9);
                            }
                        }
                    }
                }
                else {
                    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.isNotEmpty(discountList)) {
                        messageBuilder.append("已减 <span style=\"color:#fa5555\">")
                                .append(WebUtil.formatAmount(discountList.get(0).getDiscount() * 1.00 / 100))
                                .append("</span> 元");
                        //已减 X 元
                        ActivityList noSatisfy = new ActivityList();
                        noSatisfy.setTipType(5);
                        noSatisfy.setDeduct(WebUtil.formatAmount(discountList.get(0).getDiscount() * 1.00 / 100).toString());
                        activityList.add(noSatisfy);
                    }
                }
            }
        }
        promotionMessageDto.setPromotionMessage(messageBuilder.toString());
        return promotionMessageDto;
    }
}