import { describe, it, expect } from 'vitest';
import { RacesPageViewModel } from './RacesPageViewModel';
import { RaceListItemViewModel } from './RaceListItemViewModel';

describe('RaceListItemViewModel', () => {
  const baseDto = {
    id: 'race-123',
    track: 'Spa-Francorchamps',
    car: 'GT3',
    scheduledAt: '2025-01-01T20:00:00Z',
    status: 'scheduled',
    leagueId: 'league-1',
    leagueName: 'Test League',
    strengthOfField: 2500,
    isUpcoming: true,
    isLive: false,
    isPast: false,
  };

  it('maps DTO fields to properties', () => {
    const viewModel = new RaceListItemViewModel(baseDto);

    expect(viewModel.id).toBe('race-123');
    expect(viewModel.track).toBe('Spa-Francorchamps');
    expect(viewModel.car).toBe('GT3');
    expect(viewModel.scheduledAt).toBe('2025-01-01T20:00:00Z');
    expect(viewModel.status).toBe('scheduled');
    expect(viewModel.leagueId).toBe('league-1');
    expect(viewModel.leagueName).toBe('Test League');
    expect(viewModel.strengthOfField).toBe(2500);
    expect(viewModel.isUpcoming).toBe(true);
    expect(viewModel.isLive).toBe(false);
    expect(viewModel.isPast).toBe(false);
  });

  it('formats scheduled time as locale string', () => {
    const viewModel = new RaceListItemViewModel(baseDto);

    const formatted = viewModel.formattedScheduledTime;

    expect(formatted).toContain('2025');
  });

  it('computes status badge variants', () => {
    const scheduled = new RaceListItemViewModel({ ...baseDto, status: 'scheduled' });
    const running = new RaceListItemViewModel({ ...baseDto, status: 'running' });
    const completed = new RaceListItemViewModel({ ...baseDto, status: 'completed' });
    const cancelled = new RaceListItemViewModel({ ...baseDto, status: 'cancelled' });
    const other = new RaceListItemViewModel({ ...baseDto, status: 'unknown' });

    expect(scheduled.statusBadgeVariant).toBe('info');
    expect(running.statusBadgeVariant).toBe('success');
    expect(completed.statusBadgeVariant).toBe('secondary');
    expect(cancelled.statusBadgeVariant).toBe('danger');
    expect(other.statusBadgeVariant).toBe('default');
  });
});

describe('RacesPageViewModel', () => {
  const createDto = () => ({
    races: [
      {
        id: 'race-1',
        track: 'Spa',
        car: 'GT3',
        scheduledAt: '2025-01-01T20:00:00Z',
        status: 'scheduled',
        leagueId: 'league-1',
        leagueName: 'League 1',
        strengthOfField: 2500,
        isUpcoming: true,
        isLive: false,
        isPast: false,
      },
      {
        id: 'race-2',
        track: 'Nürburgring',
        car: 'GT4',
        scheduledAt: '2025-01-02T20:00:00Z',
        status: 'running',
        leagueId: 'league-2',
        leagueName: 'League 2',
        strengthOfField: null,
        isUpcoming: true,
        isLive: true,
        isPast: false,
      },
      {
        id: 'race-3',
        track: 'Daytona',
        car: 'LMP2',
        scheduledAt: '2024-12-31T20:00:00Z',
        status: 'completed',
        leagueId: 'league-3',
        leagueName: 'League 3',
        strengthOfField: 2000,
        isUpcoming: false,
        isLive: false,
        isPast: true,
      },
    ],
  });

  it('wraps races DTOs in RaceListItemViewModel instances', () => {
    const viewModel = new RacesPageViewModel(createDto());

    expect(viewModel.races).toHaveLength(3);
    expect(viewModel.races[0]).toBeInstanceOf(RaceListItemViewModel);
  });

  it('computes total count from races length', () => {
    const viewModel = new RacesPageViewModel(createDto());

    expect(viewModel.totalCount).toBe(3);
  });

  it('filters upcoming, live and past races', () => {
    const viewModel = new RacesPageViewModel(createDto());

    expect(viewModel.upcomingRaces).toHaveLength(2);
    expect(viewModel.liveRaces).toHaveLength(1);
    expect(viewModel.pastRaces).toHaveLength(1);
  });

  it('filters scheduled, running and completed races by status', () => {
    const viewModel = new RacesPageViewModel(createDto());

    expect(viewModel.scheduledRaces).toHaveLength(1);
    expect(viewModel.runningRaces).toHaveLength(1);
    expect(viewModel.completedRaces).toHaveLength(1);
  });
});