import 'reflect-metadata';

import { Test } from '@nestjs/testing';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';

import { LeagueModule } from './LeagueModule';
import {
  GET_LEAGUE_FULL_CONFIG_USE_CASE,
  LEAGUE_REPOSITORY_TOKEN,
  SEASON_REPOSITORY_TOKEN,
  LEAGUE_SCORING_CONFIG_REPOSITORY_TOKEN,
  GAME_REPOSITORY_TOKEN,
} from './LeagueProviders';

import { GetLeagueFullConfigUseCase } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
import type { LeagueRepository } from '@core/racing/domain/repositories/LeagueRepository';
import type { SeasonRepository } from '@core/racing/domain/repositories/SeasonRepository';
import type { LeagueScoringConfigRepository } from '@core/racing/domain/repositories/LeagueScoringConfigRepository';
import type { GameRepository } from '@core/racing/domain/repositories/GameRepository';

describe('LeagueProviders - Dependency Injection', () => {
  let module: import('@nestjs/testing').TestingModule;

  beforeEach(async () => {
    module = await Test.createTestingModule({
      imports: [LeagueModule],
    }).compile();
  });

  afterEach(async () => {
    await module.close();
  });

  it('should inject GetLeagueFullConfigUseCase with all required dependencies', () => {
    // Get the use case instance
    const useCase = module.get<GetLeagueFullConfigUseCase>(GET_LEAGUE_FULL_CONFIG_USE_CASE);

    // Verify the use case is defined
    expect(useCase).toBeDefined();
    expect(useCase).toBeInstanceOf(GetLeagueFullConfigUseCase);

    // Get the repositories to verify they exist
    const leagueRepo = module.get<LeagueRepository>(LEAGUE_REPOSITORY_TOKEN);
    const seasonRepo = module.get<SeasonRepository>(SEASON_REPOSITORY_TOKEN);
    const scoringRepo = module.get<LeagueScoringConfigRepository>(LEAGUE_SCORING_CONFIG_REPOSITORY_TOKEN);
    const gameRepo = module.get<GameRepository>(GAME_REPOSITORY_TOKEN);

    // Verify all repositories are defined
    expect(leagueRepo).toBeDefined();
    expect(seasonRepo).toBeDefined();
    expect(scoringRepo).toBeDefined();
    expect(gameRepo).toBeDefined();

    // Verify the use case has the repositories injected
    // We can't directly access private properties, but we can verify the use case is functional
    // by checking that it has the execute method
    expect(typeof useCase.execute).toBe('function');
  });

  it('should have the correct token for GetLeagueFullConfigUseCase', () => {
    expect(GET_LEAGUE_FULL_CONFIG_USE_CASE).toBe('GetLeagueFullConfigUseCase');
  });

  it('should have all required repository tokens defined', () => {
    expect(LEAGUE_REPOSITORY_TOKEN).toBe('ILeagueRepository');
    expect(SEASON_REPOSITORY_TOKEN).toBe('ISeasonRepository');
    expect(LEAGUE_SCORING_CONFIG_REPOSITORY_TOKEN).toBe('ILeagueScoringConfigRepository');
    expect(GAME_REPOSITORY_TOKEN).toBe('IGameRepository');
  });
});
