package com.red.circle.other.infra.gateway.user;

import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.web.props.EnvProperties;
import com.red.circle.mq.business.model.event.user.AccountBeautifulNumberEvent;
import com.red.circle.mq.rocket.business.producer.UserMqMessageService;
import com.red.circle.tool.core.num.account.PrettyAccount;
import com.red.circle.tool.core.num.account.PrettyAccountEnum;
import com.red.circle.other.domain.gateway.user.UserAccountShortProductionGateway;
import com.red.circle.other.infra.database.rds.service.user.user.BaseInfoService;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 用户短账号生产 实现.
 *
 * @author pengliang on 2023/12/17
 */
@Component
@RequiredArgsConstructor
public class UserAccountShortProductionGatewayImpl implements UserAccountShortProductionGateway {

  /**
   * 起步 account.
   */
  private static final Long INIT_ACCOUNT = 1000000L;
  private final RedisService redisService;
  private final EnvProperties evnProperties;
  private final BaseInfoService baseInfoService;
  private final UserMqMessageService userMqMessageService;
  private static final String USER_ACCOUNT_SHORT = "USER_ACCOUNT_SHORT";
  private static final String USER_ACCOUNT_SHORT_DEV = "USER_ACCOUNT_SHORT_DEV";

  @Override
  public String getNewAccount() {
//    if (evnProperties.isDev()) {
//      return Objects.toString(generateUserAccountDev(40000L, 60000L));
//    }
    // if (evnProperties.isTest()) {
    //   return generateUserAccountDev(60001L, 80000L);
    // }
    Long account = generateUserAccount();
    PrettyAccountEnum prettyAccountEnum = PrettyAccount.getPrettyAccountType(account);
    if (!Objects.equals(prettyAccountEnum, PrettyAccountEnum.NONE)) {
      userMqMessageService.accountBeautifulNumber(
          AccountBeautifulNumberEvent.newUserAccount(account, prettyAccountEnum));
      return getNewAccount();
    }
    return Objects.toString(account);
  }

  private Long generateUserAccountDev(Long start, Long end) {
    Long account = incrDevelopUserAccount();
    if (account < start) {

      return incrDevelopUserAccount(baseInfoService.maxUserAccount(start, end));
    }
    if (account > end) {
      throw new RuntimeException(
          "[dev/test] account range DEV(40000 ~ 60000) TEST(60001 ~ 80000) Use complete.");
    }
    return account;
  }

  private Long generateUserAccount() {
    Long account = incrUserAccount();
    if (account < INIT_ACCOUNT) {
      Long maxAccount = baseInfoService.maxUserAccount();
      account = incrUserAccount(Objects.isNull(maxAccount) || maxAccount <= 0 ? INIT_ACCOUNT: maxAccount);
    }
    return account;
  }


  private Long incrUserAccount() {
    return redisService.increment(USER_ACCOUNT_SHORT);
  }

  private Long incrDevelopUserAccount() {
    return redisService.increment(USER_ACCOUNT_SHORT_DEV);
  }

  private Long incrDevelopUserAccount(Long account) {
    return redisService.increment(USER_ACCOUNT_SHORT_DEV, account);
  }

  private Long incrUserAccount(Long account) {
    return redisService.increment(USER_ACCOUNT_SHORT, account);
  }

}
