import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
import { GetAllLeaguesWithCapacityAndScoringUseCase } from './GetAllLeaguesWithCapacityAndScoringUseCase';
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository';
import type { ISeasonRepository } from '../../domain/repositories/ISeasonRepository';
import type { ILeagueScoringConfigRepository } from '../../domain/repositories/ILeagueScoringConfigRepository';
import type { IGameRepository } from '../../domain/repositories/IGameRepository';
import type { LeagueScoringPresetProvider } from '../ports/LeagueScoringPresetProvider';

describe('GetAllLeaguesWithCapacityAndScoringUseCase', () => {
  let mockLeagueRepo: { findAll: Mock };
  let mockMembershipRepo: { getLeagueMembers: Mock };
  let mockSeasonRepo: { findByLeagueId: Mock };
  let mockScoringConfigRepo: { findBySeasonId: Mock };
  let mockGameRepo: { findById: Mock };
  let mockPresetProvider: { getPresetById: Mock };

  beforeEach(() => {
    mockLeagueRepo = { findAll: vi.fn() };
    mockMembershipRepo = { getLeagueMembers: vi.fn() };
    mockSeasonRepo = { findByLeagueId: vi.fn() };
    mockScoringConfigRepo = { findBySeasonId: vi.fn() };
    mockGameRepo = { findById: vi.fn() };
    mockPresetProvider = { getPresetById: vi.fn() };
  });

  it('should return enriched leagues with capacity and scoring', async () => {
    const useCase = new GetAllLeaguesWithCapacityAndScoringUseCase(
      mockLeagueRepo as unknown as ILeagueRepository,
      mockMembershipRepo as unknown as ILeagueMembershipRepository,
      mockSeasonRepo as unknown as ISeasonRepository,
      mockScoringConfigRepo as unknown as ILeagueScoringConfigRepository,
      mockGameRepo as unknown as IGameRepository,
      mockPresetProvider as unknown as LeagueScoringPresetProvider,
    );

    const league = { id: 'league1', name: 'Test League' };
    const members = [
      { status: 'active', role: 'member' },
      { status: 'active', role: 'owner' },
    ];
    const season = { id: 'season1', status: 'active', gameId: 'game1' };
    const scoringConfig = { scoringPresetId: 'preset1' };
    const game = { id: 'game1', name: 'iRacing' };
    const preset = { id: 'preset1', name: 'Default' };

    mockLeagueRepo.findAll.mockResolvedValue([league]);
    mockMembershipRepo.getLeagueMembers.mockResolvedValue(members);
    mockSeasonRepo.findByLeagueId.mockResolvedValue([season]);
    mockScoringConfigRepo.findBySeasonId.mockResolvedValue(scoringConfig);
    mockGameRepo.findById.mockResolvedValue(game);
    mockPresetProvider.getPresetById.mockReturnValue(preset);

    const result = await useCase.execute();

    expect(result.isOk()).toBe(true);
    expect(result.value).toEqual([
      {
        league,
        usedDriverSlots: 2,
        season,
        scoringConfig,
        game,
        preset,
      },
    ]);
  });
});
