import { describe, it, expect, vi, Mocked } from 'vitest';
import { LandingService } from './LandingService';
import { RacesApiClient } from '../../api/races/RacesApiClient';
import { LeaguesApiClient } from '../../api/leagues/LeaguesApiClient';
import { TeamsApiClient } from '../../api/teams/TeamsApiClient';
import { HomeDiscoveryViewModel } from '@/lib/view-models/HomeDiscoveryViewModel';

describe('LandingService', () => {
  let mockRacesApi: Mocked<RacesApiClient>;
  let mockLeaguesApi: Mocked<LeaguesApiClient>;
  let mockTeamsApi: Mocked<TeamsApiClient>;
  let service: LandingService;

  beforeEach(() => {
    mockRacesApi = {
      getPageData: vi.fn(),
    } as unknown as Mocked<RacesApiClient>;

    mockLeaguesApi = {
      getAllWithCapacity: vi.fn(),
    } as unknown as Mocked<LeaguesApiClient>;

    mockTeamsApi = {
      getAll: vi.fn(),
    } as unknown as Mocked<TeamsApiClient>;

    service = new LandingService(mockRacesApi, mockLeaguesApi, mockTeamsApi);
  });

  describe('getHomeDiscovery', () => {
    it('should return home discovery data with top leagues, teams, and upcoming races', async () => {
      const racesDto = {
        races: [
          {
            id: 'race-1',
            track: 'Monza',
            car: 'Ferrari',
            scheduledAt: '2023-10-01T10:00:00Z',
            status: 'upcoming',
            leagueId: 'league-1',
            leagueName: 'Test League',
            strengthOfField: 1500,
            isUpcoming: true,
            isLive: false,
            isPast: false,
          },
          {
            id: 'race-2',
            track: 'Silverstone',
            car: 'Mercedes',
            scheduledAt: '2023-10-02T10:00:00Z',
            status: 'upcoming',
            leagueId: 'league-1',
            leagueName: 'Test League',
            strengthOfField: 1600,
            isUpcoming: true,
            isLive: false,
            isPast: false,
          },
        ],
      };

      const leaguesDto = {
        leagues: [
          { id: 'league-1', name: 'League One' },
          { id: 'league-2', name: 'League Two' },
          { id: 'league-3', name: 'League Three' },
          { id: 'league-4', name: 'League Four' },
          { id: 'league-5', name: 'League Five' },
        ],
      };

      const teamsDto = {
        teams: [
          { id: 'team-1', name: 'Team One', tag: 'T1', description: 'Best team' },
          { id: 'team-2', name: 'Team Two', tag: 'T2', description: 'Great team' },
          { id: 'team-3', name: 'Team Three', tag: 'T3', description: 'Awesome team' },
          { id: 'team-4', name: 'Team Four', tag: 'T4', description: 'Cool team' },
          { id: 'team-5', name: 'Team Five', tag: 'T5', description: 'Pro team' },
        ],
      };

      mockRacesApi.getPageData.mockResolvedValue(racesDto as any);
      mockLeaguesApi.getAllWithCapacity.mockResolvedValue(leaguesDto as any);
      mockTeamsApi.getAll.mockResolvedValue(teamsDto as any);

      const result = await service.getHomeDiscovery();

      expect(result).toBeInstanceOf(HomeDiscoveryViewModel);
      expect(result.topLeagues).toHaveLength(4); // First 4 leagues
      expect(result.teams).toHaveLength(4); // First 4 teams
      expect(result.upcomingRaces).toHaveLength(2); // All upcoming races (first 4)
    });

    it('should handle empty data', async () => {
      mockRacesApi.getPageData.mockResolvedValue({ races: [] } as any);
      mockLeaguesApi.getAllWithCapacity.mockResolvedValue({ leagues: [] } as any);
      mockTeamsApi.getAll.mockResolvedValue({ teams: [] } as any);

      const result = await service.getHomeDiscovery();

      expect(result.topLeagues).toHaveLength(0);
      expect(result.teams).toHaveLength(0);
      expect(result.upcomingRaces).toHaveLength(0);
    });

    it('should throw error when any API call fails', async () => {
      mockRacesApi.getPageData.mockRejectedValue(new Error('Races API failed'));

      await expect(service.getHomeDiscovery()).rejects.toThrow('Races API failed');
    });
  });
});