package com.bonus.core.marketing.v2.rule.pay.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.bonus.core.customer.api.CustInfoApi;
import com.bonus.core.customer.constants.CustConstant;
import com.bonus.core.customer.model.CustInfo;
import com.bonus.core.marketing.util.EnumUtil;
import com.bonus.core.marketing.v2.rule.param.RuleRangeParam;
import com.bonus.core.marketing.v2.rule.pay.constants.RulePayEnum;
import com.bonus.core.marketing.v2.rule.pay.dto.RulePayComputeDTO;
import com.bonus.core.marketing.v2.rule.pay.dto.RulePayResultDTO;
import com.bonus.core.marketing.v2.rule.pay.handler.RulePayHandler;
import com.bonus.core.marketing.v2.rule.pay.handler.RulePayProvider;
import com.bonus.core.marketing.v2.service.MarketRuleService;
import com.bonus.core.marketing.vo.MarketRuleVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class RulePayApi {
   private static final Logger log = LoggerFactory.getLogger(RulePayApi.class);
   @Resource
   private RulePayProvider rulePayProvider;
   @Resource
   private MarketRuleService marketRuleService;
   @Resource
   private CustInfoApi custInfoApi;

   public RulePayResultDTO compute(RulePayComputeDTO computeDTO) {
      log.info("【扣款规则】开始");
      Long custId = computeDTO.getCustId();
      CustInfo custInfo = this.custInfoApi.getCustInfoByCustId(Objects.isNull(custId) ? CustConstant.TEMPORARY_CUST_ID : custId);
      RuleRangeParam ruleRangeParam = RuleRangeParam.rulePayRangeParam(computeDTO, custInfo);
      log.info("【扣款规则】查找合适规则入参：{}", JSONUtil.toJsonStr(ruleRangeParam));
      List<MarketRuleVO> suitableRules = this.marketRuleService.getSuitableRules(ruleRangeParam);
      if (CollUtil.isEmpty(suitableRules)) {
         log.info("【扣款规则】根据生效周期未匹配到扣款规则");
         return new RulePayResultDTO();
      } else {
         Optional<MarketRuleVO> rule = suitableRules.stream().filter((e) -> {
            return RulePayEnum.RULE_PAY_SEQUENCE.getKey().equals(e.getRuleType());
         }).findFirst();
         if (!rule.isPresent()) {
            log.info("【扣款规则】未匹配到扣款规则");
            return new RulePayResultDTO();
         } else {
            RulePayResultDTO result = this.handle(computeDTO, (MarketRuleVO)rule.get());
            log.info("【扣款规则】规则计算结果：{}", JSONUtil.toJsonStr(result));
            return result;
         }
      }
   }

   protected RulePayResultDTO handle(RulePayComputeDTO computeDTO, MarketRuleVO ruleInfo) {
      RulePayHandler handler = this.rulePayProvider.getMarketPayHandler(ruleInfo.getRuleType());
      if (Objects.isNull(handler)) {
         log.info("【扣款规则】规则类型：{}，未找到对应规则类型的实现方法", ruleInfo.getRuleType());
         return new RulePayResultDTO();
      } else {
         log.info("【扣款规则】规则类型：{}，规则详情：{}", ((RulePayEnum) EnumUtil.getEnumByKey(RulePayEnum.class, ruleInfo.getRuleType())).getValue(), JSONUtil.toJsonStr(ruleInfo));
         return handler.handle(computeDTO, ruleInfo);
      }
   }
}
