import { Injectable, Inject } from '@nestjs/common';
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 { UserSnapshot } from '../value-objects/user-snapshot.vo';

/**
 * 推荐服务客户端接口（防腐层）
 */
export interface IReferralServiceClient {
  /**
   * 获取龙虎榜统计数据
   */
  getTeamStatisticsForLeaderboard(params: {
    periodStartAt: Date;
    periodEndAt: Date;
    limit: number;
  }): Promise<Array<{
    userId: bigint;
    totalTeamPlanting: number;
    maxDirectTeamPlanting: number;
    effectiveScore: number;
  }>>;
}

/**
 * 身份服务客户端接口（防腐层）
 */
export interface IIdentityServiceClient {
  /**
   * 批量获取用户快照信息
   */
  getUserSnapshots(userIds: bigint[]): Promise<Map<string, {
    userId: bigint;
    nickname: string;
    avatar: string | null;
    accountNo: string | null;
  }>>;
}

export const REFERRAL_SERVICE_CLIENT = Symbol('IReferralServiceClient');
export const IDENTITY_SERVICE_CLIENT = Symbol('IIdentityServiceClient');

/**
 * 龙虎榜计算领域服务
 *
 * 负责计算排名数据的核心逻辑
 */
@Injectable()
export class LeaderboardCalculationService {
  constructor(
    @Inject(REFERRAL_SERVICE_CLIENT)
    private readonly referralService: IReferralServiceClient,
    @Inject(IDENTITY_SERVICE_CLIENT)
    private readonly identityService: IIdentityServiceClient,
  ) {}

  /**
   * 计算龙虎榜排名
   *
   * 流程：
   * 1. 从 Referral Service 获取团队统计数据
   * 2. 从 Identity Service 获取用户信息
   * 3. 构建排名列表
   *
   * @param type - 榜单类型
   * @param limit - 最大返回数量
   * @returns 排名列表
   */
  async calculateRankings(
    type: LeaderboardType,
    limit: number = 100,
  ): Promise<LeaderboardRanking[]> {
    const period = LeaderboardPeriod.current(type);

    // 1. 从 Referral Service 获取团队统计数据
    const teamStats = await this.referralService.getTeamStatisticsForLeaderboard({
      periodStartAt: period.startAt,
      periodEndAt: period.endAt,
      limit,
    });

    if (teamStats.length === 0) {
      return [];
    }

    // 2. 获取用户信息
    const userIds = teamStats.map(s => s.userId);
    const userSnapshots = await this.identityService.getUserSnapshots(userIds);

    // 3. 构建排名列表
    const rankings: LeaderboardRanking[] = [];

    for (let i = 0; i < teamStats.length; i++) {
      const stat = teamStats[i];
      const userInfo = userSnapshots.get(stat.userId.toString());

      if (!userInfo) continue;

      const ranking = LeaderboardRanking.createRealRanking({
        leaderboardType: type,
        period,
        userId: stat.userId,
        rankPosition: i + 1,
        displayPosition: i + 1,  // 初始显示排名等于实际排名
        previousRank: null,      // TODO: 从历史数据获取
        totalTeamPlanting: stat.totalTeamPlanting,
        maxDirectTeamPlanting: stat.maxDirectTeamPlanting,
        userSnapshot: UserSnapshot.create({
          userId: userInfo.userId,
          nickname: userInfo.nickname,
          avatar: userInfo.avatar,
          accountNo: userInfo.accountNo,
        }),
      });

      rankings.push(ranking);
    }

    return rankings;
  }

  /**
   * 根据已有数据重新计算排名（用于手动调整后）
   */
  recalculatePositions(rankings: LeaderboardRanking[]): LeaderboardRanking[] {
    // 按有效分值降序排序
    const sorted = [...rankings].sort((a, b) =>
      b.score.effectiveScore - a.score.effectiveScore
    );

    // 重新分配排名位置
    for (let i = 0; i < sorted.length; i++) {
      sorted[i].updateDisplayPosition(i + 1);
    }

    return sorted;
  }
}
