import { LeaderboardType } from '../../src/domain/value-objects/leaderboard-type.enum';
import { LeaderboardPeriod } from '../../src/domain/value-objects/leaderboard-period.vo';

describe('LeaderboardRepository Integration Tests', () => {
  describe('Database Connection', () => {
    it('should connect to the database', async () => {
      const isConnected = global.testUtils?.prisma !== undefined;

      if (!isConnected) {
        console.log('Skipping database test - no connection available');
        return;
      }

      // Test basic query
      const result = await global.testUtils.prisma.$queryRaw`SELECT 1 as result`;
      expect(result).toBeDefined();
    });
  });

  describe('LeaderboardConfig Operations', () => {
    beforeEach(async () => {
      if (global.testUtils?.cleanDatabase) {
        await global.testUtils.cleanDatabase();
      }
    });

    it('should create and retrieve leaderboard config', async () => {
      if (!global.testUtils?.prisma) {
        console.log('Skipping test - no database connection');
        return;
      }

      const config = await global.testUtils.prisma.leaderboardConfig.create({
        data: {
          configKey: 'TEST_CONFIG',
          dailyEnabled: true,
          weeklyEnabled: true,
          monthlyEnabled: true,
          virtualRankingEnabled: false,
          virtualAccountCount: 0,
          displayLimit: 30,
          refreshIntervalMinutes: 5,
        },
      });

      expect(config.id).toBeDefined();
      expect(config.configKey).toBe('TEST_CONFIG');
      expect(config.dailyEnabled).toBe(true);

      // Retrieve
      const retrieved = await global.testUtils.prisma.leaderboardConfig.findUnique({
        where: { configKey: 'TEST_CONFIG' },
      });

      expect(retrieved).toBeDefined();
      expect(retrieved?.displayLimit).toBe(30);
    });

    it('should update leaderboard config', async () => {
      if (!global.testUtils?.prisma) {
        console.log('Skipping test - no database connection');
        return;
      }

      await global.testUtils.prisma.leaderboardConfig.create({
        data: {
          configKey: 'UPDATE_TEST',
          dailyEnabled: true,
          weeklyEnabled: true,
          monthlyEnabled: true,
          virtualRankingEnabled: false,
          virtualAccountCount: 0,
          displayLimit: 30,
          refreshIntervalMinutes: 5,
        },
      });

      const updated = await global.testUtils.prisma.leaderboardConfig.update({
        where: { configKey: 'UPDATE_TEST' },
        data: {
          virtualRankingEnabled: true,
          virtualAccountCount: 20,
        },
      });

      expect(updated.virtualRankingEnabled).toBe(true);
      expect(updated.virtualAccountCount).toBe(20);
    });
  });

  describe('LeaderboardRanking Operations', () => {
    beforeEach(async () => {
      if (global.testUtils?.cleanDatabase) {
        await global.testUtils.cleanDatabase();
      }
    });

    it('should create leaderboard ranking entries', async () => {
      if (!global.testUtils?.prisma) {
        console.log('Skipping test - no database connection');
        return;
      }

      const period = LeaderboardPeriod.currentDaily();

      const ranking = await global.testUtils.prisma.leaderboardRanking.create({
        data: {
          leaderboardType: LeaderboardType.DAILY,
          periodKey: period.key,
          periodStartAt: period.startAt,
          periodEndAt: period.endAt,
          userId: BigInt(1),
          rankPosition: 1,
          displayPosition: 1,
          previousRank: null,
          totalTeamPlanting: 200,
          maxDirectTeamPlanting: 50,
          effectiveScore: 150,
          isVirtual: false,
          userSnapshot: { nickname: 'TestUser', avatar: null },
        },
      });

      expect(ranking.id).toBeDefined();
      expect(ranking.rankPosition).toBe(1);
      expect(ranking.effectiveScore).toBe(150);
    });

    it('should query rankings by period and type', async () => {
      if (!global.testUtils?.prisma) {
        console.log('Skipping test - no database connection');
        return;
      }

      const period = LeaderboardPeriod.currentDaily();

      // Create multiple rankings
      await global.testUtils.prisma.leaderboardRanking.createMany({
        data: [
          {
            leaderboardType: LeaderboardType.DAILY,
            periodKey: period.key,
            periodStartAt: period.startAt,
            periodEndAt: period.endAt,
            userId: BigInt(1),
            rankPosition: 1,
            displayPosition: 1,
            totalTeamPlanting: 300,
            maxDirectTeamPlanting: 100,
            effectiveScore: 200,
            isVirtual: false,
            userSnapshot: { nickname: 'User1', avatar: null },
          },
          {
            leaderboardType: LeaderboardType.DAILY,
            periodKey: period.key,
            periodStartAt: period.startAt,
            periodEndAt: period.endAt,
            userId: BigInt(2),
            rankPosition: 2,
            displayPosition: 2,
            totalTeamPlanting: 200,
            maxDirectTeamPlanting: 50,
            effectiveScore: 150,
            isVirtual: false,
            userSnapshot: { nickname: 'User2', avatar: null },
          },
        ],
      });

      const rankings = await global.testUtils.prisma.leaderboardRanking.findMany({
        where: {
          leaderboardType: LeaderboardType.DAILY,
          periodKey: period.key,
        },
        orderBy: { rankPosition: 'asc' },
      });

      expect(rankings.length).toBe(2);
      expect(rankings[0].effectiveScore).toBe(200);
      expect(rankings[1].effectiveScore).toBe(150);
    });
  });

  describe('VirtualAccount Operations', () => {
    beforeEach(async () => {
      if (global.testUtils?.cleanDatabase) {
        await global.testUtils.cleanDatabase();
      }
    });

    it('should create virtual accounts', async () => {
      if (!global.testUtils?.prisma) {
        console.log('Skipping test - no database connection');
        return;
      }

      const virtualAccount = await global.testUtils.prisma.virtualAccount.create({
        data: {
          displayName: 'VirtualUser1',
          avatar: null,
          accountType: 'RANKING_VIRTUAL',
          isActive: true,
        },
      });

      expect(virtualAccount.id).toBeDefined();
      expect(virtualAccount.displayName).toBe('VirtualUser1');
      expect(virtualAccount.isActive).toBe(true);
    });

    it('should query active virtual accounts', async () => {
      if (!global.testUtils?.prisma) {
        console.log('Skipping test - no database connection');
        return;
      }

      await global.testUtils.prisma.virtualAccount.createMany({
        data: [
          { displayName: 'Active1', accountType: 'RANKING_VIRTUAL', isActive: true },
          { displayName: 'Active2', accountType: 'RANKING_VIRTUAL', isActive: true },
          { displayName: 'Inactive', accountType: 'RANKING_VIRTUAL', isActive: false },
        ],
      });

      const activeAccounts = await global.testUtils.prisma.virtualAccount.findMany({
        where: { isActive: true },
      });

      expect(activeAccounts.length).toBe(2);
    });
  });
});
