import type { DashboardOverviewResult } from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import { Driver } from '@core/racing/domain/entities/Driver';
import { League } from '@core/racing/domain/entities/League';
import { Race } from '@core/racing/domain/entities/Race';
import { Standing } from '@core/racing/domain/entities/Standing';
import { Result as RaceResult } from '@core/racing/domain/entities/result/Result';
import type { FeedItem } from '@core/social/domain/types/FeedItem';
import { beforeEach, describe, expect, it } from 'vitest';
import { DashboardOverviewPresenter } from './DashboardOverviewPresenter';

const createOutput = (): DashboardOverviewResult => {
  const driver = Driver.create({ id: 'driver-1', iracingId: '12345', name: 'Test Driver', country: 'DE' });
  const league1 = League.create({ id: 'league-1', name: 'League 1', description: 'First league', ownerId: 'owner-1' });
  const league2 = League.create({ id: 'league-2', name: 'League 2', description: 'Second league', ownerId: 'owner-2' });
  const league3 = League.create({ id: 'league-3', name: 'League 3', description: 'Third league', ownerId: 'owner-3' });

  const race1 = Race.create({
    id: 'race-1',
    leagueId: 'league-1',
    track: 'Spa',
    car: 'GT3',
    scheduledAt: new Date('2025-01-01T10:00:00Z'),
    status: 'scheduled',
  });
  const race2 = Race.create({
    id: 'race-2',
    leagueId: 'league-2',
    track: 'Monza',
    car: 'GT3',
    scheduledAt: new Date('2025-01-02T10:00:00Z'),
    status: 'scheduled',
  });
  const race3 = Race.create({
    id: 'race-3',
    leagueId: 'league-3',
    track: 'Nürburgring',
    car: 'GT3',
    scheduledAt: new Date('2024-12-01T10:00:00Z'),
    status: 'completed',
  });

  const standing1 = Standing.create({ leagueId: 'league-1', driverId: 'driver-1', position: 1, points: 150 });

  const result1 = RaceResult.create({
    id: 'result-1',
    raceId: 'race-3',
    driverId: 'driver-1',
    position: 1,
    fastestLap: 120,
    incidents: 0,
    startPosition: 1,
  });

  const feedItem: FeedItem = {
    id: 'feed-1',
    type: 'friend-joined-league',
    headline: 'You won a race',
    body: 'Congrats!',
    timestamp: new Date('2024-12-02T10:00:00Z'),
    ctaLabel: 'View',
    ctaHref: '/races/race-3',
  };

  const friend = Driver.create({ id: 'friend-1', iracingId: '67890', name: 'Friend One', country: 'US' });

  return {
    currentDriver: {
      driver,
      avatarUrl: 'https://example.com/avatar.jpg',
      rating: 2500,
      globalRank: 42,
      totalRaces: 10,
      wins: 3,
      podiums: 5,
      consistency: 90,
    },
    myUpcomingRaces: [
      {
        race: race1,
        league: league1,
        isMyLeague: true,
      },
    ],
    otherUpcomingRaces: [
      {
        race: race2,
        league: league2,
        isMyLeague: false,
      },
    ],
    upcomingRaces: [
      {
        race: race1,
        league: league1,
        isMyLeague: true,
      },
      {
        race: race2,
        league: league2,
        isMyLeague: false,
      },
    ],
    activeLeaguesCount: 2,
    nextRace: {
      race: race1,
      league: league1,
      isMyLeague: true,
    },
    recentResults: [
      {
        race: race3,
        league: league3,
        result: result1,
      },
    ],
    leagueStandingsSummaries: [
      {
        league: league1,
        standing: standing1,
        totalDrivers: 20,
      },
    ],
    feedSummary: {
      notificationCount: 3,
      items: [feedItem],
    },
    friends: [
      {
        driver: friend,
        avatarUrl: 'https://example.com/friend.jpg',
      },
    ],
  };
};

describe('DashboardOverviewPresenter', () => {
  let presenter: DashboardOverviewPresenter;

  beforeEach(() => {
    presenter = new DashboardOverviewPresenter();
  });

  it('maps DashboardOverviewResult to DashboardOverviewDTO correctly', () => {
    const output = createOutput();

    presenter.present(output);
    const dto = presenter.getResponseModel();

    expect(dto.activeLeaguesCount).toBe(2);
    expect(dto.currentDriver?.id).toBe('driver-1');
    expect(dto.myUpcomingRaces[0]!.id).toBe('race-1');
    expect(dto.otherUpcomingRaces[0]!.id).toBe('race-2');
    expect(dto.upcomingRaces).toHaveLength(2);
    expect(dto.nextRace?.id).toBe('race-1');
    expect(dto.recentResults[0]!.raceId).toBe('race-3');
    expect(dto.leagueStandingsSummaries[0]!.leagueId).toBe('league-1');
    expect(dto.feedSummary.notificationCount).toBe(3);
    expect(dto.feedSummary.items[0]!.id).toBe('feed-1');
    expect(dto.friends[0]!.id).toBe('friend-1');
  });

});