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

import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.common.business.enums.PropsActivityReceiveStatusEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.order.inner.endpoint.UserRechargeCountClient;
import com.red.circle.other.app.dto.clientobject.activity.ActivityCumulativeRechargeCO;
import com.red.circle.other.app.dto.clientobject.activity.ActivityResourceCumulativeRechargeCO;
import com.red.circle.other.domain.gateway.props.ActivitySourceGroupGateway;
import com.red.circle.other.infra.database.rds.entity.user.user.UserCustomGiftRecord;
import com.red.circle.other.infra.database.rds.service.user.user.UserActivityRewardReceiveRecordService;
import com.red.circle.other.infra.database.rds.service.user.user.UserCustomGiftRecordService;
import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum;
import com.red.circle.other.inner.model.dto.activity.props.ActivityResource;
import com.red.circle.other.inner.model.dto.activity.rule.CumulativeRechargeContent;
import com.red.circle.other.inner.model.dto.user.UserActivityRewardReceiveRecordDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateFormatConstant;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
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 lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 累计充值奖励查询.
 *
 * @author pengshigang on 2021/6/21
 */
@Component
@RequiredArgsConstructor
public class MonthlyCumulativeRechargeRewardQueryExe {

  private final UserRechargeCountClient userRechargeCountClient;
  private final ActivitySourceGroupGateway activitySourceGroupGateway;
  private final UserCustomGiftRecordService userCustomGiftRecordService;
  private final UserActivityRewardReceiveRecordService activityRewardReceiveRecordService;


  public ActivityCumulativeRechargeCO execute(AppExtCommand cmd) {

    List<ActivityResource> activityResources = activitySourceGroupGateway
        .listActivityResource(cmd.requireReqSysOriginEnum(),
            PropsActivityTypeEnum.CUMULATIVE_RECHARGE);

    if (CollectionUtils.isEmpty(activityResources)) {
      return null;
    }

    Map<Long, UserActivityRewardReceiveRecordDTO> userRewardReceiveRecordMap = activityRewardReceiveRecordService.mapByThisMonth(
        cmd.getReqUserId());

    // 用户是否允许上传专属礼物
    Map<Integer, UserCustomGiftRecord> userAllowUploadMap = userCustomGiftRecordService.mapByAmount(
        cmd.getReqUserId());

    //累计充值金额
    BigDecimal monthlyRecharge = ResponseAssert.requiredSuccess(userRechargeCountClient
        .getThisMonthTotalPersonalRecharge(cmd.getReqUserId()));

    return new ActivityCumulativeRechargeCO()
        .setMonthlyRecharge(monthlyRecharge)
        .setActivityTime(getActivityTime())
        .setActivityResources(activityResources.stream()
            .map(activityResource -> new ActivityResourceCumulativeRechargeCO()
                .setReceiveStatus(
                    getUserActivityRewardReceiveRecord(userRewardReceiveRecordMap,
                        activityResource,
                        monthlyRecharge))
                .setAllowUpload(userAllowUpload(userAllowUploadMap, activityResource))
                .setCustomGiftRecordId(customGiftRecord(userAllowUploadMap, activityResource))
                .setActivityResource(activityResource)).toList()
        );

  }


  private PropsActivityReceiveStatusEnum getUserActivityRewardReceiveRecord(
      Map<Long, UserActivityRewardReceiveRecordDTO> userRewardReceiveRecordMap,
      ActivityResource activityResource, BigDecimal monthlyRecharge) {

    UserActivityRewardReceiveRecordDTO activityRewardReceiveRecord = userRewardReceiveRecordMap
        .get(activityResource.getRuleId());

    if (Objects.nonNull(activityRewardReceiveRecord)) {
      return PropsActivityReceiveStatusEnum.RECEIVED;
    }

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

    return ArithmeticUtils.gte(monthlyRecharge, cumulativeRechargeContent.getQuantity())
        ? PropsActivityReceiveStatusEnum.NOT_RECEIVED
        : PropsActivityReceiveStatusEnum.INELIGIBLE;
  }


  private String getActivityTime() {
    return LocalDateTimeUtils.nowFirstDayOfMonth(DateFormatConstant.DD_SLASH_MM)
        + " - "
        + LocalDateTimeUtils.lastDayOfMonth(DateFormatConstant.DD_SLASH_MM);
  }

  private Long customGiftRecord(Map<Integer, UserCustomGiftRecord> userAllowUploadMap,
      ActivityResource resource) {
    CumulativeRechargeContent cumulativeRechargeContent = CumulativeRechargeContent
        .serializable(resource.getJsonData());
    return
        Objects.nonNull(userAllowUploadMap.get(cumulativeRechargeContent.getQuantity().intValue()))
            ? userAllowUploadMap.get(cumulativeRechargeContent.getQuantity().intValue()).getId()
            : null;
  }

  private Boolean userAllowUpload(Map<Integer, UserCustomGiftRecord> userAllowUploadMap,
      ActivityResource resource) {
    CumulativeRechargeContent cumulativeRechargeContent = CumulativeRechargeContent
        .serializable(resource.getJsonData());
    return Objects.nonNull(
        userAllowUploadMap.get(cumulativeRechargeContent.getQuantity().intValue()));
  }


}
