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

import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.tool.core.date.DateUtils;
import com.red.circle.other.app.dto.clientobject.user.invite.InviteRedPacketUserInfoCO;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.cache.service.user.RedPacketInviteUserCacheService;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteRedPacketRecord;
import com.red.circle.other.infra.database.rds.service.user.user.InviteRedPacketRecordService;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import java.math.BigDecimal;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 邀请用户-红包基础信息.
 * </p>
 *
 * @author pengshigang
 * @since 2023-12-20
 */
@Service
@AllArgsConstructor
public class InviteNewRedPacketInfoQryExe {

  private final UserProfileGateway userProfileGateway;
  private final InviteRedPacketRecordService inviteRedPacketRecordService;
  private final RedPacketInviteUserCacheService redPacketInviteUserCacheService;

  public InviteRedPacketUserInfoCO execute(AppExtCommand cmd) {

    UserProfile userProfile = userProfileGateway.getByUserId(cmd.getReqUserId());
    ResponseAssert.notNull(UserErrorCode.USER_INFO_NOT_FOUND, userProfile);

    InviteRedPacketUserInfoCO redPacketInfoCO = new InviteRedPacketUserInfoCO();
    redPacketInfoCO.setThisInviteCode(userProfile.getAccount());

    InviteRedPacketRecord packetRecord = getUserRedPacketByUndone(cmd);
    if (Objects.isNull(packetRecord)) {
      return redPacketInfoCO;
    }

    redPacketInfoCO.setCountdown(
        DateUtils.toDurationSeconds(DateUtils.now(), packetRecord.getExpiresTime()));
    redPacketInfoCO.setTotalAmount(packetRecord.getTotalAmount());
    redPacketInfoCO.setCurrentAmount(packetRecord.getCurrentAmount());
    redPacketInfoCO.setRemainAmount(BigDecimal.valueOf(packetRecord.getTotalAmount())
        .subtract(packetRecord.getCurrentAmount()));
    redPacketInfoCO.setResidueNumber(getRedPacketLotteryCount(packetRecord));
    return redPacketInfoCO;
  }

  private InviteRedPacketRecord getUserRedPacketByUndone(AppExtCommand cmd) {
    return inviteRedPacketRecordService.getUserRedPacketByUndone(
        cmd.getReqUserId());
  }

  private Long getRedPacketLotteryCount(InviteRedPacketRecord packetRecord) {
    return redPacketInviteUserCacheService.getRedPacketLotteryCount(packetRecord.getId());
  }

}
