import { describe, it, expect } from 'vitest';
import { LeagueDetailViewModel, LeagueViewModel, DriverViewModel, RaceViewModel } from './LeagueDetailViewModel';

describe('LeagueDetailViewModel', () => {
  const baseLeague = {
    id: 'league-1',
    name: 'Pro Series',
    game: 'iRacing',
    tier: 'premium' as const,
    season: '2025 Season 1',
    description: 'High level competition',
    drivers: 24,
    races: 10,
    completedRaces: 4,
    totalImpressions: 100_000,
    avgViewsPerRace: 10_000,
    engagement: 3.5,
    rating: 4.7,
    seasonStatus: 'active' as const,
    seasonDates: { start: '2025-01-01', end: '2025-04-01' },
    nextRace: { name: 'Round 5', date: '2025-02-01' },
    sponsorSlots: {
      main: { available: true, price: 5_000, benefits: ['Branding', 'Mentions'] },
      secondary: { available: 2, total: 3, price: 2_000, benefits: ['Branding'] },
    },
  };

  const drivers = [
    { id: 'd1', name: 'Alice', country: 'US', position: 1, races: 4, impressions: 30_000, team: 'Alpha' },
    { id: 'd2', name: 'Bob', country: 'DE', position: 2, races: 4, impressions: 25_000, team: 'Beta' },
  ];

  const races = [
    { id: 'r1', name: 'Round 1', date: '2025-01-01', views: 12_000, status: 'completed' as const },
    { id: 'r2', name: 'Round 2', date: '2025-01-08', views: 11_000, status: 'upcoming' as const },
  ];

  it('maps nested league, drivers and races into view models', () => {
    const vm = new LeagueDetailViewModel({ league: baseLeague, drivers, races });

    expect(vm.league).toBeInstanceOf(LeagueViewModel);
    expect(vm.drivers).toHaveLength(2);
    expect(vm.drivers[0]).toBeInstanceOf(DriverViewModel);
    expect(vm.races).toHaveLength(2);
    expect(vm.races[0]).toBeInstanceOf(RaceViewModel);
  });

  it('keeps core league metrics available on LeagueViewModel', () => {
    const vm = new LeagueDetailViewModel({ league: baseLeague, drivers, races });

    expect(vm.league.id).toBe('league-1');
    expect(vm.league.drivers).toBe(24);
    expect(vm.league.races).toBe(10);
    expect(vm.league.completedRaces).toBe(4);
    expect(vm.league.totalImpressions).toBe(100_000);
    expect(vm.league.avgViewsPerRace).toBe(10_000);
  });

  it('exposes formatted impression and views statistics', () => {
    const vm = new LeagueDetailViewModel({ league: baseLeague, drivers, races });

    expect(vm.league.formattedTotalImpressions).toBe(baseLeague.totalImpressions.toLocaleString());
    expect(vm.league.formattedAvgViewsPerRace).toBe(baseLeague.avgViewsPerRace.toLocaleString());
    expect(vm.league.projectedTotalViews).toBe(baseLeague.avgViewsPerRace * baseLeague.races);
    expect(vm.league.formattedProjectedTotal).toBe(vm.league.projectedTotalViews.toLocaleString());
  });

  it('calculates CPM for main sponsor from projected total views', () => {
    const vm = new LeagueDetailViewModel({ league: baseLeague, drivers, races });

    const expectedCpm = Math.round((baseLeague.sponsorSlots.main.price / vm.league.projectedTotalViews) * 1000);

    expect(vm.league.mainSponsorCpm).toBe(expectedCpm);
    expect(vm.league.formattedMainSponsorCpm).toBe(`$${expectedCpm.toFixed(2)}`);
  });

  it('derives races left and tier configuration', () => {
    const vm = new LeagueDetailViewModel({ league: baseLeague, drivers, races });

    expect(vm.league.racesLeft).toBe(baseLeague.races - baseLeague.completedRaces);
    const tierConfig = vm.league.tierConfig;
    expect(tierConfig.color).toBeDefined();
    expect(tierConfig.bgColor).toBeDefined();
    expect(tierConfig.border).toBeDefined();
  });

  it('formats driver impressions and race date/views', () => {
    const vm = new LeagueDetailViewModel({ league: baseLeague, drivers, races });

    expect(vm.drivers[0].formattedImpressions).toBe(drivers[0].impressions.toLocaleString());
    // formattedDate uses a short, locale-specific date string like "Jan 1"
    const formattedDate = vm.races[0].formattedDate;
    expect(typeof formattedDate).toBe('string');
    expect(formattedDate.length).toBeGreaterThan(0);
    expect(vm.races[0].formattedViews).toBe(races[0].views.toLocaleString());
  });
});
