package com.bonus.canteen.core.marketing.v2.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.canteen.core.allocation.api.GlobalMetadataApi;
import com.bonus.canteen.core.common.enums.MetadataModelTypeEnum;
import com.bonus.canteen.core.common.redis.RedisUtil;
import com.bonus.canteen.core.common.utils.TenantContextHolder;
import com.bonus.canteen.core.marketing.v2.rule.meal.dto.api.RuleMealApi;
import com.bonus.canteen.core.marketing.v2.rule.pay.api.RulePayApi;
import com.bonus.canteen.core.marketing.v2.rule.pay.dto.RulePayComputeDTO;
import com.bonus.canteen.core.marketing.v2.rule.pay.dto.RulePayResultDTO;
import com.bonus.canteen.core.marketing.v2.rule.price.api.RulePriceApi;
import com.bonus.canteen.core.marketing.v2.rule.price.dto.RulePriceDTO;
import com.bonus.canteen.core.marketing.v2.rule.price.dto.RulePriceResultDTO;
import com.bonus.canteen.core.marketing.v2.rule.price.dto.RulePriceResultOrderDTO;
import com.bonus.canteen.core.marketing.v2.rule.recharge.api.RuleRechargeApi;
import com.bonus.canteen.core.marketing.v2.rule.recharge.dto.RuleRechargeComputeDTO;
import com.bonus.canteen.core.marketing.v2.rule.recharge.dto.RuleRechargeResultDTO;
import com.bonus.canteen.core.marketing.v2.service.MarketRuleRecordService;
import com.bonus.canteen.core.pay.common.constants.PayChannelEnum;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class MarketApi {
   private static final Logger log = LoggerFactory.getLogger(MarketApi.class);
   @Resource
   @Lazy
   private GlobalMetadataApi globalMetadataApi;
   @Resource
   private RuleRechargeApi ruleRechargeApi;
   @Resource
   private RulePayApi rulePayApi;

   @Autowired
   private RuleMealApi ruleMealApi;

   @Autowired
   private RulePriceApi rulePriceApi;

   @Autowired
   private MarketRuleRecordService marketRuleRecordService;

   public RuleRechargeResultDTO ruleRechargeCompute(RuleRechargeComputeDTO computeDTO) {
      log.info("【充值规则】入参：{}", JSONUtil.toJsonStr(computeDTO));
      if (Objects.isNull(computeDTO.getCustId())) {
         throw new ServiceException("人员ID不允许为空");
      } else {
         String value = this.globalMetadataApi.getAvailableValue(MetadataModelTypeEnum.MERCHANT, "ifUseRuleRecharge", (Long)null, (Long)null);
         boolean flag = CharSequenceUtil.equals(value, LeConstants.COMMON_YES.toString());
         if (!flag) {
            log.info("商户未配置充值规则");
            return new RuleRechargeResultDTO(computeDTO);
         } else {
            String key = String.format("yunshitang:%s:market:recharge:%s", TenantContextHolder.getTenantId(), computeDTO.getCustId());
            RLock lock = RedisUtil.getLock(key);
            lock.lock(300L, TimeUnit.SECONDS);

            RuleRechargeResultDTO var6;
            try {
               var6 = this.ruleRechargeApi.compute(computeDTO);
            } catch (Exception var10) {
               log.info("充值规则异常：", var10);
               throw new ServiceException(var10.getMessage());
            } finally {
               if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                  lock.unlock();
               }
            }
            return var6;
         }
      }
   }

   public RulePayResultDTO rulePayCompute(RulePayComputeDTO computeDTO) {
      log.info("【扣款规则】入参：{}", JSONUtil.toJsonStr(computeDTO));
      String value = this.globalMetadataApi.getAvailableValue(MetadataModelTypeEnum.MERCHANT, "ifUseRulePay", (Long)null, (Long)null);
      boolean flag = CharSequenceUtil.equals(value, LeConstants.COMMON_YES.toString());
      if (!flag) {
         log.info("商户未配置扣款规则");
         return new RulePayResultDTO();
      } else {
         return this.rulePayApi.compute(computeDTO);
      }
   }

   public void ruleMealCompute(RulePriceDTO rulePriceDTO) {
      log.info("【就餐规则】入参：{}", JSONUtil.toJsonStr(rulePriceDTO));
      if (PayChannelEnum.OTHER.getKey().equals(rulePriceDTO.getPayChannel())) {
         log.info("【就餐规则】记账不走规则");
      } else if (CollUtil.isEmpty(rulePriceDTO.getOrders())) {
         throw new ServiceException("订单列表不允许为空");
      } else if (Objects.isNull(rulePriceDTO.getCustId())) {
         throw new ServiceException("人员ID不允许为空");
      } else {
         String value = this.globalMetadataApi.getAvailableValue(MetadataModelTypeEnum.MERCHANT, "ifUseRuleMeal", (Long)null, (Long)null);
         boolean flag = CharSequenceUtil.equals(value, LeConstants.COMMON_YES.toString());
         if (!flag) {
            log.info("商户未配置就餐规则");
         } else {
            this.ruleMealApi.compute(rulePriceDTO);
         }
      }
   }

   public RulePriceResultDTO rulePriceCompute(RulePriceDTO rulePriceDTO) {
      log.info("【计价规则】入参：{}", JSONUtil.toJsonStr(rulePriceDTO));
      if (CollUtil.isEmpty(rulePriceDTO.getOrders())) {
         throw new ServiceException("订单列表不允许为空");
      } else if (Objects.isNull(rulePriceDTO.getCustId())) {
         throw new ServiceException("人员ID不允许为空");
      } else if (PayChannelEnum.OTHER.getKey().equals(rulePriceDTO.getPayChannel())) {
         log.info("【计价规则】记账不走规则");
         return new RulePriceResultDTO(RulePriceResultOrderDTO.convertToResultOrder(rulePriceDTO.getOrders()));
      } else {
         String value = this.globalMetadataApi.getAvailableValue(MetadataModelTypeEnum.MERCHANT, "ifUseRulePrice", (Long)null, (Long)null);
         boolean flag = CharSequenceUtil.equals(value, LeConstants.COMMON_YES.toString());
         if (!flag) {
            log.info("商户未配置计价规则");
            return new RulePriceResultDTO(RulePriceResultOrderDTO.convertToResultOrder(rulePriceDTO.getOrders()));
         } else {
            String key = String.format("yunshitang:%s:market:price:%s", TenantContextHolder.getTenantId(), rulePriceDTO.getCustId());
            RLock lock = RedisUtil.getLock(key);
            lock.lock(300L, TimeUnit.SECONDS);

            RulePriceResultDTO var6;
            try {
               var6 = this.rulePriceApi.compute(rulePriceDTO);
            } catch (Exception var10) {
               log.info("计价规则异常：", var10);
               throw new ServiceException(var10.getMessage());
            } finally {
               if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                  lock.unlock();
               }

            }

            return var6;
         }
      }
   }

   public void disableMarketRecord(List<Long> orderIds) {
      if (!CollUtil.isEmpty(orderIds)) {
         this.marketRuleRecordService.disableRecord(orderIds);
      }
   }
}
