import { vi, describe, it, expect, beforeEach } from 'vitest';
import { InMemoryLeagueStandingsRepository } from './InMemoryLeagueStandingsRepository';
import type { Logger } from '@core/shared/application';
import type { RawStanding } from '@core/league/application/ports/ILeagueStandingsRepository';

describe('InMemoryLeagueStandingsRepository', () => {
  let repository: InMemoryLeagueStandingsRepository;
  let mockLogger: Logger;

  beforeEach(() => {
    mockLogger = {
      debug: vi.fn(),
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    };
    repository = new InMemoryLeagueStandingsRepository(mockLogger);
  });

  const createTestStanding = (id: string, leagueId: string, driverId: string, position: number, points: number): RawStanding => ({
    id,
    leagueId,
    driverId,
    position,
    points,
    wins: 0,
    racesCompleted: 0,
  });

  describe('constructor', () => {
    it('should initialize with a logger', () => {
      expect(repository).toBeDefined();
      expect(mockLogger.info).toHaveBeenCalledWith('InMemoryLeagueStandingsRepository initialized.');
    });
  });

  describe('getLeagueStandings', () => {
    it('should return empty array if league not found', async () => {
      const result = await repository.getLeagueStandings('nonexistent');
      expect(result).toEqual([]);
      expect(mockLogger.debug).toHaveBeenCalledWith('[InMemoryLeagueStandingsRepository] Getting standings for league: nonexistent.');
      expect(mockLogger.info).toHaveBeenCalledWith('Found 0 standings for league: nonexistent.');
    });

    it('should return the standings if league exists', async () => {
      const standings: RawStanding[] = [
        createTestStanding('1', 'league1', 'driver1', 1, 25),
        createTestStanding('2', 'league1', 'driver2', 2, 20),
      ];
      (repository as InMemoryLeagueStandingsRepository).setLeagueStandings('league1', standings);

      const result = await repository.getLeagueStandings('league1');
      expect(result).toEqual(standings);
      expect(mockLogger.debug).toHaveBeenCalledWith('[InMemoryLeagueStandingsRepository] Getting standings for league: league1.');
      expect(mockLogger.info).toHaveBeenCalledWith('Found 2 standings for league: league1.');
    });

    it('should return empty array if league exists but has no standings', async () => {
      (repository as InMemoryLeagueStandingsRepository).setLeagueStandings('league1', []);

      const result = await repository.getLeagueStandings('league1');
      expect(result).toEqual([]);
      expect(mockLogger.info).toHaveBeenCalledWith('Found 0 standings for league: league1.');
    });
  });

  describe('setLeagueStandings', () => {
    it('should set standings for a league', async () => {
      const standings: RawStanding[] = [
        createTestStanding('1', 'league1', 'driver1', 1, 25),
      ];

      (repository as InMemoryLeagueStandingsRepository).setLeagueStandings('league1', standings);

      const result = await repository.getLeagueStandings('league1');
      expect(result).toEqual(standings);
      expect(mockLogger.debug).toHaveBeenCalledWith('[InMemoryLeagueStandingsRepository] Set standings for league: league1.');
    });
  });
});