import { describe, it, expect } from 'vitest';
import { LeagueStewardingViewModel, type RaceWithProtests, type Protest, type Penalty } from './LeagueStewardingViewModel';

const createProtest = (id: string, status: string): Protest => ({
  id,
  protestingDriverId: `pd-${id}`,
  accusedDriverId: `ad-${id}`,
  incident: { lap: 1, description: 'Test incident' },
  filedAt: '2024-01-01T21:00:00Z',
  status,
});

const createPenalty = (id: string): Penalty => ({
  id,
  driverId: `d-${id}`,
  type: 'time',
  value: 5,
  reason: 'Test penalty',
});

const createRaceWithProtests = (id: string, pendingCount: number, resolvedCount: number, penaltiesCount: number): RaceWithProtests => ({
  race: {
    id,
    track: 'Spa-Francorchamps',
    scheduledAt: new Date('2024-01-01T20:00:00Z'),
  },
  pendingProtests: Array.from({ length: pendingCount }, (_, index) => createProtest(`${id}-pending-${index + 1}`, 'pending')),
  resolvedProtests: Array.from({ length: resolvedCount }, (_, index) => createProtest(`${id}-resolved-${index + 1}`, 'upheld')),
  penalties: Array.from({ length: penaltiesCount }, (_, index) => createPenalty(`${id}-pen-${index + 1}`)),
});

describe('LeagueStewardingViewModel', () => {
  it('aggregates totals across all races', () => {
    const races: RaceWithProtests[] = [
      createRaceWithProtests('race-1', 2, 1, 1),
      createRaceWithProtests('race-2', 1, 3, 2),
      createRaceWithProtests('race-3', 0, 0, 0),
    ];

    const driverMap = {
      d1: { id: 'd1', name: 'Driver 1' },
      d2: { id: 'd2', name: 'Driver 2' },
    };

    const viewModel = new LeagueStewardingViewModel(races, driverMap);

    expect(viewModel.totalPending).toBe(3);
    expect(viewModel.totalResolved).toBe(4);
    expect(viewModel.totalPenalties).toBe(3);
  });

  it('filters races into pending and history buckets', () => {
    const races: RaceWithProtests[] = [
      createRaceWithProtests('race-1', 2, 0, 0), // pending only
      createRaceWithProtests('race-2', 0, 3, 0), // history only (resolved)
      createRaceWithProtests('race-3', 0, 0, 2), // history only (penalties)
      createRaceWithProtests('race-4', 0, 0, 0), // no activity
    ];

    const viewModel = new LeagueStewardingViewModel(races, {});

    const pendingIds = viewModel.pendingRaces.map(r => r.race.id).sort();
    const historyIds = viewModel.historyRaces.map(r => r.race.id).sort();

    expect(pendingIds).toEqual(['race-1']);
    expect(historyIds).toEqual(['race-2', 'race-3']);
  });

  it('exposes all drivers as a flat array', () => {
    const races: RaceWithProtests[] = [createRaceWithProtests('race-1', 0, 0, 0)];

    const driverMap = {
      d1: { id: 'd1', name: 'Driver 1', avatarUrl: 'avatar-1.png' },
      d2: { id: 'd2', name: 'Driver 2', iracingId: 'ir-2' },
    };

    const viewModel = new LeagueStewardingViewModel(races, driverMap);

    expect(viewModel.allDrivers).toHaveLength(2);
    expect(viewModel.allDrivers).toEqual([
      driverMap.d1,
      driverMap.d2,
    ]);
  });

  it('handles an empty dataset gracefully', () => {
    const viewModel = new LeagueStewardingViewModel([], {});

    expect(viewModel.totalPending).toBe(0);
    expect(viewModel.totalResolved).toBe(0);
    expect(viewModel.totalPenalties).toBe(0);
    expect(viewModel.pendingRaces).toEqual([]);
    expect(viewModel.historyRaces).toEqual([]);
    expect(viewModel.allDrivers).toEqual([]);
  });
});
