import type {
  IRacesPagePresenter,
  RacesPageViewModel,
  RaceListItemViewModel,
  RacesPageResultDTO,
} from '@core/racing/application/presenters/IRacesPagePresenter';

export class RacesPagePresenter implements IRacesPagePresenter {
  private viewModel: RacesPageViewModel | null = null;

  reset(): void {
    this.viewModel = null;
  }

  present(input: RacesPageResultDTO): void {
    const { races } = input;
    const now = new Date();
    const nextWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);

    const raceViewModels: RaceListItemViewModel[] = races.map((race) => {
      const scheduledAt =
        typeof race.scheduledAt === 'string'
          ? race.scheduledAt
          : race.scheduledAt.toISOString();

      const allowedStatuses: RaceListItemViewModel['status'][] = [
        'scheduled',
        'running',
        'completed',
        'cancelled',
      ];

      const status: RaceListItemViewModel['status'] =
        allowedStatuses.includes(race.status as RaceListItemViewModel['status'])
          ? (race.status as RaceListItemViewModel['status'])
          : 'scheduled';

      return {
        id: race.id,
        track: race.track,
        car: race.car,
        scheduledAt,
        status,
        leagueId: race.leagueId,
        leagueName: race.leagueName,
        strengthOfField: race.strengthOfField,
        isUpcoming: race.isUpcoming,
        isLive: race.isLive,
        isPast: race.isPast,
      };
    });

    const stats = {
      total: raceViewModels.length,
      scheduled: raceViewModels.filter(r => r.status === 'scheduled').length,
      running: raceViewModels.filter(r => r.status === 'running').length,
      completed: raceViewModels.filter(r => r.status === 'completed').length,
    };

    const liveRaces = raceViewModels.filter(r => r.isLive);

    const upcomingThisWeek = raceViewModels
      .filter(r => {
        const scheduledDate = new Date(r.scheduledAt);
        return r.isUpcoming && scheduledDate >= now && scheduledDate <= nextWeek;
      })
      .slice(0, 5);

    const recentResults = raceViewModels
      .filter(r => r.status === 'completed')
      .sort((a, b) => new Date(b.scheduledAt).getTime() - new Date(a.scheduledAt).getTime())
      .slice(0, 3);

    this.viewModel = {
      races: raceViewModels,
      stats,
      liveRaces,
      upcomingThisWeek,
      recentResults,
    };
  }

  getViewModel(): RacesPageViewModel {
    if (!this.viewModel) {
      throw new Error('ViewModel not yet generated. Call present() first.');
    }
    return this.viewModel;
  }
}