package com.red.circle.other.app.command.activity.query;

import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.other.app.common.props.GroupRewardPoolCommon;
import com.red.circle.other.app.dto.clientobject.activity.ActivityUserRewardPropsCO;
import com.red.circle.other.infra.database.cache.service.user.UserInviteCacheService;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRuleConfig;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteUserSummary;
import com.red.circle.other.infra.database.rds.service.user.user.InviteUserSummaryService;
import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum;
import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardProps;
import com.red.circle.other.inner.model.dto.activity.rule.CumulativeRechargeContent;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.num.ArithmeticUtils;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 邀请用户注册活动 邀请用户数量奖励 .
 *
 * @author pengshigang on 2022/5/24
 */
@Component
@RequiredArgsConstructor
public class InviteUserQuantityAwardQueryExe {

  private final GroupRewardPoolCommon groupRewardPoolManager;
  private final UserInviteCacheService userInviteCacheService;
  private final InviteUserSummaryService inviteUserSummaryService;

  public List<ActivityUserRewardPropsCO> execute(AppExtCommand cmd) {

    List<ActivityUserRewardPropsCO> result = Lists.newArrayList();

    String idsStr = userInviteCacheService.getRewardsReceivedRuleIds(cmd.getReqUserId());
    //已领取的奖励组ID
    List<Long> ruleConfigIds = Optional.ofNullable(JacksonUtils.readValue(idsStr, new
            TypeReference<List<Long>>() {
            }))
        .orElse(Lists.newArrayList());

    //消耗金额
    InviteUserSummary summary = inviteUserSummaryService.getByUserId(cmd.getReqUserId());
    Long userCount = 0L;
    if (Objects.nonNull(summary)) {
      userCount = summary.getQuantity();
    }

    List<PropsActivityRuleConfig> activityRuleConfigs = getActivityRuleConfigs(cmd);

    Map<Long, List<ActivityRewardProps>> mapRewardProps = groupRewardPoolManager.mapRewardProps(
        cmd.requireReqSysOriginEnum(),
        activityRuleConfigs.stream().map(PropsActivityRuleConfig::getResourceGroupId)
            .collect(Collectors.toSet()));

    for (PropsActivityRuleConfig config : activityRuleConfigs) {

      ActivityUserRewardPropsCO rewardPropsCO = getBuild();

      CumulativeRechargeContent cumulativeRechargeContent = CumulativeRechargeContent
          .serializable(config.getJsonData());

      // 2040 配置错误
      ResponseAssert.isTrue(CommonErrorCode.CONFIGURATION_ERROR,
          Objects.nonNull(cumulativeRechargeContent) && ArithmeticUtils
              .gt(cumulativeRechargeContent.getQuantity(), BigDecimal.ZERO));

      rewardPropsCO.setActivityRewardPropsList(mapRewardProps.get(config.getResourceGroupId()));

      rewardPropsCO.setQuantity(cumulativeRechargeContent.getQuantity());
      rewardPropsCO.setId(config.getId());

      //不够资格显示要求金额
      if (userCount < cumulativeRechargeContent.getQuantity().longValue()) {
        rewardPropsCO.setState(0);
        result.add(rewardPropsCO);
        continue;
      }

      if (ruleConfigIds.contains(config.getId())) {
        rewardPropsCO.setState(2);
        result.add(rewardPropsCO);
        continue;
      }

      rewardPropsCO.setState(1);
      result.add(rewardPropsCO);
    }
    return result;
  }

  private ActivityUserRewardPropsCO getBuild() {
    return new ActivityUserRewardPropsCO();
  }


  private List<PropsActivityRuleConfig> getActivityRuleConfigs(AppExtCommand cmd) {
    List<PropsActivityRuleConfig> configs = groupRewardPoolManager
        .listByActivityTypeLimit(cmd.requireReqSysOriginEnum(),
            PropsActivityTypeEnum.INVITE_USER_REWARDS);
    ResponseAssert.notEmpty(CommonErrorCode.DATA_ERROR, configs);
    return configs;
  }


}
