import { Injectable, Inject } from '@nestjs/common';
import { VirtualAccount } from '../entities/virtual-account.entity';
import { LeaderboardRanking } from '../aggregates/leaderboard-ranking/leaderboard-ranking.aggregate';
import { LeaderboardType } from '../value-objects/leaderboard-type.enum';
import { LeaderboardPeriod } from '../value-objects/leaderboard-period.vo';
import {
  IVirtualAccountRepository,
  VIRTUAL_ACCOUNT_REPOSITORY,
} from '../repositories/virtual-account.repository.interface';

// 随机中文名字库
const CHINESE_SURNAMES = ['王', '李', '张', '刘', '陈', '杨', '赵', '黄', '周', '吴', '徐', '孙', '马', '朱', '胡'];
const CHINESE_NAMES = ['伟', '芳', '娜', '敏', '静', '丽', '强', '磊', '洋', '勇', '艳', '涛', '明', '超', '秀'];

/**
 * 虚拟排名生成服务
 *
 * 负责生成虚拟账户和虚拟排名条目
 */
@Injectable()
export class VirtualRankingGeneratorService {
  constructor(
    @Inject(VIRTUAL_ACCOUNT_REPOSITORY)
    private readonly virtualAccountRepository: IVirtualAccountRepository,
  ) {}

  /**
   * 生成虚拟排名条目
   *
   * @param params.type - 榜单类型
   * @param params.count - 需要生成的虚拟排名数量
   * @param params.topRealScore - 真实用户的最高分（虚拟分值将高于此值）
   */
  async generateVirtualRankings(params: {
    type: LeaderboardType;
    count: number;
    topRealScore: number;
  }): Promise<LeaderboardRanking[]> {
    if (params.count <= 0) {
      return [];
    }

    const period = LeaderboardPeriod.current(params.type);

    // 1. 获取或创建虚拟账户
    let virtualAccounts = await this.virtualAccountRepository.findActiveRankingVirtuals(params.count);

    // 如果虚拟账户不足，创建新的
    if (virtualAccounts.length < params.count) {
      const needed = params.count - virtualAccounts.length;
      const newAccounts = await this.createVirtualAccounts(needed, params.topRealScore);
      await this.virtualAccountRepository.saveAll(newAccounts);
      virtualAccounts = [...virtualAccounts, ...newAccounts];
    }

    // 2. 生成虚拟排名
    const virtualRankings: LeaderboardRanking[] = [];

    // 虚拟账户的分值应该高于真实用户最高分
    const scoreBase = params.topRealScore + 100;

    for (let i = 0; i < params.count; i++) {
      const account = virtualAccounts[i];

      // 生成递减的分值（第一名分值最高）
      const generatedScore = scoreBase + (params.count - i) * 50 + Math.floor(Math.random() * 30);

      const ranking = LeaderboardRanking.createVirtualRanking({
        leaderboardType: params.type,
        period,
        virtualAccountId: account.id!,
        displayPosition: i + 1,  // 虚拟账户占据前面的位置
        generatedScore,
        displayName: account.displayName,
        avatar: account.avatar,
      });

      virtualRankings.push(ranking);
    }

    return virtualRankings;
  }

  /**
   * 创建虚拟账户
   */
  private async createVirtualAccounts(count: number, baseScore: number): Promise<VirtualAccount[]> {
    const accounts: VirtualAccount[] = [];

    for (let i = 0; i < count; i++) {
      const displayName = this.generateRandomName();
      const avatar = this.generateRandomAvatar();

      const account = VirtualAccount.createRankingVirtual({
        displayName,
        avatar,
        minScore: baseScore,
        maxScore: baseScore + 500,
      });

      accounts.push(account);
    }

    return accounts;
  }

  /**
   * 生成随机中文名（部分脱敏）
   */
  private generateRandomName(): string {
    const surname = CHINESE_SURNAMES[Math.floor(Math.random() * CHINESE_SURNAMES.length)];
    const name1 = CHINESE_NAMES[Math.floor(Math.random() * CHINESE_NAMES.length)];
    const name2 = Math.random() > 0.5
      ? CHINESE_NAMES[Math.floor(Math.random() * CHINESE_NAMES.length)]
      : '';

    // 部分名字用 * 遮挡
    const maskedName = surname + '*' + (name2 || '*');
    return maskedName;
  }

  /**
   * 生成随机头像URL
   */
  private generateRandomAvatar(): string {
    const avatarId = Math.floor(Math.random() * 100) + 1;
    return `https://api.dicebear.com/7.x/avataaars/svg?seed=${avatarId}`;
  }

  /**
   * 批量生成虚拟账户（供管理后台使用）
   */
  async batchCreateVirtualAccounts(params: {
    count: number;
    minScore: number;
    maxScore: number;
  }): Promise<VirtualAccount[]> {
    const accounts: VirtualAccount[] = [];

    for (let i = 0; i < params.count; i++) {
      const displayName = this.generateRandomName();
      const avatar = this.generateRandomAvatar();

      const account = VirtualAccount.createRankingVirtual({
        displayName,
        avatar,
        minScore: params.minScore,
        maxScore: params.maxScore,
      });

      accounts.push(account);
    }

    await this.virtualAccountRepository.saveAll(accounts);
    return accounts;
  }
}
