import { RankingMergerService } from '../../../src/domain/services/ranking-merger.service';
import { LeaderboardRanking } from '../../../src/domain/aggregates/leaderboard-ranking/leaderboard-ranking.aggregate';
import { LeaderboardType, LeaderboardPeriod, UserSnapshot } from '../../../src/domain/value-objects';

describe('RankingMergerService', () => {
  let service: RankingMergerService;
  let mockPeriod: LeaderboardPeriod;

  beforeEach(() => {
    service = new RankingMergerService();
    mockPeriod = LeaderboardPeriod.currentDaily();
  });

  const createRealRanking = (userId: bigint, rankPosition: number) => {
    return LeaderboardRanking.createRealRanking({
      leaderboardType: LeaderboardType.DAILY,
      period: mockPeriod,
      userId,
      rankPosition,
      displayPosition: rankPosition,
      previousRank: null,
      totalTeamPlanting: 100,
      maxDirectTeamPlanting: 50,
      userSnapshot: UserSnapshot.create({
        userId,
        nickname: `用户${userId}`,
      }),
    });
  };

  const createVirtualRanking = (virtualAccountId: bigint, displayPosition: number) => {
    return LeaderboardRanking.createVirtualRanking({
      leaderboardType: LeaderboardType.DAILY,
      period: mockPeriod,
      virtualAccountId,
      displayPosition,
      generatedScore: 500,
      displayName: `虚拟用户${virtualAccountId}`,
      avatar: null,
    });
  };

  describe('mergeRankings', () => {
    it('没有虚拟排名时应该保持原始排名', () => {
      const realRankings = [
        createRealRanking(1n, 1),
        createRealRanking(2n, 2),
        createRealRanking(3n, 3),
      ];

      const merged = service.mergeRankings([], realRankings, 30);

      expect(merged.length).toBe(3);
      expect(merged[0].displayPosition.value).toBe(1);
      expect(merged[1].displayPosition.value).toBe(2);
      expect(merged[2].displayPosition.value).toBe(3);
    });

    it('有虚拟排名时应该正确调整真实用户排名', () => {
      const virtualRankings = [
        createVirtualRanking(100n, 1),
        createVirtualRanking(101n, 2),
      ];

      const realRankings = [
        createRealRanking(1n, 1),
        createRealRanking(2n, 2),
      ];

      const merged = service.mergeRankings(virtualRankings, realRankings, 30);

      expect(merged.length).toBe(4);
      expect(merged[0].isVirtual).toBe(true);
      expect(merged[0].displayPosition.value).toBe(1);
      expect(merged[1].isVirtual).toBe(true);
      expect(merged[1].displayPosition.value).toBe(2);
      expect(merged[2].isVirtual).toBe(false);
      expect(merged[2].displayPosition.value).toBe(3); // 原来第1名变成第3名
      expect(merged[3].isVirtual).toBe(false);
      expect(merged[3].displayPosition.value).toBe(4); // 原来第2名变成第4名
    });

    it('应该遵守显示数量限制', () => {
      const virtualRankings = [
        createVirtualRanking(100n, 1),
        createVirtualRanking(101n, 2),
      ];

      const realRankings = [
        createRealRanking(1n, 1),
        createRealRanking(2n, 2),
        createRealRanking(3n, 3),
      ];

      const merged = service.mergeRankings(virtualRankings, realRankings, 3);

      expect(merged.length).toBe(3);
      expect(merged[0].isVirtual).toBe(true);
      expect(merged[1].isVirtual).toBe(true);
      expect(merged[2].isVirtual).toBe(false);
    });
  });

  describe('getRealRankingsOnly', () => {
    it('应该只返回真实用户排名', () => {
      const virtualRanking = createVirtualRanking(100n, 1);
      const realRanking = createRealRanking(1n, 2);

      const rankings = [virtualRanking, realRanking];
      const realOnly = service.getRealRankingsOnly(rankings, 10);

      expect(realOnly.length).toBe(1);
      expect(realOnly[0].isVirtual).toBe(false);
    });
  });

  describe('getVirtualRankingsOnly', () => {
    it('应该只返回虚拟排名', () => {
      const virtualRanking = createVirtualRanking(100n, 1);
      const realRanking = createRealRanking(1n, 2);

      const rankings = [virtualRanking, realRanking];
      const virtualOnly = service.getVirtualRankingsOnly(rankings);

      expect(virtualOnly.length).toBe(1);
      expect(virtualOnly[0].isVirtual).toBe(true);
    });
  });

  describe('calculateRealRankPosition', () => {
    it('应该正确计算真实排名位置', () => {
      const virtualRanking = createVirtualRanking(100n, 1);
      const realRanking1 = createRealRanking(1n, 2);
      const realRanking2 = createRealRanking(2n, 3);

      const rankings = [virtualRanking, realRanking1, realRanking2];

      expect(service.calculateRealRankPosition(rankings, 1n)).toBe(1);
      expect(service.calculateRealRankPosition(rankings, 2n)).toBe(2);
    });

    it('用户不在排名中应该返回null', () => {
      const rankings = [createRealRanking(1n, 1)];

      expect(service.calculateRealRankPosition(rankings, 999n)).toBeNull();
    });
  });

  describe('validateRankingContinuity', () => {
    it('连续排名应该验证通过', () => {
      const rankings = [
        createRealRanking(1n, 1),
        createRealRanking(2n, 2),
        createRealRanking(3n, 3),
      ];

      expect(service.validateRankingContinuity(rankings)).toBe(true);
    });

    it('空数组应该验证通过', () => {
      expect(service.validateRankingContinuity([])).toBe(true);
    });
  });
});
