import type { RacesPageDataDTO } from '@/lib/types/generated/RacesPageDataDTO';
import type { RacesViewData, RaceViewData } from '@/lib/view-data/RacesViewData';
import { DateDisplay } from '@/lib/display-objects/DateDisplay';
import { RaceStatusDisplay } from '@/lib/display-objects/RaceStatusDisplay';
import { RelativeTimeDisplay } from '@/lib/display-objects/RelativeTimeDisplay';

export class RacesViewDataBuilder {
  static build(apiDto: RacesPageDataDTO): RacesViewData {
    const now = new Date();
    const races = apiDto.races.map((race): RaceViewData => {
      return {
        id: race.id,
        track: race.track,
        car: race.car,
        scheduledAt: race.scheduledAt,
        scheduledAtLabel: DateDisplay.formatShort(race.scheduledAt),
        timeLabel: DateDisplay.formatTime(race.scheduledAt),
        relativeTimeLabel: RelativeTimeDisplay.format(race.scheduledAt, now),
        status: race.status as RaceViewData['status'],
        statusLabel: RaceStatusDisplay.getLabel(race.status),
        statusVariant: RaceStatusDisplay.getVariant(race.status),
        statusIconName: RaceStatusDisplay.getIconName(race.status),
        sessionType: 'Race',
        leagueId: race.leagueId,
        leagueName: race.leagueName,
        strengthOfField: race.strengthOfField ?? null,
        isUpcoming: race.isUpcoming,
        isLive: race.isLive,
        isPast: race.isPast,
      };
    });

    const leagues = Array.from(
      new Map(
        races
          .filter(r => r.leagueId && r.leagueName)
          .map(r => [r.leagueId, { id: r.leagueId!, name: r.leagueName! }])
      ).values()
    );

    const groupedRaces = new Map<string, RaceViewData[]>();
    races.forEach((race) => {
      const dateKey = race.scheduledAt.split('T')[0]!;
      if (!groupedRaces.has(dateKey)) {
        groupedRaces.set(dateKey, []);
      }
      groupedRaces.get(dateKey)!.push(race);
    });

    const racesByDate = Array.from(groupedRaces.entries()).map(([dateKey, dayRaces]) => ({
      dateKey,
      dateLabel: dayRaces[0]?.scheduledAtLabel || '',
      races: dayRaces,
    }));

    return {
      races,
      totalCount: races.length,
      scheduledCount: races.filter(r => r.status === 'scheduled').length,
      runningCount: races.filter(r => r.status === 'running').length,
      completedCount: races.filter(r => r.status === 'completed').length,
      leagues,
      upcomingRaces: races.filter(r => r.isUpcoming).slice(0, 5),
      liveRaces: races.filter(r => r.isLive),
      recentResults: races.filter(r => r.isPast).slice(0, 5),
      racesByDate,
    };
  }
}
