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

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.other.domain.gateway.props.ActivitySourceGroupGateway;
import com.red.circle.other.infra.common.activity.PropsActivitySendCommon;
import com.red.circle.other.infra.common.activity.send.SendRewardSingle;
import com.red.circle.other.infra.database.cache.service.other.CheckInCacheService;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRewardConfig;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRuleConfig;
import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRuleConfigService;
import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum;
import com.red.circle.other.inner.model.cmd.activity.SendRandomCheckInCmd;
import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardProps;
import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardPropsDTO;
import com.red.circle.tool.core.num.NumUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 新打卡抽奖.
 *
 * @author pengliang on 2020/11/27
 */
@Component
@RequiredArgsConstructor
public class CheckInLotteryQryExe {

  private final CheckInCacheService checkInCacheService;
  private final PropsActivitySendCommon propsActivitySendCommon;
  private final ActivitySourceGroupGateway activitySourceGroupGateway;
  private final PropsActivityRuleConfigService propsActivityRuleConfigService;

  public ActivityRewardPropsDTO execute(AppExtCommand cmd) {

    ResponseAssert.isTrue(UserErrorCode.PROCESSED_TODAY,
        Objects.equals(checkInCacheService.markDailyCheckIn(cmd.getReqUserId()),
            Boolean.TRUE));

    return sendRandomCheckInActivityProps(
        new SendRandomCheckInCmd()
            .setSysOrigin(cmd.requireReqSysOrigin())
            .setAcceptUserId(cmd.requiredReqUserId())
            .setTrackId(IdWorkerUtils.getId())
    );
  }


  public ActivityRewardPropsDTO sendRandomCheckInActivityProps(SendRandomCheckInCmd cmd) {

    List<ActivityRewardPropsDTO> rewardPropsList = listRewardProps(cmd.getSysOrigin());
    ResponseAssert.notEmpty(CommonErrorCode.DATA_ERROR, rewardPropsList);

    ActivityRewardPropsDTO rewardProps = rewardPropsList
        .get(NumUtils.randomBetweenRepeatedly(0, rewardPropsList.size() - 1));
    ResponseAssert.notNull(CommonErrorCode.DATA_ERROR, rewardProps);

    propsActivitySendCommon.sendActivitySingle(SendRewardSingle.builder()
        .rewardConfig(new PropsActivityRewardConfig()
            .setContent(rewardProps.getContent())
            .setDetailType(
                Optional.ofNullable(rewardProps.getDetailType()).orElse(rewardProps.getType()))
            .setQuantity(rewardProps.getQuantity())
            .setType(rewardProps.getType())
            .setGroupId(rewardProps.getGroupId())
        )
        .trackId(cmd.getTrackId())
        .sysOrigin(SysOriginPlatformEnum.valueOf(cmd.getSysOrigin()))
        .acceptUserId(cmd.getAcceptUserId())
        .origin(SendPropsOrigin.DAILY_REGISTER)
        .build());

    return rewardProps;
  }

  private List<ActivityRewardPropsDTO> listRewardProps(String sysOrigin) {
    List<PropsActivityRuleConfig> ruleConfigs = listByActivityTypeLimit(sysOrigin,
        PropsActivityTypeEnum.DAILY_REGISTER);
    if (CollectionUtil.isEmpty(ruleConfigs)) {
      return Lists.newArrayList();
    }

    return getRewardPoolList(
        activitySourceGroupGateway.getActivityPropsGroup(
                sysOrigin, ruleConfigs.get(0).getResourceGroupId())
            .getActivityRewardProps());
  }


  private List<ActivityRewardPropsDTO> getRewardPoolList(
      List<ActivityRewardProps> activityPropsGroups) {

    if (CollectionUtil.isEmpty(activityPropsGroups)) {
      return Lists.newArrayList();
    }

    return activityPropsGroups.stream()
        .map(rewardProps -> new ActivityRewardPropsDTO()
            .setId(rewardProps.getId())
            .setCover(rewardProps.getCover())
            .setGroupId(rewardProps.getGroupId())
            .setSort(rewardProps.getSort())
            .setQuantity(rewardProps.getQuantity())
            .setType(rewardProps.getType())
            .setDetailType(rewardProps.getDetailType())
            .setAmount(rewardProps.getAmount())
            .setRemark(rewardProps.getRemark())
            .setContent(rewardProps.getContent()))
        .collect(Collectors.toList());
  }

  private List<PropsActivityRuleConfig> listByActivityTypeLimit(String sysOrigin,
      PropsActivityTypeEnum type) {

    return Optional.ofNullable(propsActivityRuleConfigService
            .listPlatformByActivityType(sysOrigin, type))
        .orElseGet(Lists::newArrayList);
  }

}
