import type {
    DashboardOverviewResult,
} from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import {
    DashboardDriverSummaryDTO,
    DashboardFeedItemSummaryDTO,
    DashboardFeedSummaryDTO,
    DashboardFriendSummaryDTO,
    DashboardLeagueStandingSummaryDTO,
    DashboardOverviewDTO,
    DashboardRaceSummaryDTO,
    DashboardRecentResultDTO,
} from '../dtos/DashboardOverviewDTO';

export class DashboardOverviewPresenter {
  private responseModel: DashboardOverviewDTO | null = null;

  present(data: DashboardOverviewResult): void {
    const currentDriver: DashboardDriverSummaryDTO | null = data.currentDriver
      ? {
          id: data.currentDriver.driver.id,
          name: String(data.currentDriver.driver.name),
          country: String(data.currentDriver.driver.country),
          avatarUrl: data.currentDriver.avatarUrl,
          category: data.currentDriver.driver.category ?? null,
          rating: data.currentDriver.rating,
          globalRank: data.currentDriver.globalRank,
          totalRaces: data.currentDriver.totalRaces,
          wins: data.currentDriver.wins,
          podiums: data.currentDriver.podiums,
          consistency: data.currentDriver.consistency,
        }
      : null;

    const mapRace = (raceSummary: DashboardOverviewResult['myUpcomingRaces'][number]): DashboardRaceSummaryDTO => ({
      id: raceSummary.race.id,
      leagueId: raceSummary.league?.id ? String(raceSummary.league.id) : null,
      leagueName: raceSummary.league?.name ? String(raceSummary.league.name) : null,
      track: String(raceSummary.race.track),
      car: String(raceSummary.race.car),
      scheduledAt: raceSummary.race.scheduledAt.toISOString(),
      status: raceSummary.race.status.toString(),
      isMyLeague: raceSummary.isMyLeague,
    });

    const myUpcomingRaces: DashboardRaceSummaryDTO[] = data.myUpcomingRaces.map(mapRace);
    const otherUpcomingRaces: DashboardRaceSummaryDTO[] = data.otherUpcomingRaces.map(mapRace);
    const upcomingRaces: DashboardRaceSummaryDTO[] = data.upcomingRaces.map(mapRace);

    const nextRace: DashboardRaceSummaryDTO | null = data.nextRace ? mapRace(data.nextRace) : null;

    const recentResults: DashboardRecentResultDTO[] = data.recentResults.map(resultSummary => ({
      raceId: resultSummary.race.id,
      raceName: String(resultSummary.race.track),
      leagueId: resultSummary.league?.id ? String(resultSummary.league.id) : null,
      leagueName: resultSummary.league?.name ? String(resultSummary.league.name) : null,
      finishedAt: resultSummary.race.scheduledAt.toISOString(),
      position: Number(resultSummary.result.position),
      incidents: Number(resultSummary.result.incidents),
    }));

    const leagueStandingsSummaries: DashboardLeagueStandingSummaryDTO[] =
      data.leagueStandingsSummaries.map(standing => ({
        leagueId: String(standing.league.id),
        leagueName: String(standing.league.name),
        position: standing.standing?.position ? Number(standing.standing.position) : null,
        totalDrivers: standing.totalDrivers,
        points: standing.standing?.points ? Number(standing.standing.points) : null,
      }));

    const feedItems: DashboardFeedItemSummaryDTO[] = data.feedSummary.items.map(item => ({
      id: item.id,
      type: String(item.type),
      headline: item.headline,
      body: item.body ?? '',
      timestamp: item.timestamp.toISOString(),
      ctaLabel: item.ctaLabel ?? '',
      ctaHref: item.ctaHref ?? '',
    }));

    const feedSummary: DashboardFeedSummaryDTO = {
      notificationCount: data.feedSummary.notificationCount,
      items: feedItems,
    };

    const friends: DashboardFriendSummaryDTO[] = data.friends.map(friend => ({
      id: friend.driver.id,
      name: String(friend.driver.name),
      country: String(friend.driver.country),
      avatarUrl: friend.avatarUrl,
    }));

    this.responseModel = {
      currentDriver,
      myUpcomingRaces,
      otherUpcomingRaces,
      upcomingRaces,
      activeLeaguesCount: data.activeLeaguesCount,
      nextRace,
      recentResults,
      leagueStandingsSummaries,
      feedSummary,
      friends,
    };
  }

  getResponseModel(): DashboardOverviewDTO {
    if (!this.responseModel) throw new Error('Presenter not presented');
    return this.responseModel;
  }
}
