/**
 * Integration Test: Profile Overview Use Case Orchestration
 *
 * Tests the orchestration logic of profile overview-related Use Cases:
 * - GetProfileOverviewUseCase: Retrieves driver's profile overview with stats, team memberships, and social summary
 * - UpdateDriverProfileUseCase: Updates driver's profile information
 * - 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 { InMemoryDriverRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryDriverRepository';
import { InMemoryTeamRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryTeamRepository';
import { InMemoryTeamMembershipRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryTeamMembershipRepository';
import { InMemorySocialGraphRepository } from '../../../adapters/social/persistence/inmemory/InMemorySocialAndFeed';
import { InMemoryDriverStatsRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryDriverStatsRepository';
import { InMemoryDriverExtendedProfileProvider } from '../../../adapters/racing/ports/InMemoryDriverExtendedProfileProvider';
import { InMemoryEventPublisher } from '../../../adapters/events/InMemoryEventPublisher';
import { InMemoryResultRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryResultRepository';
import { InMemoryStandingRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryStandingRepository';
import { InMemoryRaceRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryRaceRepository';
import { GetProfileOverviewUseCase } from '../../../core/racing/application/use-cases/GetProfileOverviewUseCase';
import { UpdateDriverProfileUseCase } from '../../../core/racing/application/use-cases/UpdateDriverProfileUseCase';
import { DriverStatsUseCase } from '../../../core/racing/application/use-cases/DriverStatsUseCase';
import { RankingUseCase } from '../../../core/racing/application/use-cases/RankingUseCase';
import { Driver } from '../../../core/racing/domain/entities/Driver';
import { Team } from '../../../core/racing/domain/entities/Team';
import { TeamMembership } from '../../../core/racing/domain/types/TeamMembership';
import { DriverStats } from '../../../core/racing/application/use-cases/DriverStatsUseCase';
import { DriverRanking } from '../../../core/racing/application/use-cases/RankingUseCase';
import { Logger } from '../../../core/shared/domain/Logger';

// Mock logger for testing
class MockLogger implements Logger {
  debug(message: string, ...args: any[]): void {}
  info(message: string, ...args: any[]): void {}
  warn(message: string, ...args: any[]): void {}
  error(message: string, ...args: any[]): void {}
}

describe('Profile Overview Use Case Orchestration', () => {
  let driverRepository: InMemoryDriverRepository;
  let teamRepository: InMemoryTeamRepository;
  let teamMembershipRepository: InMemoryTeamMembershipRepository;
  let socialRepository: InMemorySocialGraphRepository;
  let driverStatsRepository: InMemoryDriverStatsRepository;
  let driverExtendedProfileProvider: InMemoryDriverExtendedProfileProvider;
  let eventPublisher: InMemoryEventPublisher;
  let resultRepository: InMemoryResultRepository;
  let standingRepository: InMemoryStandingRepository;
  let raceRepository: InMemoryRaceRepository;
  let driverStatsUseCase: DriverStatsUseCase;
  let rankingUseCase: RankingUseCase;
  let getProfileOverviewUseCase: GetProfileOverviewUseCase;
  let updateDriverProfileUseCase: UpdateDriverProfileUseCase;
  let logger: MockLogger;

  beforeAll(() => {
    logger = new MockLogger();
    driverRepository = new InMemoryDriverRepository(logger);
    teamRepository = new InMemoryTeamRepository(logger);
    teamMembershipRepository = new InMemoryTeamMembershipRepository(logger);
    socialRepository = new InMemorySocialGraphRepository(logger);
    driverStatsRepository = new InMemoryDriverStatsRepository(logger);
    driverExtendedProfileProvider = new InMemoryDriverExtendedProfileProvider(logger);
    eventPublisher = new InMemoryEventPublisher();
    resultRepository = new InMemoryResultRepository(logger, raceRepository);
    standingRepository = new InMemoryStandingRepository(logger, {}, resultRepository, raceRepository);
    raceRepository = new InMemoryRaceRepository(logger);
    driverStatsUseCase = new DriverStatsUseCase(resultRepository, standingRepository, driverStatsRepository, logger);
    rankingUseCase = new RankingUseCase(standingRepository, driverRepository, driverStatsRepository, logger);
    getProfileOverviewUseCase = new GetProfileOverviewUseCase(
      driverRepository,
      teamRepository,
      teamMembershipRepository,
      socialRepository,
      driverExtendedProfileProvider,
      driverStatsUseCase,
      rankingUseCase
    );
    updateDriverProfileUseCase = new UpdateDriverProfileUseCase(driverRepository, logger);
  });

  beforeEach(async () => {
    await driverRepository.clear();
    await teamRepository.clear();
    await teamMembershipRepository.clear();
    await socialRepository.clear();
    await driverStatsRepository.clear();
    eventPublisher.clear();
  });

  describe('GetProfileOverviewUseCase - Success Path', () => {
    it('should retrieve complete profile overview for driver with all data', async () => {
      // Scenario: Driver with complete profile data
      // Given: A driver exists with complete personal information
      const driverId = 'driver-123';
      const driver = Driver.create({
        id: driverId,
        iracingId: '12345',
        name: 'John Doe',
        country: 'US',
        bio: 'Professional racing driver with 10 years experience',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has complete statistics
      const stats: DriverStats = {
        totalRaces: 50,
        wins: 15,
        podiums: 25,
        dnfs: 5,
        avgFinish: 8.5,
        bestFinish: 1,
        worstFinish: 20,
        finishRate: 90,
        winRate: 30,
        podiumRate: 50,
        percentile: 85,
        rating: 1850,
        consistency: 92,
        overallRank: 42,
      };
      await driverStatsRepository.saveDriverStats(driverId, stats);

      // And: The driver is a member of a team
      const team = Team.create({
        id: 'team-1',
        name: 'Racing Team',
        tag: 'RT',
        description: 'Professional racing team',
        ownerId: 'owner-1',
        isRecruiting: true,
      });
      await teamRepository.create(team);

      const membership: TeamMembership = {
        teamId: 'team-1',
        driverId: driverId,
        role: 'Driver',
        status: 'active',
        joinedAt: new Date('2024-01-01'),
      };
      await teamMembershipRepository.saveMembership(membership);

      // And: The driver has friends
      const friendDriver = Driver.create({
        id: 'friend-1',
        iracingId: '67890',
        name: 'Jane Smith',
        country: 'UK',
        avatarRef: undefined,
      });
      await driverRepository.create(friendDriver);
      await socialRepository.seed({
        drivers: [driver, friendDriver],
        friendships: [{ driverId: driverId, friendId: 'friend-1' }],
        feedEvents: [],
      });

      // When: GetProfileOverviewUseCase.execute() is called with driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should contain all profile sections
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();

      // And: Driver info should be complete
      expect(profile.driverInfo.driver.id).toBe(driverId);
      expect(profile.driverInfo.driver.name.toString()).toBe('John Doe');
      expect(profile.driverInfo.driver.country.toString()).toBe('US');
      expect(profile.driverInfo.driver.bio?.toString()).toBe('Professional racing driver with 10 years experience');
      expect(profile.driverInfo.totalDrivers).toBeGreaterThan(0);
      expect(profile.driverInfo.globalRank).toBe(42);
      expect(profile.driverInfo.consistency).toBe(92);
      expect(profile.driverInfo.rating).toBe(1850);

      // And: Stats should be complete
      expect(profile.stats).not.toBeNull();
      expect(profile.stats!.totalRaces).toBe(50);
      expect(profile.stats!.wins).toBe(15);
      expect(profile.stats!.podiums).toBe(25);
      expect(profile.stats!.dnfs).toBe(5);
      expect(profile.stats!.avgFinish).toBe(8.5);
      expect(profile.stats!.bestFinish).toBe(1);
      expect(profile.stats!.worstFinish).toBe(20);
      expect(profile.stats!.finishRate).toBe(90);
      expect(profile.stats!.winRate).toBe(30);
      expect(profile.stats!.podiumRate).toBe(50);
      expect(profile.stats!.percentile).toBe(85);
      expect(profile.stats!.rating).toBe(1850);
      expect(profile.stats!.consistency).toBe(92);
      expect(profile.stats!.overallRank).toBe(42);

      // And: Finish distribution should be calculated
      expect(profile.finishDistribution).not.toBeNull();
      expect(profile.finishDistribution!.totalRaces).toBe(50);
      expect(profile.finishDistribution!.wins).toBe(15);
      expect(profile.finishDistribution!.podiums).toBe(25);
      expect(profile.finishDistribution!.dnfs).toBe(5);
      expect(profile.finishDistribution!.topTen).toBeGreaterThan(0);
      expect(profile.finishDistribution!.other).toBeGreaterThan(0);

      // And: Team memberships should be present
      expect(profile.teamMemberships).toHaveLength(1);
      expect(profile.teamMemberships[0].team.id).toBe('team-1');
      expect(profile.teamMemberships[0].team.name.toString()).toBe('Racing Team');
      expect(profile.teamMemberships[0].membership.role).toBe('Driver');
      expect(profile.teamMemberships[0].membership.status).toBe('active');

      // And: Social summary should show friends
      expect(profile.socialSummary.friendsCount).toBe(1);
      expect(profile.socialSummary.friends).toHaveLength(1);
      expect(profile.socialSummary.friends[0].id).toBe('friend-1');
      expect(profile.socialSummary.friends[0].name.toString()).toBe('Jane Smith');

      // And: Extended profile should be present (generated by provider)
      expect(profile.extendedProfile).not.toBeNull();
      expect(profile.extendedProfile!.socialHandles).toBeInstanceOf(Array);
      expect(profile.extendedProfile!.achievements).toBeInstanceOf(Array);
    });

    it('should retrieve profile overview for driver with minimal data', async () => {
      // Scenario: Driver with minimal profile data
      // Given: A driver exists with minimal information
      const driverId = 'driver-456';
      const driver = Driver.create({
        id: driverId,
        iracingId: '78901',
        name: 'New Driver',
        country: 'DE',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has no statistics
      // And: The driver is not a member of any team
      // And: The driver has no friends
      // When: GetProfileOverviewUseCase.execute() is called with driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should contain basic driver info
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();

      // And: Driver info should be present
      expect(profile.driverInfo.driver.id).toBe(driverId);
      expect(profile.driverInfo.driver.name.toString()).toBe('New Driver');
      expect(profile.driverInfo.driver.country.toString()).toBe('DE');
      expect(profile.driverInfo.totalDrivers).toBeGreaterThan(0);

      // And: Stats should be null (no data)
      expect(profile.stats).toBeNull();

      // And: Finish distribution should be null
      expect(profile.finishDistribution).toBeNull();

      // And: Team memberships should be empty
      expect(profile.teamMemberships).toHaveLength(0);

      // And: Social summary should show no friends
      expect(profile.socialSummary.friendsCount).toBe(0);
      expect(profile.socialSummary.friends).toHaveLength(0);

      // And: Extended profile should be present (generated by provider)
      expect(profile.extendedProfile).not.toBeNull();
    });

    it('should retrieve profile overview with multiple team memberships', async () => {
      // Scenario: Driver with multiple team memberships
      // Given: A driver exists
      const driverId = 'driver-789';
      const driver = Driver.create({
        id: driverId,
        iracingId: '11111',
        name: 'Multi Team Driver',
        country: 'FR',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver is a member of multiple teams
      const team1 = Team.create({
        id: 'team-1',
        name: 'Team A',
        tag: 'TA',
        description: 'Team A',
        ownerId: 'owner-1',
        isRecruiting: true,
      });
      await teamRepository.create(team1);

      const team2 = Team.create({
        id: 'team-2',
        name: 'Team B',
        tag: 'TB',
        description: 'Team B',
        ownerId: 'owner-2',
        isRecruiting: false,
      });
      await teamRepository.create(team2);

      const membership1: TeamMembership = {
        teamId: 'team-1',
        driverId: driverId,
        role: 'Driver',
        status: 'active',
        joinedAt: new Date('2024-01-01'),
      };
      await teamMembershipRepository.saveMembership(membership1);

      const membership2: TeamMembership = {
        teamId: 'team-2',
        driverId: driverId,
        role: 'Admin',
        status: 'active',
        joinedAt: new Date('2024-02-01'),
      };
      await teamMembershipRepository.saveMembership(membership2);

      // When: GetProfileOverviewUseCase.execute() is called with driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should contain all team memberships
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();

      // And: Team memberships should include both teams
      expect(profile.teamMemberships).toHaveLength(2);
      expect(profile.teamMemberships[0].team.id).toBe('team-1');
      expect(profile.teamMemberships[0].membership.role).toBe('Driver');
      expect(profile.teamMemberships[1].team.id).toBe('team-2');
      expect(profile.teamMemberships[1].membership.role).toBe('Admin');

      // And: Team memberships should be sorted by joined date
      expect(profile.teamMemberships[0].membership.joinedAt.getTime()).toBeLessThan(
        profile.teamMemberships[1].membership.joinedAt.getTime()
      );
    });

    it('should retrieve profile overview with multiple friends', async () => {
      // Scenario: Driver with multiple friends
      // Given: A driver exists
      const driverId = 'driver-friends';
      const driver = Driver.create({
        id: driverId,
        iracingId: '22222',
        name: 'Social Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has multiple friends
      const friend1 = Driver.create({
        id: 'friend-1',
        iracingId: '33333',
        name: 'Friend 1',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(friend1);

      const friend2 = Driver.create({
        id: 'friend-2',
        iracingId: '44444',
        name: 'Friend 2',
        country: 'UK',
        avatarRef: undefined,
      });
      await driverRepository.create(friend2);

      const friend3 = Driver.create({
        id: 'friend-3',
        iracingId: '55555',
        name: 'Friend 3',
        country: 'DE',
        avatarRef: undefined,
      });
      await driverRepository.create(friend3);

      await socialRepository.seed({
        drivers: [driver, friend1, friend2, friend3],
        friendships: [
          { driverId: driverId, friendId: 'friend-1' },
          { driverId: driverId, friendId: 'friend-2' },
          { driverId: driverId, friendId: 'friend-3' },
        ],
        feedEvents: [],
      });

      // When: GetProfileOverviewUseCase.execute() is called with driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should contain all friends
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();

      // And: Social summary should show 3 friends
      expect(profile.socialSummary.friendsCount).toBe(3);
      expect(profile.socialSummary.friends).toHaveLength(3);

      // And: All friends should be present
      const friendIds = profile.socialSummary.friends.map(f => f.id);
      expect(friendIds).toContain('friend-1');
      expect(friendIds).toContain('friend-2');
      expect(friendIds).toContain('friend-3');
    });
  });

  describe('GetProfileOverviewUseCase - Edge Cases', () => {
    it('should handle driver with no statistics', async () => {
      // Scenario: Driver without statistics
      // Given: A driver exists
      const driverId = 'driver-no-stats';
      const driver = Driver.create({
        id: driverId,
        iracingId: '66666',
        name: 'No Stats Driver',
        country: 'CA',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has no statistics
      // When: GetProfileOverviewUseCase.execute() is called with driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should contain driver info with null stats
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();

      expect(profile.driverInfo.driver.id).toBe(driverId);
      expect(profile.stats).toBeNull();
      expect(profile.finishDistribution).toBeNull();
    });

    it('should handle driver with no team memberships', async () => {
      // Scenario: Driver without team memberships
      // Given: A driver exists
      const driverId = 'driver-no-teams';
      const driver = Driver.create({
        id: driverId,
        iracingId: '77777',
        name: 'Solo Driver',
        country: 'IT',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver is not a member of any team
      // When: GetProfileOverviewUseCase.execute() is called with driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should contain driver info with empty team memberships
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();

      expect(profile.driverInfo.driver.id).toBe(driverId);
      expect(profile.teamMemberships).toHaveLength(0);
    });

    it('should handle driver with no friends', async () => {
      // Scenario: Driver without friends
      // Given: A driver exists
      const driverId = 'driver-no-friends';
      const driver = Driver.create({
        id: driverId,
        iracingId: '88888',
        name: 'Lonely Driver',
        country: 'ES',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has no friends
      // When: GetProfileOverviewUseCase.execute() is called with driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should contain driver info with empty social summary
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();

      expect(profile.driverInfo.driver.id).toBe(driverId);
      expect(profile.socialSummary.friendsCount).toBe(0);
      expect(profile.socialSummary.friends).toHaveLength(0);
    });
  });

  describe('GetProfileOverviewUseCase - Error Handling', () => {
    it('should return error when driver does not exist', async () => {
      // Scenario: Non-existent driver
      // Given: No driver exists with the given ID
      const nonExistentDriverId = 'non-existent-driver';

      // When: GetProfileOverviewUseCase.execute() is called with non-existent driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId: nonExistentDriverId });

      // Then: Should return error
      expect(result.isErr()).toBe(true);
      const error = result.getError();
      expect(error.code).toBe('DRIVER_NOT_FOUND');
      expect(error.details.message).toBe('Driver not found');
    });

    it('should return error when driver ID is invalid', async () => {
      // Scenario: Invalid driver ID
      // Given: An invalid driver ID (empty string)
      const invalidDriverId = '';

      // When: GetProfileOverviewUseCase.execute() is called with invalid driver ID
      const result = await getProfileOverviewUseCase.execute({ driverId: invalidDriverId });

      // Then: Should return error
      expect(result.isErr()).toBe(true);
      const error = result.getError();
      expect(error.code).toBe('DRIVER_NOT_FOUND');
      expect(error.details.message).toBe('Driver not found');
    });
  });

  describe('UpdateDriverProfileUseCase - Success Path', () => {
    it('should update driver bio', async () => {
      // Scenario: Update driver bio
      // Given: A driver exists with bio
      const driverId = 'driver-update-bio';
      const driver = Driver.create({
        id: driverId,
        iracingId: '99999',
        name: 'Update Driver',
        country: 'US',
        bio: 'Original bio',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // When: UpdateDriverProfileUseCase.execute() is called with new bio
      const result = await updateDriverProfileUseCase.execute({
        driverId,
        bio: 'Updated bio',
      });

      // Then: The operation should succeed
      expect(result.isOk()).toBe(true);

      // And: The driver's bio should be updated
      const updatedDriver = await driverRepository.findById(driverId);
      expect(updatedDriver).not.toBeNull();
      expect(updatedDriver!.bio?.toString()).toBe('Updated bio');
    });

    it('should update driver country', async () => {
      // Scenario: Update driver country
      // Given: A driver exists with country
      const driverId = 'driver-update-country';
      const driver = Driver.create({
        id: driverId,
        iracingId: '10101',
        name: 'Country Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // When: UpdateDriverProfileUseCase.execute() is called with new country
      const result = await updateDriverProfileUseCase.execute({
        driverId,
        country: 'DE',
      });

      // Then: The operation should succeed
      expect(result.isOk()).toBe(true);

      // And: The driver's country should be updated
      const updatedDriver = await driverRepository.findById(driverId);
      expect(updatedDriver).not.toBeNull();
      expect(updatedDriver!.country.toString()).toBe('DE');
    });

    it('should update multiple profile fields at once', async () => {
      // Scenario: Update multiple fields
      // Given: A driver exists
      const driverId = 'driver-update-multiple';
      const driver = Driver.create({
        id: driverId,
        iracingId: '11111',
        name: 'Multi Update Driver',
        country: 'US',
        bio: 'Original bio',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // When: UpdateDriverProfileUseCase.execute() is called with multiple updates
      const result = await updateDriverProfileUseCase.execute({
        driverId,
        bio: 'Updated bio',
        country: 'FR',
      });

      // Then: The operation should succeed
      expect(result.isOk()).toBe(true);

      // And: Both fields should be updated
      const updatedDriver = await driverRepository.findById(driverId);
      expect(updatedDriver).not.toBeNull();
      expect(updatedDriver!.bio?.toString()).toBe('Updated bio');
      expect(updatedDriver!.country.toString()).toBe('FR');
    });
  });

  describe('UpdateDriverProfileUseCase - Validation', () => {
    it('should reject update with empty bio', async () => {
      // Scenario: Empty bio
      // Given: A driver exists
      const driverId = 'driver-empty-bio';
      const driver = Driver.create({
        id: driverId,
        iracingId: '12121',
        name: 'Empty Bio Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // When: UpdateDriverProfileUseCase.execute() is called with empty bio
      const result = await updateDriverProfileUseCase.execute({
        driverId,
        bio: '',
      });

      // Then: Should return error
      expect(result.isErr()).toBe(true);
      const error = result.getError();
      expect(error.code).toBe('INVALID_PROFILE_DATA');
      expect(error.details.message).toBe('Profile data is invalid');
    });

    it('should reject update with empty country', async () => {
      // Scenario: Empty country
      // Given: A driver exists
      const driverId = 'driver-empty-country';
      const driver = Driver.create({
        id: driverId,
        iracingId: '13131',
        name: 'Empty Country Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // When: UpdateDriverProfileUseCase.execute() is called with empty country
      const result = await updateDriverProfileUseCase.execute({
        driverId,
        country: '',
      });

      // Then: Should return error
      expect(result.isErr()).toBe(true);
      const error = result.getError();
      expect(error.code).toBe('INVALID_PROFILE_DATA');
      expect(error.details.message).toBe('Profile data is invalid');
    });
  });

  describe('UpdateDriverProfileUseCase - Error Handling', () => {
    it('should return error when driver does not exist', async () => {
      // Scenario: Non-existent driver
      // Given: No driver exists with the given ID
      const nonExistentDriverId = 'non-existent-driver';

      // When: UpdateDriverProfileUseCase.execute() is called with non-existent driver ID
      const result = await updateDriverProfileUseCase.execute({
        driverId: nonExistentDriverId,
        bio: 'New bio',
      });

      // Then: Should return error
      expect(result.isErr()).toBe(true);
      const error = result.getError();
      expect(error.code).toBe('DRIVER_NOT_FOUND');
      expect(error.details.message).toContain('Driver with id');
    });

    it('should return error when driver ID is invalid', async () => {
      // Scenario: Invalid driver ID
      // Given: An invalid driver ID (empty string)
      const invalidDriverId = '';

      // When: UpdateDriverProfileUseCase.execute() is called with invalid driver ID
      const result = await updateDriverProfileUseCase.execute({
        driverId: invalidDriverId,
        bio: 'New bio',
      });

      // Then: Should return error
      expect(result.isErr()).toBe(true);
      const error = result.getError();
      expect(error.code).toBe('DRIVER_NOT_FOUND');
      expect(error.details.message).toContain('Driver with id');
    });
  });

  describe('Profile Data Orchestration', () => {
    it('should correctly calculate win percentage from race results', async () => {
      // Scenario: Win percentage calculation
      // Given: A driver exists
      const driverId = 'driver-win-percentage';
      const driver = Driver.create({
        id: driverId,
        iracingId: '14141',
        name: 'Win Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has 10 race starts and 3 wins
      const stats: DriverStats = {
        totalRaces: 10,
        wins: 3,
        podiums: 5,
        dnfs: 0,
        avgFinish: 5.0,
        bestFinish: 1,
        worstFinish: 10,
        finishRate: 100,
        winRate: 30,
        podiumRate: 50,
        percentile: 70,
        rating: 1600,
        consistency: 85,
        overallRank: 100,
      };
      await driverStatsRepository.saveDriverStats(driverId, stats);

      // When: GetProfileOverviewUseCase.execute() is called
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should show win percentage as 30%
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();
      expect(profile.stats!.winRate).toBe(30);
    });

    it('should correctly calculate podium rate from race results', async () => {
      // Scenario: Podium rate calculation
      // Given: A driver exists
      const driverId = 'driver-podium-rate';
      const driver = Driver.create({
        id: driverId,
        iracingId: '15151',
        name: 'Podium Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has 10 race starts and 5 podiums
      const stats: DriverStats = {
        totalRaces: 10,
        wins: 2,
        podiums: 5,
        dnfs: 0,
        avgFinish: 4.0,
        bestFinish: 1,
        worstFinish: 8,
        finishRate: 100,
        winRate: 20,
        podiumRate: 50,
        percentile: 60,
        rating: 1550,
        consistency: 80,
        overallRank: 150,
      };
      await driverStatsRepository.saveDriverStats(driverId, stats);

      // When: GetProfileOverviewUseCase.execute() is called
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should show podium rate as 50%
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();
      expect(profile.stats!.podiumRate).toBe(50);
    });

    it('should correctly calculate finish distribution', async () => {
      // Scenario: Finish distribution calculation
      // Given: A driver exists
      const driverId = 'driver-finish-dist';
      const driver = Driver.create({
        id: driverId,
        iracingId: '16161',
        name: 'Finish Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has 20 race starts with various finishes
      const stats: DriverStats = {
        totalRaces: 20,
        wins: 5,
        podiums: 8,
        dnfs: 2,
        avgFinish: 6.5,
        bestFinish: 1,
        worstFinish: 15,
        finishRate: 90,
        winRate: 25,
        podiumRate: 40,
        percentile: 75,
        rating: 1700,
        consistency: 88,
        overallRank: 75,
      };
      await driverStatsRepository.saveDriverStats(driverId, stats);

      // When: GetProfileOverviewUseCase.execute() is called
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: The result should show correct finish distribution
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();
      expect(profile.finishDistribution!.totalRaces).toBe(20);
      expect(profile.finishDistribution!.wins).toBe(5);
      expect(profile.finishDistribution!.podiums).toBe(8);
      expect(profile.finishDistribution!.dnfs).toBe(2);
      expect(profile.finishDistribution!.topTen).toBeGreaterThan(0);
      expect(profile.finishDistribution!.other).toBeGreaterThan(0);
    });

    it('should correctly format team affiliation with role', async () => {
      // Scenario: Team affiliation formatting
      // Given: A driver exists
      const driverId = 'driver-team-affiliation';
      const driver = Driver.create({
        id: driverId,
        iracingId: '17171',
        name: 'Team Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver is affiliated with a team
      const team = Team.create({
        id: 'team-affiliation',
        name: 'Affiliation Team',
        tag: 'AT',
        description: 'Team for testing',
        ownerId: 'owner-1',
        isRecruiting: true,
      });
      await teamRepository.create(team);

      const membership: TeamMembership = {
        teamId: 'team-affiliation',
        driverId: driverId,
        role: 'Driver',
        status: 'active',
        joinedAt: new Date('2024-01-01'),
      };
      await teamMembershipRepository.saveMembership(membership);

      // When: GetProfileOverviewUseCase.execute() is called
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: Team affiliation should show team name and role
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();
      expect(profile.teamMemberships).toHaveLength(1);
      expect(profile.teamMemberships[0].team.name.toString()).toBe('Affiliation Team');
      expect(profile.teamMemberships[0].membership.role).toBe('Driver');
    });

    it('should correctly identify driver role in each team', async () => {
      // Scenario: Driver role identification
      // Given: A driver exists
      const driverId = 'driver-roles';
      const driver = Driver.create({
        id: driverId,
        iracingId: '18181',
        name: 'Role Driver',
        country: 'US',
        avatarRef: undefined,
      });
      await driverRepository.create(driver);

      // And: The driver has different roles in different teams
      const team1 = Team.create({
        id: 'team-role-1',
        name: 'Team A',
        tag: 'TA',
        description: 'Team A',
        ownerId: 'owner-1',
        isRecruiting: true,
      });
      await teamRepository.create(team1);

      const team2 = Team.create({
        id: 'team-role-2',
        name: 'Team B',
        tag: 'TB',
        description: 'Team B',
        ownerId: 'owner-2',
        isRecruiting: false,
      });
      await teamRepository.create(team2);

      const team3 = Team.create({
        id: 'team-role-3',
        name: 'Team C',
        tag: 'TC',
        description: 'Team C',
        ownerId: driverId,
        isRecruiting: true,
      });
      await teamRepository.create(team3);

      const membership1: TeamMembership = {
        teamId: 'team-role-1',
        driverId: driverId,
        role: 'Driver',
        status: 'active',
        joinedAt: new Date('2024-01-01'),
      };
      await teamMembershipRepository.saveMembership(membership1);

      const membership2: TeamMembership = {
        teamId: 'team-role-2',
        driverId: driverId,
        role: 'Admin',
        status: 'active',
        joinedAt: new Date('2024-02-01'),
      };
      await teamMembershipRepository.saveMembership(membership2);

      const membership3: TeamMembership = {
        teamId: 'team-role-3',
        driverId: driverId,
        role: 'Owner',
        status: 'active',
        joinedAt: new Date('2024-03-01'),
      };
      await teamMembershipRepository.saveMembership(membership3);

      // When: GetProfileOverviewUseCase.execute() is called
      const result = await getProfileOverviewUseCase.execute({ driverId });

      // Then: Each team should show the correct role
      expect(result.isOk()).toBe(true);
      const profile = result.unwrap();
      expect(profile.teamMemberships).toHaveLength(3);

      const teamARole = profile.teamMemberships.find(m => m.team.id === 'team-role-1')?.membership.role;
      const teamBRole = profile.teamMemberships.find(m => m.team.id === 'team-role-2')?.membership.role;
      const teamCRole = profile.teamMemberships.find(m => m.team.id === 'team-role-3')?.membership.role;

      expect(teamARole).toBe('Driver');
      expect(teamBRole).toBe('Admin');
      expect(teamCRole).toBe('Owner');
    });
  });
});
