/**
 * Integration Test: Driver Rankings Use Case Orchestration
 *
 * Tests the orchestration logic of driver rankings-related Use Cases:
 * - GetDriverRankingsUseCase: Retrieves comprehensive list of all drivers with search, filter, and sort capabilities
 * - Validates that Use Cases correctly interact with their Ports (Repositories, Event Publishers)
 * - Uses In-Memory adapters for fast, deterministic testing
 *
 * Focus: Business logic orchestration, NOT UI rendering
 */

import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
import { InMemoryLeaderboardsRepository } from '../../../adapters/leaderboards/persistence/inmemory/InMemoryLeaderboardsRepository';
import { InMemoryLeaderboardsEventPublisher } from '../../../adapters/leaderboards/events/InMemoryLeaderboardsEventPublisher';
import { GetDriverRankingsUseCase } from '../../../core/leaderboards/application/use-cases/GetDriverRankingsUseCase';
import { ValidationError } from '../../../core/shared/errors/ValidationError';

describe('Driver Rankings Use Case Orchestration', () => {
  let leaderboardsRepository: InMemoryLeaderboardsRepository;
  let eventPublisher: InMemoryLeaderboardsEventPublisher;
  let getDriverRankingsUseCase: GetDriverRankingsUseCase;

  beforeAll(() => {
    leaderboardsRepository = new InMemoryLeaderboardsRepository();
    eventPublisher = new InMemoryLeaderboardsEventPublisher();
    getDriverRankingsUseCase = new GetDriverRankingsUseCase({
      leaderboardsRepository,
      eventPublisher,
    });
  });

  beforeEach(() => {
    leaderboardsRepository.clear();
    eventPublisher.clear();
  });

  describe('GetDriverRankingsUseCase - Success Path', () => {
    it('should retrieve all drivers with complete data', async () => {
      // Scenario: System has multiple drivers with complete data
      // Given: Multiple drivers exist with various ratings, names, and team affiliations
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Racing Team A',
        raceCount: 50,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Jane Doe',
        rating: 4.8,
        teamId: 'team-2',
        teamName: 'Speed Squad',
        raceCount: 45,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Bob Johnson',
        rating: 4.5,
        teamId: 'team-1',
        teamName: 'Racing Team A',
        raceCount: 40,
      });

      // When: GetDriverRankingsUseCase.execute() is called with default query
      const result = await getDriverRankingsUseCase.execute({});

      // Then: The result should contain all drivers
      expect(result.drivers).toHaveLength(3);

      // And: Each driver entry should include rank, name, rating, team affiliation, and race count
      expect(result.drivers[0]).toMatchObject({
        rank: 1,
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Racing Team A',
        raceCount: 50,
      });

      // And: Drivers should be sorted by rating (highest first)
      expect(result.drivers[0].rating).toBe(5.0);
      expect(result.drivers[1].rating).toBe(4.8);
      expect(result.drivers[2].rating).toBe(4.5);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should retrieve drivers with pagination', async () => {
      // Scenario: System has many drivers requiring pagination
      // Given: More than 20 drivers exist
      for (let i = 1; i <= 25; i++) {
        leaderboardsRepository.addDriver({
          id: `driver-${i}`,
          name: `Driver ${i}`,
          rating: 5.0 - i * 0.1,
          raceCount: 10 + i,
        });
      }

      // When: GetDriverRankingsUseCase.execute() is called with page=1, limit=20
      const result = await getDriverRankingsUseCase.execute({ page: 1, limit: 20 });

      // Then: The result should contain 20 drivers
      expect(result.drivers).toHaveLength(20);

      // And: The result should include pagination metadata (total, page, limit)
      expect(result.pagination.total).toBe(25);
      expect(result.pagination.page).toBe(1);
      expect(result.pagination.limit).toBe(20);
      expect(result.pagination.totalPages).toBe(2);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should retrieve drivers with different page sizes', async () => {
      // Scenario: User requests different page sizes
      // Given: More than 50 drivers exist
      for (let i = 1; i <= 60; i++) {
        leaderboardsRepository.addDriver({
          id: `driver-${i}`,
          name: `Driver ${i}`,
          rating: 5.0 - i * 0.1,
          raceCount: 10 + i,
        });
      }

      // When: GetDriverRankingsUseCase.execute() is called with limit=50
      const result = await getDriverRankingsUseCase.execute({ limit: 50 });

      // Then: The result should contain 50 drivers
      expect(result.drivers).toHaveLength(50);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should retrieve drivers with consistent ranking order', async () => {
      // Scenario: Verify ranking consistency
      // Given: Multiple drivers exist with various ratings
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 5.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.8,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Driver C',
        rating: 4.5,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called
      const result = await getDriverRankingsUseCase.execute({});

      // Then: Driver ranks should be sequential (1, 2, 3...)
      expect(result.drivers[0].rank).toBe(1);
      expect(result.drivers[1].rank).toBe(2);
      expect(result.drivers[2].rank).toBe(3);

      // And: No duplicate ranks should appear
      const ranks = result.drivers.map((d) => d.rank);
      expect(new Set(ranks).size).toBe(ranks.length);

      // And: All ranks should be sequential
      for (let i = 0; i < ranks.length; i++) {
        expect(ranks[i]).toBe(i + 1);
      }

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should retrieve drivers with accurate data', async () => {
      // Scenario: Verify data accuracy
      // Given: Drivers exist with valid ratings, names, and team affiliations
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Racing Team A',
        raceCount: 50,
      });

      // When: GetDriverRankingsUseCase.execute() is called
      const result = await getDriverRankingsUseCase.execute({});

      // Then: All driver ratings should be valid numbers
      expect(result.drivers[0].rating).toBeGreaterThan(0);
      expect(typeof result.drivers[0].rating).toBe('number');

      // And: All driver ranks should be sequential
      expect(result.drivers[0].rank).toBe(1);

      // And: All driver names should be non-empty strings
      expect(result.drivers[0].name).toBeTruthy();
      expect(typeof result.drivers[0].name).toBe('string');

      // And: All team affiliations should be valid
      expect(result.drivers[0].teamId).toBe('team-1');
      expect(result.drivers[0].teamName).toBe('Racing Team A');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });
  });

  describe('GetDriverRankingsUseCase - Search Functionality', () => {
    it('should search for drivers by name', async () => {
      // Scenario: User searches for a specific driver
      // Given: Drivers exist with names: "John Smith", "Jane Doe", "Bob Johnson"
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Jane Doe',
        rating: 4.8,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Bob Johnson',
        rating: 4.5,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with search="John"
      const result = await getDriverRankingsUseCase.execute({ search: 'John' });

      // Then: The result should contain drivers whose names contain "John"
      expect(result.drivers).toHaveLength(2);
      expect(result.drivers.map((d) => d.name)).toContain('John Smith');
      expect(result.drivers.map((d) => d.name)).toContain('Bob Johnson');

      // And: The result should not contain drivers whose names do not contain "John"
      expect(result.drivers.map((d) => d.name)).not.toContain('Jane Doe');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should search for drivers by partial name', async () => {
      // Scenario: User searches with partial name
      // Given: Drivers exist with names: "Alexander", "Alex", "Alexandra"
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Alexander',
        rating: 5.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Alex',
        rating: 4.8,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Alexandra',
        rating: 4.5,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with search="Alex"
      const result = await getDriverRankingsUseCase.execute({ search: 'Alex' });

      // Then: The result should contain all drivers whose names start with "Alex"
      expect(result.drivers).toHaveLength(3);
      expect(result.drivers.map((d) => d.name)).toContain('Alexander');
      expect(result.drivers.map((d) => d.name)).toContain('Alex');
      expect(result.drivers.map((d) => d.name)).toContain('Alexandra');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should handle case-insensitive search', async () => {
      // Scenario: Search is case-insensitive
      // Given: Drivers exist with names: "John Smith", "JOHN DOE", "johnson"
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'JOHN DOE',
        rating: 4.8,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'johnson',
        rating: 4.5,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with search="john"
      const result = await getDriverRankingsUseCase.execute({ search: 'john' });

      // Then: The result should contain all drivers whose names contain "john" (case-insensitive)
      expect(result.drivers).toHaveLength(3);
      expect(result.drivers.map((d) => d.name)).toContain('John Smith');
      expect(result.drivers.map((d) => d.name)).toContain('JOHN DOE');
      expect(result.drivers.map((d) => d.name)).toContain('johnson');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should return empty result when no drivers match search', async () => {
      // Scenario: Search returns no results
      // Given: Drivers exist
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with search="NonExistentDriver"
      const result = await getDriverRankingsUseCase.execute({ search: 'NonExistentDriver' });

      // Then: The result should contain empty drivers list
      expect(result.drivers).toHaveLength(0);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });
  });

  describe('GetDriverRankingsUseCase - Filter Functionality', () => {
    it('should filter drivers by rating range', async () => {
      // Scenario: User filters drivers by rating
      // Given: Drivers exist with ratings: 3.5, 4.0, 4.5, 5.0
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 3.5,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Driver C',
        rating: 4.5,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-4',
        name: 'Driver D',
        rating: 5.0,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with minRating=4.0
      const result = await getDriverRankingsUseCase.execute({ minRating: 4.0 });

      // Then: The result should only contain drivers with rating >= 4.0
      expect(result.drivers).toHaveLength(3);
      expect(result.drivers.every((d) => d.rating >= 4.0)).toBe(true);

      // And: Drivers with rating < 4.0 should not be visible
      expect(result.drivers.map((d) => d.name)).not.toContain('Driver A');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should filter drivers by team', async () => {
      // Scenario: User filters drivers by team
      // Given: Drivers exist with various team affiliations
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.8,
        teamId: 'team-2',
        teamName: 'Team 2',
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Driver C',
        rating: 4.5,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with teamId="team-1"
      const result = await getDriverRankingsUseCase.execute({ teamId: 'team-1' });

      // Then: The result should only contain drivers from that team
      expect(result.drivers).toHaveLength(2);
      expect(result.drivers.every((d) => d.teamId === 'team-1')).toBe(true);

      // And: Drivers from other teams should not be visible
      expect(result.drivers.map((d) => d.name)).not.toContain('Driver B');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should filter drivers by multiple criteria', async () => {
      // Scenario: User applies multiple filters
      // Given: Drivers exist with various ratings and team affiliations
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.8,
        teamId: 'team-2',
        teamName: 'Team 2',
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Driver C',
        rating: 4.5,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-4',
        name: 'Driver D',
        rating: 3.5,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with minRating=4.0 and teamId="team-1"
      const result = await getDriverRankingsUseCase.execute({ minRating: 4.0, teamId: 'team-1' });

      // Then: The result should only contain drivers from that team with rating >= 4.0
      expect(result.drivers).toHaveLength(2);
      expect(result.drivers.every((d) => d.teamId === 'team-1' && d.rating >= 4.0)).toBe(true);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should handle empty filter results', async () => {
      // Scenario: Filters return no results
      // Given: Drivers exist
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 3.5,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with minRating=10.0 (impossible)
      const result = await getDriverRankingsUseCase.execute({ minRating: 10.0 });

      // Then: The result should contain empty drivers list
      expect(result.drivers).toHaveLength(0);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });
  });

  describe('GetDriverRankingsUseCase - Sort Functionality', () => {
    it('should sort drivers by rating (high to low)', async () => {
      // Scenario: User sorts drivers by rating
      // Given: Drivers exist with ratings: 3.5, 4.0, 4.5, 5.0
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 3.5,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Driver C',
        rating: 4.5,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-4',
        name: 'Driver D',
        rating: 5.0,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with sortBy="rating", sortOrder="desc"
      const result = await getDriverRankingsUseCase.execute({ sortBy: 'rating', sortOrder: 'desc' });

      // Then: The result should be sorted by rating in descending order
      expect(result.drivers[0].rating).toBe(5.0);
      expect(result.drivers[1].rating).toBe(4.5);
      expect(result.drivers[2].rating).toBe(4.0);
      expect(result.drivers[3].rating).toBe(3.5);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should sort drivers by name (A-Z)', async () => {
      // Scenario: User sorts drivers by name
      // Given: Drivers exist with names: "Zoe", "Alice", "Bob"
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Zoe',
        rating: 5.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Alice',
        rating: 4.8,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Bob',
        rating: 4.5,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with sortBy="name", sortOrder="asc"
      const result = await getDriverRankingsUseCase.execute({ sortBy: 'name', sortOrder: 'asc' });

      // Then: The result should be sorted alphabetically by name
      expect(result.drivers[0].name).toBe('Alice');
      expect(result.drivers[1].name).toBe('Bob');
      expect(result.drivers[2].name).toBe('Zoe');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should sort drivers by rank (low to high)', async () => {
      // Scenario: User sorts drivers by rank
      // Given: Drivers exist with various ranks
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 5.0,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.8,
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Driver C',
        rating: 4.5,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called with sortBy="rank", sortOrder="asc"
      const result = await getDriverRankingsUseCase.execute({ sortBy: 'rank', sortOrder: 'asc' });

      // Then: The result should be sorted by rank in ascending order
      expect(result.drivers[0].rank).toBe(1);
      expect(result.drivers[1].rank).toBe(2);
      expect(result.drivers[2].rank).toBe(3);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should sort drivers by race count (high to low)', async () => {
      // Scenario: User sorts drivers by race count
      // Given: Drivers exist with various race counts
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 5.0,
        raceCount: 50,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.8,
        raceCount: 30,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Driver C',
        rating: 4.5,
        raceCount: 40,
      });

      // When: GetDriverRankingsUseCase.execute() is called with sortBy="raceCount", sortOrder="desc"
      const result = await getDriverRankingsUseCase.execute({ sortBy: 'raceCount', sortOrder: 'desc' });

      // Then: The result should be sorted by race count in descending order
      expect(result.drivers[0].raceCount).toBe(50);
      expect(result.drivers[1].raceCount).toBe(40);
      expect(result.drivers[2].raceCount).toBe(30);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });
  });

  describe('GetDriverRankingsUseCase - Edge Cases', () => {
    it('should handle system with no drivers', async () => {
      // Scenario: System has no drivers
      // Given: No drivers exist in the system
      // When: GetDriverRankingsUseCase.execute() is called
      const result = await getDriverRankingsUseCase.execute({});

      // Then: The result should contain empty drivers list
      expect(result.drivers).toHaveLength(0);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should handle drivers with same rating', async () => {
      // Scenario: Multiple drivers with identical ratings
      // Given: Multiple drivers exist with the same rating
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Zoe',
        rating: 5.0,
        raceCount: 50,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Alice',
        rating: 5.0,
        raceCount: 45,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Bob',
        rating: 5.0,
        raceCount: 40,
      });

      // When: GetDriverRankingsUseCase.execute() is called
      const result = await getDriverRankingsUseCase.execute({});

      // Then: Drivers should be sorted by rating
      expect(result.drivers[0].rating).toBe(5.0);
      expect(result.drivers[1].rating).toBe(5.0);
      expect(result.drivers[2].rating).toBe(5.0);

      // And: Drivers with same rating should have consistent ordering (e.g., by name)
      expect(result.drivers[0].name).toBe('Alice');
      expect(result.drivers[1].name).toBe('Bob');
      expect(result.drivers[2].name).toBe('Zoe');

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should handle drivers with no team affiliation', async () => {
      // Scenario: Drivers without team affiliation
      // Given: Drivers exist with and without team affiliations
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'Driver A',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 10,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'Driver B',
        rating: 4.8,
        raceCount: 10,
      });

      // When: GetDriverRankingsUseCase.execute() is called
      const result = await getDriverRankingsUseCase.execute({});

      // Then: All drivers should be returned
      expect(result.drivers).toHaveLength(2);

      // And: Drivers without team should show empty or default team value
      expect(result.drivers[0].teamId).toBe('team-1');
      expect(result.drivers[0].teamName).toBe('Team 1');
      expect(result.drivers[1].teamId).toBeUndefined();
      expect(result.drivers[1].teamName).toBeUndefined();

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });

    it('should handle pagination with empty results', async () => {
      // Scenario: Pagination with no results
      // Given: No drivers exist
      // When: GetDriverRankingsUseCase.execute() is called with page=1, limit=20
      const result = await getDriverRankingsUseCase.execute({ page: 1, limit: 20 });

      // Then: The result should contain empty drivers list
      expect(result.drivers).toHaveLength(0);

      // And: Pagination metadata should show total=0
      expect(result.pagination.total).toBe(0);
      expect(result.pagination.page).toBe(1);
      expect(result.pagination.limit).toBe(20);
      expect(result.pagination.totalPages).toBe(0);

      // And: EventPublisher should emit DriverRankingsAccessedEvent
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(1);
    });
  });

  describe('GetDriverRankingsUseCase - Error Handling', () => {
    it('should handle driver repository errors gracefully', async () => {
      // Scenario: Driver repository throws error
      // Given: LeaderboardsRepository throws an error during query
      const originalFindAllDrivers = leaderboardsRepository.findAllDrivers.bind(leaderboardsRepository);
      leaderboardsRepository.findAllDrivers = async () => {
        throw new Error('Repository error');
      };

      // When: GetDriverRankingsUseCase.execute() is called
      try {
        await getDriverRankingsUseCase.execute({});
        // Should not reach here
        expect(true).toBe(false);
      } catch (error) {
        // Then: Should propagate the error appropriately
        expect(error).toBeInstanceOf(Error);
        expect((error as Error).message).toBe('Repository error');
      }

      // And: EventPublisher should NOT emit any events
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(0);

      // Restore original method
      leaderboardsRepository.findAllDrivers = originalFindAllDrivers;
    });

    it('should handle invalid query parameters', async () => {
      // Scenario: Invalid query parameters
      // Given: Invalid parameters (e.g., negative page, invalid sort field)
      // When: GetDriverRankingsUseCase.execute() is called with invalid parameters
      try {
        await getDriverRankingsUseCase.execute({ page: -1 });
        // Should not reach here
        expect(true).toBe(false);
      } catch (error) {
        // Then: Should throw ValidationError
        expect(error).toBeInstanceOf(ValidationError);
      }

      // And: EventPublisher should NOT emit any events
      expect(eventPublisher.getDriverRankingsAccessedEventCount()).toBe(0);
    });
  });

  describe('Driver Rankings Data Orchestration', () => {
    it('should correctly calculate driver rankings based on rating', async () => {
      // Scenario: Driver ranking calculation
      // Given: Drivers exist with ratings: 5.0, 4.8, 4.5, 4.2, 4.0
      const ratings = [5.0, 4.8, 4.5, 4.2, 4.0];
      ratings.forEach((rating, index) => {
        leaderboardsRepository.addDriver({
          id: `driver-${index}`,
          name: `Driver ${index}`,
          rating,
          raceCount: 10 + index,
        });
      });

      // When: GetDriverRankingsUseCase.execute() is called
      const result = await getDriverRankingsUseCase.execute({});

      // Then: Driver rankings should be:
      // - Rank 1: Driver with rating 5.0
      // - Rank 2: Driver with rating 4.8
      // - Rank 3: Driver with rating 4.5
      // - Rank 4: Driver with rating 4.2
      // - Rank 5: Driver with rating 4.0
      expect(result.drivers[0].rank).toBe(1);
      expect(result.drivers[0].rating).toBe(5.0);
      expect(result.drivers[1].rank).toBe(2);
      expect(result.drivers[1].rating).toBe(4.8);
      expect(result.drivers[2].rank).toBe(3);
      expect(result.drivers[2].rating).toBe(4.5);
      expect(result.drivers[3].rank).toBe(4);
      expect(result.drivers[3].rating).toBe(4.2);
      expect(result.drivers[4].rank).toBe(5);
      expect(result.drivers[4].rating).toBe(4.0);
    });

    it('should correctly format driver entries with team affiliation', async () => {
      // Scenario: Driver entry formatting
      // Given: A driver exists with team affiliation
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Racing Team A',
        raceCount: 50,
      });

      // When: GetDriverRankingsUseCase.execute() is called
      const result = await getDriverRankingsUseCase.execute({});

      // Then: Driver entry should include:
      // - Rank: Sequential number
      // - Name: Driver's full name
      // - Rating: Driver's rating (formatted)
      // - Team: Team name and logo (if available)
      // - Race Count: Number of races completed
      const driver = result.drivers[0];
      expect(driver.rank).toBe(1);
      expect(driver.name).toBe('John Smith');
      expect(driver.rating).toBe(5.0);
      expect(driver.teamId).toBe('team-1');
      expect(driver.teamName).toBe('Racing Team A');
      expect(driver.raceCount).toBe(50);
    });

    it('should correctly handle pagination metadata', async () => {
      // Scenario: Pagination metadata calculation
      // Given: 50 drivers exist
      for (let i = 1; i <= 50; i++) {
        leaderboardsRepository.addDriver({
          id: `driver-${i}`,
          name: `Driver ${i}`,
          rating: 5.0 - i * 0.1,
          raceCount: 10 + i,
        });
      }

      // When: GetDriverRankingsUseCase.execute() is called with page=2, limit=20
      const result = await getDriverRankingsUseCase.execute({ page: 2, limit: 20 });

      // Then: Pagination metadata should include:
      // - Total: 50
      // - Page: 2
      // - Limit: 20
      // - Total Pages: 3
      expect(result.pagination.total).toBe(50);
      expect(result.pagination.page).toBe(2);
      expect(result.pagination.limit).toBe(20);
      expect(result.pagination.totalPages).toBe(3);
    });

    it('should correctly apply search, filter, and sort together', async () => {
      // Scenario: Combined query operations
      // Given: Drivers exist with various names, ratings, and team affiliations
      leaderboardsRepository.addDriver({
        id: 'driver-1',
        name: 'John Smith',
        rating: 5.0,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 50,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-2',
        name: 'John Doe',
        rating: 4.8,
        teamId: 'team-2',
        teamName: 'Team 2',
        raceCount: 45,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-3',
        name: 'Jane Jenkins',
        rating: 4.5,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 40,
      });
      leaderboardsRepository.addDriver({
        id: 'driver-4',
        name: 'Bob Smith',
        rating: 3.5,
        teamId: 'team-1',
        teamName: 'Team 1',
        raceCount: 30,
      });

      // When: GetDriverRankingsUseCase.execute() is called with:
      // - search: "John"
      // - minRating: 4.0
      // - teamId: "team-1"
      // - sortBy: "rating"
      // - sortOrder: "desc"
      const result = await getDriverRankingsUseCase.execute({
        search: 'John',
        minRating: 4.0,
        teamId: 'team-1',
        sortBy: 'rating',
        sortOrder: 'desc',
      });

      // Then: The result should:
      // - Only contain drivers from team-1
      // - Only contain drivers with rating >= 4.0
      // - Only contain drivers whose names contain "John"
      // - Be sorted by rating in descending order
      expect(result.drivers).toHaveLength(1);
      expect(result.drivers[0].name).toBe('John Smith');
      expect(result.drivers[0].teamId).toBe('team-1');
      expect(result.drivers[0].rating).toBe(5.0);
    });
  });
});
