package com.bonus.canteen.core.marketing.v2.rule.recharge.handler.timesgift.extension.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.bonus.canteen.core.account.v3.api.AccTradeApi;
import com.bonus.canteen.core.account.v3.api.dto.AccRechargeSumApiDTO;
import com.bonus.canteen.core.account.v3.api.vo.AccRechargeSumApiVO;
import com.bonus.canteen.core.account.v3.constants.AccTradeTypeEnum;
import com.bonus.canteen.core.marketing.v2.constants.MarketRangeTypeEnum;
import com.bonus.canteen.core.marketing.v2.model.MarketRuleRange;
import com.bonus.canteen.core.marketing.v2.rule.recharge.constants.RuleRechargeComputeTypeEnum;
import com.bonus.canteen.core.marketing.v2.rule.recharge.constants.RuleRechargeSumEnum;
import com.bonus.canteen.core.marketing.v2.rule.recharge.dto.RuleRechargeResultDTO;
import com.bonus.canteen.core.marketing.v2.rule.recharge.dto.RuleRechargeWalletDTO;
import com.bonus.canteen.core.marketing.v2.rule.recharge.handler.timesgift.dto.RechargeTimesGiftDTO;
import com.bonus.canteen.core.marketing.v2.rule.recharge.handler.timesgift.dto.RechargeTimesGiftItemDTO;
import com.bonus.canteen.core.marketing.v2.rule.recharge.handler.timesgift.extension.RechargeTimesGiftHandlerExtension;
import com.bonus.canteen.core.marketing.v2.service.MarketRuleRangeService;
import com.bonus.canteen.core.marketing.vo.MarketRuleVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class DefaultRechargeTimesGiftHandlerImpl implements RechargeTimesGiftHandlerExtension {
   private static final Logger log = LoggerFactory.getLogger(DefaultRechargeTimesGiftHandlerImpl.class);
   @Autowired
   private AccTradeApi accTradeApi;
   @Autowired
   private MarketRuleRangeService rangeService;

   @Override
   public void handle(RuleRechargeResultDTO resultDTO, MarketRuleVO rule) {
      RechargeTimesGiftDTO ruleInfo = (RechargeTimesGiftDTO)JSONObject.parseObject(rule.getRuleInfo(), RechargeTimesGiftDTO.class);
      List<List<RechargeTimesGiftItemDTO>> items = ruleInfo.getItems();
      if (!CollUtil.isEmpty(items)) {
         List<MarketRuleRange> rangeList = this.rangeService.getRangeByRuleId(rule.getRuleId());
         List<Integer> payChannelList = this.rangeService.filterRangeDetailByType(rangeList, MarketRangeTypeEnum.RANGE_PAY_CHANNEL);
         AccRechargeSumApiDTO sumApiDTO = RuleRechargeSumEnum.getSumParam(ruleInfo.getSumType(), payChannelList, resultDTO);
         AccRechargeSumApiVO accRechargeSum = this.accTradeApi.getAccRechargeSum(sumApiDTO);
         if (!Objects.isNull(accRechargeSum)) {
            int count = accRechargeSum.getSumCount() + 1;
            List<RechargeTimesGiftItemDTO> itemDTOs = count >= items.size() ? (List)CollUtil.getLast(items) : (List)items.get(accRechargeSum.getSumCount());
            this.handleTimesAndAmount(resultDTO, itemDTOs);
         }
      }
   }

   protected void handleTimesAndAmount(RuleRechargeResultDTO resultDTO, List<RechargeTimesGiftItemDTO> items) {
      BigDecimal amount = resultDTO.getAmount();
      List<RechargeTimesGiftItemDTO> sortItems = (List)items.stream().sorted(Comparator.comparing(RechargeTimesGiftItemDTO::getDoorAmount).reversed()).collect(Collectors.toList());
      sortItems.stream().filter((e) -> {
         return amount.compareTo(e.getDoorAmount()) >= 0;
      }).findFirst().ifPresent((firstStep) -> {
         BigDecimal discount = firstStep.getDiscount();
         BigDecimal giftAmount = RuleRechargeComputeTypeEnum.COMPUTE_TYPE_AMOUNT.getKey().equals(firstStep.getComputeType()) ? discount : amount.multiply(discount).setScale(0, RoundingMode.UP);
         if (giftAmount.compareTo(BigDecimal.ZERO) > 0) {
            resultDTO.setActualAmount(resultDTO.getActualAmount().add(giftAmount));
            resultDTO.getWalletDetails().add((new RuleRechargeWalletDTO()).setWalletId(firstStep.getWalletId()).setAmount(giftAmount).setTradeType(AccTradeTypeEnum.RECHARGE_GIFT.getKey()));
         }
      });
   }
}
