import type { IRaceRepository } from '../../domain/repositories/IRaceRepository';
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
import type { GetAllRacesResultDTO } from '../presenters/IGetAllRacesPresenter';
import type { AsyncUseCase, Logger } from '@core/shared/application';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

export class GetAllRacesUseCase implements AsyncUseCase<void, GetAllRacesResultDTO, 'REPOSITORY_ERROR'> {
  constructor(
    private readonly raceRepository: IRaceRepository,
    private readonly leagueRepository: ILeagueRepository,
    private readonly logger: Logger,
  ) {}

  async execute(): Promise<Result<GetAllRacesResultDTO, ApplicationErrorCode<'REPOSITORY_ERROR', { message: string }>>> {
    this.logger.debug('Executing GetAllRacesUseCase');
    try {
      const races = await this.raceRepository.findAll();
      const leagues = await this.leagueRepository.findAll();
      const leagueMap = new Map(leagues.map(league => [league.id, league.name]));

      const raceViewModels = races.map(race => ({
        id: race.id,
        name: `${race.track} - ${race.car}`,
        date: race.scheduledAt.toISOString(),
        leagueName: leagueMap.get(race.leagueId) || 'Unknown League',
      }));

      const dto: GetAllRacesResultDTO = {
        races: raceViewModels,
        totalCount: races.length,
      };

      this.logger.debug('Successfully retrieved all races.');
      return Result.ok(dto);
    } catch (error) {
      this.logger.error('Error executing GetAllRacesUseCase', error instanceof Error ? error : new Error(String(error)));
      return Result.err({
        code: 'REPOSITORY_ERROR',
        details: { message: error instanceof Error ? error.message : 'Unknown error occurred' },
      });
    }
  }
}