import { describe, it, expect } from 'vitest';

import {
  DashboardOverviewUseCase,
  type DashboardOverviewInput,
  type DashboardOverviewResult,
} from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import { Driver } from '@core/racing/domain/entities/Driver';
import { Race } from '@core/racing/domain/entities/Race';
import { League } from '@core/racing/domain/entities/League';
import { Standing } from '@core/racing/domain/entities/Standing';
import { LeagueMembership } from '@core/racing/domain/entities/LeagueMembership';
import { Result as RaceResult } from '@core/racing/domain/entities/result/Result';

import type { FeedItem } from '@core/social/domain/types/FeedItem';
import { Result as UseCaseResult } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { JoinRequest } from '@core/racing/domain/entities/JoinRequest';
import { RaceRegistration } from '@core/racing/domain/entities/RaceRegistration';

describe('DashboardOverviewUseCase', () => {
  it('partitions upcoming races into myUpcomingRaces and otherUpcomingRaces and selects nextRace from myUpcomingRaces', async () => {
    const driverId = 'driver-1';

    const driver = Driver.create({ id: driverId, iracingId: '12345', name: 'Alice Racer', country: 'US' });

    const leagues = [
      League.create({ id: 'league-1', name: 'Alpha League', description: 'First league', ownerId: 'owner-1' }),
      League.create({ id: 'league-2', name: 'Beta League', description: 'Second league', ownerId: 'owner-2' }),
    ];

    const now = Date.now();

    const races = [
      Race.create({
        id: 'race-1',
        leagueId: 'league-1',
        track: 'Monza',
        car: 'GT3',
        scheduledAt: new Date(now + 60 * 60 * 1000),
        status: 'scheduled',
      }),
      Race.create({
        id: 'race-2',
        leagueId: 'league-1',
        track: 'Spa',
        car: 'GT3',
        scheduledAt: new Date(now + 2 * 60 * 60 * 1000),
        status: 'scheduled',
      }),
      Race.create({
        id: 'race-3',
        leagueId: 'league-2',
        track: 'Silverstone',
        car: 'GT4',
        scheduledAt: new Date(now + 3 * 60 * 60 * 1000),
        status: 'scheduled',
      }),
      Race.create({
        id: 'race-4',
        leagueId: 'league-2',
        track: 'Imola',
        car: 'GT4',
        scheduledAt: new Date(now + 4 * 60 * 60 * 1000),
        status: 'scheduled',
      }),
    ];

    const results: RaceResult[] = [];

    const memberships = [
      LeagueMembership.create({
        leagueId: 'league-1',
        driverId,
        role: 'member',
        status: 'active',
      }),
      LeagueMembership.create({
        leagueId: 'league-2',
        driverId,
        role: 'member',
        status: 'active',
      }),
    ];

    const registeredRaceIds = new Set<string>(['race-1', 'race-3']);

    const feedItems: FeedItem[] = [];
    const friends: Driver[] = [];

    const driverRepository = {
      findById: async (id: string): Promise<Driver | null> => (id === driver.id ? driver : null),
      findByIRacingId: async (): Promise<Driver | null> => null,
      findAll: async (): Promise<Driver[]> => [],
      create: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByIRacingId: async (): Promise<boolean> => false,
    };

    const raceRepository = {
      findById: async (): Promise<Race | null> => null,
      findAll: async (): Promise<Race[]> => races,
      findByLeagueId: async (): Promise<Race[]> => [],
      findUpcomingByLeagueId: async (): Promise<Race[]> => [],
      findCompletedByLeagueId: async (): Promise<Race[]> => [],
      findByStatus: async (): Promise<Race[]> => [],
      findByDateRange: async (): Promise<Race[]> => [],
      create: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
    };

    const resultRepository = {
      findById: async (): Promise<RaceResult | null> => null,
      findAll: async (): Promise<RaceResult[]> => results,
      findByRaceId: async (): Promise<RaceResult[]> => [],
      findByDriverId: async (): Promise<RaceResult[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<RaceResult[]> => [],
      create: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      createMany: async (): Promise<RaceResult[]> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByRaceId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByRaceId: async (): Promise<boolean> => false,
    };

    const leagueRepository = {
      findById: async (): Promise<League | null> => null,
      findAll: async (): Promise<League[]> => leagues,
      findByOwnerId: async (): Promise<League[]> => [],
      create: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      searchByName: async (): Promise<League[]> => [],
    };

    const standingRepository = {
      findByLeagueId: async (): Promise<Standing[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<Standing | null> => null,
      findAll: async (): Promise<Standing[]> => [],
      save: async (): Promise<Standing> => {
        throw new Error('Not implemented');
      },
      saveMany: async (): Promise<Standing[]> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByLeagueId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      recalculate: async (): Promise<Standing[]> => [],
    };

    const leagueMembershipRepository = {
      getMembership: async (leagueId: string, driverIdParam: string): Promise<LeagueMembership | null> => {
        return (
          memberships.find(
            m => m.leagueId.toString() === leagueId && m.driverId.toString() === driverIdParam,
          ) ?? null
        );
      },
      getLeagueMembers: async (): Promise<LeagueMembership[]> => [],
      getJoinRequests: async (): Promise<JoinRequest[]> => [],
      saveMembership: async (): Promise<LeagueMembership> => {
        throw new Error('Not implemented');
      },
      removeMembership: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      saveJoinRequest: async (): Promise<JoinRequest> => {
        throw new Error('Not implemented');
      },
      removeJoinRequest: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
    };

    const raceRegistrationRepository = {
      isRegistered: async (raceId: string, driverIdParam: string): Promise<boolean> => {
        if (driverIdParam !== driverId) return false;
        return registeredRaceIds.has(raceId);
      },
      getRegisteredDrivers: async (): Promise<string[]> => [],
      getRegistrationCount: async (): Promise<number> => 0,
      register: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      withdraw: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      getDriverRegistrations: async (): Promise<string[]> => [],
      clearRaceRegistrations: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      findByRaceId: async (): Promise<RaceRegistration[]> => [],
    };

    const feedRepository = {
      getFeedForDriver: async (): Promise<FeedItem[]> => feedItems,
      getGlobalFeed: async (): Promise<FeedItem[]> => [],
    };

    const socialRepository = {
      getFriends: async (): Promise<Driver[]> => friends,
      getFriendIds: async (): Promise<string[]> => [],
      getSuggestedFriends: async (): Promise<Driver[]> => [],
    };

    const getDriverAvatar = async (id: string): Promise<string> => `avatar-${id}`;

    const getDriverStats = (id: string) =>
      id === driverId
        ? {
            rating: 1600,
            wins: 5,
            podiums: 12,
            totalRaces: 40,
            overallRank: 42,
            consistency: 88,
          }
        : null;

    // Mock output port to capture presented data
    let _presentedData: DashboardOverviewResult | null = null;
    const outputPort: UseCaseOutputPort<DashboardOverviewResult> = {
      present: (data: DashboardOverviewResult) => {
        _presentedData = data;
      },
    };

    const useCase = new DashboardOverviewUseCase(
      driverRepository,
      raceRepository,
      resultRepository,
      leagueRepository,
      standingRepository,
      leagueMembershipRepository,
      raceRegistrationRepository,
      feedRepository,
      socialRepository,
      getDriverAvatar,
      getDriverStats,
      outputPort,
    );

    const input: DashboardOverviewInput = { driverId };

    const result: UseCaseResult<
      void,
      ApplicationErrorCode<'DRIVER_NOT_FOUND' | 'REPOSITORY_ERROR', { message: string }>
    > = await useCase.execute(input);

    expect(result.isOk()).toBe(true);
    expect(_presentedData).not.toBeNull();
    const vm = _presentedData!;

    expect(vm.myUpcomingRaces.map(r => r.race.id)).toEqual(['race-1', 'race-3']);

    expect(vm.otherUpcomingRaces.map(r => r.race.id)).toEqual(['race-2', 'race-4']);

    expect(vm.nextRace).not.toBeNull();
    expect(vm.nextRace!.race.id).toBe('race-1');
  });

  it('builds recentResults sorted by date descending and leagueStandingsSummaries from standings', async () => {
    const driverId = 'driver-2';

    const driver = Driver.create({ id: driverId, iracingId: '67890', name: 'Result Driver', country: 'DE' });

    const leagues = [
      League.create({ id: 'league-A', name: 'Results League A', description: 'League A', ownerId: 'owner-A' }),
      League.create({ id: 'league-B', name: 'Results League B', description: 'League B', ownerId: 'owner-B' }),
    ];

    const raceOld = Race.create({
      id: 'race-old',
      leagueId: 'league-A',
      track: 'Old Circuit',
      car: 'GT3',
      scheduledAt: new Date('2024-01-01T10:00:00Z'),
      status: 'completed',
    });

    const raceNew = Race.create({
      id: 'race-new',
      leagueId: 'league-B',
      track: 'New Circuit',
      car: 'GT4',
      scheduledAt: new Date('2024-02-01T10:00:00Z'),
      status: 'completed',
    });

    const races = [raceOld, raceNew];

    const results: RaceResult[] = [
      RaceResult.create({
        id: 'result-old',
        raceId: raceOld.id,
        driverId,
        position: 5,
        fastestLap: 120,
        incidents: 3,
        startPosition: 5,
      }),
      RaceResult.create({
        id: 'result-new',
        raceId: raceNew.id,
        driverId,
        position: 2,
        fastestLap: 115,
        incidents: 1,
        startPosition: 2,
      }),
    ];

    const memberships = [
      LeagueMembership.create({
        leagueId: 'league-A',
        driverId,
        role: 'member',
        status: 'active',
      }),
      LeagueMembership.create({
        leagueId: 'league-B',
        driverId,
        role: 'member',
        status: 'active',
      }),
    ];

    const standingsByLeague = new Map<string, Standing[]>();
    standingsByLeague.set('league-A', [
      Standing.create({ leagueId: 'league-A', driverId, position: 3, points: 50 }),
      Standing.create({ leagueId: 'league-A', driverId: 'other-1', position: 1, points: 80 }),
    ]);
    standingsByLeague.set('league-B', [
      Standing.create({ leagueId: 'league-B', driverId, position: 1, points: 100 }),
      Standing.create({ leagueId: 'league-B', driverId: 'other-2', position: 2, points: 90 }),
    ]);

    const driverRepository = {
      findById: async (id: string): Promise<Driver | null> => (id === driver.id ? driver : null),
      findByIRacingId: async (): Promise<Driver | null> => null,
      findAll: async (): Promise<Driver[]> => [],
      create: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByIRacingId: async (): Promise<boolean> => false,
    };

    const raceRepository = {
      findById: async (): Promise<Race | null> => null,
      findAll: async (): Promise<Race[]> => races,
      findByLeagueId: async (): Promise<Race[]> => [],
      findUpcomingByLeagueId: async (): Promise<Race[]> => [],
      findCompletedByLeagueId: async (): Promise<Race[]> => [],
      findByStatus: async (): Promise<Race[]> => [],
      findByDateRange: async (): Promise<Race[]> => [],
      create: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
    };

    const resultRepository = {
      findById: async (): Promise<RaceResult | null> => null,
      findAll: async (): Promise<RaceResult[]> => results,
      findByRaceId: async (): Promise<RaceResult[]> => [],
      findByDriverId: async (): Promise<RaceResult[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<RaceResult[]> => [],
      create: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      createMany: async (): Promise<RaceResult[]> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByRaceId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByRaceId: async (): Promise<boolean> => false,
    };

    const leagueRepository = {
      findById: async (): Promise<League | null> => null,
      findAll: async (): Promise<League[]> => leagues,
      findByOwnerId: async (): Promise<League[]> => [],
      create: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      searchByName: async (): Promise<League[]> => [],
    };

    const standingRepository = {
      findByLeagueId: async (leagueId: string): Promise<Standing[]> =>
        standingsByLeague.get(leagueId) ?? [],
      findByDriverIdAndLeagueId: async (): Promise<Standing | null> => null,
      findAll: async (): Promise<Standing[]> => [],
      save: async (): Promise<Standing> => {
        throw new Error('Not implemented');
      },
      saveMany: async (): Promise<Standing[]> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByLeagueId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      recalculate: async (): Promise<Standing[]> => [],
    };

    const leagueMembershipRepository = {
      getMembership: async (leagueId: string, driverIdParam: string): Promise<LeagueMembership | null> => {
        return (
          memberships.find(
            m => m.leagueId.toString() === leagueId && m.driverId.toString() === driverIdParam,
          ) ?? null
        );
      },
      getLeagueMembers: async (): Promise<LeagueMembership[]> => [],
      getJoinRequests: async (): Promise<JoinRequest[]> => [],
      saveMembership: async (): Promise<LeagueMembership> => {
        throw new Error('Not implemented');
      },
      removeMembership: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      saveJoinRequest: async (): Promise<JoinRequest> => {
        throw new Error('Not implemented');
      },
      removeJoinRequest: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
    };

    const raceRegistrationRepository = {
      isRegistered: async (): Promise<boolean> => false,
      getRegisteredDrivers: async (): Promise<string[]> => [],
      getRegistrationCount: async (): Promise<number> => 0,
      register: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      withdraw: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      getDriverRegistrations: async (): Promise<string[]> => [],
      clearRaceRegistrations: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      findByRaceId: async (): Promise<RaceRegistration[]> => [],
    };

    const feedRepository = {
      getFeedForDriver: async (): Promise<FeedItem[]> => [],
      getGlobalFeed: async (): Promise<FeedItem[]> => [],
    };

    const socialRepository = {
      getFriends: async (): Promise<Driver[]> => [],
      getFriendIds: async (): Promise<string[]> => [],
      getSuggestedFriends: async (): Promise<Driver[]> => [],
    };

    const getDriverAvatar = async (id: string): Promise<string> => `avatar-${id}`;

    const getDriverStats = (id: string) =>
      id === driverId
        ? {
            rating: 1800,
            wins: 3,
            podiums: 7,
            totalRaces: 20,
            overallRank: 10,
            consistency: 92,
          }
        : null;

    // Mock output port to capture presented data
    let _presentedData: DashboardOverviewResult | null = null;
    const outputPort: UseCaseOutputPort<DashboardOverviewResult> = {
      present: (data: DashboardOverviewResult) => {
        _presentedData = data;
      },
    };

    const useCase = new DashboardOverviewUseCase(
      driverRepository,
      raceRepository,
      resultRepository,
      leagueRepository,
      standingRepository,
      leagueMembershipRepository,
      raceRegistrationRepository,
      feedRepository,
      socialRepository,
      getDriverAvatar,
      getDriverStats,
      outputPort,
    );

    const input: DashboardOverviewInput = { driverId };

    const result: UseCaseResult<
      void,
      ApplicationErrorCode<'DRIVER_NOT_FOUND' | 'REPOSITORY_ERROR', { message: string }>
    > = await useCase.execute(input);

    expect(result.isOk()).toBe(true);
    expect(_presentedData).not.toBeNull();
    const vm = _presentedData!;

    expect(vm.recentResults.length).toBe(2);
    expect(vm.recentResults[0]!.race.id).toBe('race-new');
    expect(vm.recentResults[1]!.race.id).toBe('race-old');

    const summariesByLeague = new Map(
      vm.leagueStandingsSummaries.map(s => [s.league.id.toString(), s] as const),
    );

    const summaryA = summariesByLeague.get('league-A');
    const summaryB = summariesByLeague.get('league-B');

    expect(summaryA).toBeDefined();
    expect(summaryA!.standing?.position.toNumber()).toBe(3);
    expect(summaryA!.standing?.points.toNumber()).toBe(50);
    expect(summaryA!.totalDrivers).toBe(2);

    expect(summaryB).toBeDefined();
    expect(summaryB!.standing?.position.toNumber()).toBe(1);
    expect(summaryB!.standing?.points.toNumber()).toBe(100);
    expect(summaryB!.totalDrivers).toBe(2);
  });

  it('returns empty collections and safe defaults when driver has no races or standings', async () => {
    const driverId = 'driver-empty';

    const driver = Driver.create({ id: driverId, iracingId: '11111', name: 'New Racer', country: 'FR' });

    const driverRepository = {
      findById: async (id: string): Promise<Driver | null> => (id === driver.id ? driver : null),
      findByIRacingId: async (): Promise<Driver | null> => null,
      findAll: async (): Promise<Driver[]> => [],
      create: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByIRacingId: async (): Promise<boolean> => false,
    };

    const raceRepository = {
      findById: async (): Promise<Race | null> => null,
      findAll: async (): Promise<Race[]> => [],
      findByLeagueId: async (): Promise<Race[]> => [],
      findUpcomingByLeagueId: async (): Promise<Race[]> => [],
      findCompletedByLeagueId: async (): Promise<Race[]> => [],
      findByStatus: async (): Promise<Race[]> => [],
      findByDateRange: async (): Promise<Race[]> => [],
      create: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
    };

    const resultRepository = {
      findById: async (): Promise<RaceResult | null> => null,
      findAll: async (): Promise<RaceResult[]> => [],
      findByRaceId: async (): Promise<RaceResult[]> => [],
      findByDriverId: async (): Promise<RaceResult[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<RaceResult[]> => [],
      create: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      createMany: async (): Promise<RaceResult[]> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByRaceId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByRaceId: async (): Promise<boolean> => false,
    };

    const leagueRepository = {
      findById: async (): Promise<League | null> => null,
      findAll: async (): Promise<League[]> => [],
      findByOwnerId: async (): Promise<League[]> => [],
      create: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      searchByName: async (): Promise<League[]> => [],
    };

    const standingRepository = {
      findByLeagueId: async (): Promise<Standing[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<Standing | null> => null,
      findAll: async (): Promise<Standing[]> => [],
      save: async (): Promise<Standing> => {
        throw new Error('Not implemented');
      },
      saveMany: async (): Promise<Standing[]> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByLeagueId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      recalculate: async (): Promise<Standing[]> => [],
    };

    const leagueMembershipRepository = {
      getMembership: async (): Promise<LeagueMembership | null> => null,
      getLeagueMembers: async (): Promise<LeagueMembership[]> => [],
      getJoinRequests: async (): Promise<JoinRequest[]> => [],
      saveMembership: async (): Promise<LeagueMembership> => {
        throw new Error('Not implemented');
      },
      removeMembership: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      saveJoinRequest: async (): Promise<JoinRequest> => {
        throw new Error('Not implemented');
      },
      removeJoinRequest: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
    };

    const raceRegistrationRepository = {
      isRegistered: async (): Promise<boolean> => false,
      getRegisteredDrivers: async (): Promise<string[]> => [],
      getRegistrationCount: async (): Promise<number> => 0,
      register: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      withdraw: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      getDriverRegistrations: async (): Promise<string[]> => [],
      clearRaceRegistrations: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      findByRaceId: async (): Promise<RaceRegistration[]> => [],
    };

    const feedRepository = {
      getFeedForDriver: async (): Promise<FeedItem[]> => [],
      getGlobalFeed: async (): Promise<FeedItem[]> => [],
    };

    const socialRepository = {
      getFriends: async (): Promise<Driver[]> => [],
      getFriendIds: async (): Promise<string[]> => [],
      getSuggestedFriends: async (): Promise<Driver[]> => [],
    };

    const getDriverAvatar = async (id: string): Promise<string> => `avatar-${id}`;

    const getDriverStats = () => null;

    // Mock output port to capture presented data
    let _presentedData: DashboardOverviewResult | null = null;
    const outputPort: UseCaseOutputPort<DashboardOverviewResult> = {
      present: (data: DashboardOverviewResult) => {
        _presentedData = data;
      },
    };

    const useCase = new DashboardOverviewUseCase(
      driverRepository,
      raceRepository,
      resultRepository,
      leagueRepository,
      standingRepository,
      leagueMembershipRepository,
      raceRegistrationRepository,
      feedRepository,
      socialRepository,
      getDriverAvatar,
      getDriverStats,
      outputPort,
    );

    const input: DashboardOverviewInput = { driverId };

    const result: UseCaseResult<
      void,
      ApplicationErrorCode<'DRIVER_NOT_FOUND' | 'REPOSITORY_ERROR', { message: string }>
    > = await useCase.execute(input);

    expect(result.isOk()).toBe(true);
    expect(_presentedData).not.toBeNull();
    const vm = _presentedData!;

    expect(vm.myUpcomingRaces).toEqual([]);
    expect(vm.otherUpcomingRaces).toEqual([]);
    expect(vm.nextRace).toBeNull();
    expect(vm.recentResults).toEqual([]);
    expect(vm.leagueStandingsSummaries).toEqual([]);
    expect(vm.friends).toEqual([]);
    expect(vm.feedSummary.notificationCount).toBe(0);
    expect(vm.feedSummary.items).toEqual([]);
  });

  it('returns DRIVER_NOT_FOUND error when driver is missing', async () => {
    const driverId = 'missing-driver';

    const driverRepository = {
      findById: async (): Promise<Driver | null> => null,
      findByIRacingId: async (): Promise<Driver | null> => null,
      findAll: async (): Promise<Driver[]> => [],
      create: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByIRacingId: async (): Promise<boolean> => false,
    };

    const raceRepository = {
      findById: async (): Promise<Race | null> => null,
      findAll: async (): Promise<Race[]> => [],
      findByLeagueId: async (): Promise<Race[]> => [],
      findUpcomingByLeagueId: async (): Promise<Race[]> => [],
      findCompletedByLeagueId: async (): Promise<Race[]> => [],
      findByStatus: async (): Promise<Race[]> => [],
      findByDateRange: async (): Promise<Race[]> => [],
      create: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
    };

    const resultRepository = {
      findById: async (): Promise<RaceResult | null> => null,
      findAll: async (): Promise<RaceResult[]> => [],
      findByRaceId: async (): Promise<RaceResult[]> => [],
      findByDriverId: async (): Promise<RaceResult[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<RaceResult[]> => [],
      create: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      createMany: async (): Promise<RaceResult[]> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByRaceId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByRaceId: async (): Promise<boolean> => false,
    };

    const leagueRepository = {
      findById: async (): Promise<League | null> => null,
      findAll: async (): Promise<League[]> => [],
      findByOwnerId: async (): Promise<League[]> => [],
      create: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      searchByName: async (): Promise<League[]> => [],
    };

    const standingRepository = {
      findByLeagueId: async (): Promise<Standing[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<Standing | null> => null,
      findAll: async (): Promise<Standing[]> => [],
      save: async (): Promise<Standing> => {
        throw new Error('Not implemented');
      },
      saveMany: async (): Promise<Standing[]> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByLeagueId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      recalculate: async (): Promise<Standing[]> => [],
    };

    const leagueMembershipRepository = {
      getMembership: async (): Promise<LeagueMembership | null> => null,
      getLeagueMembers: async (): Promise<LeagueMembership[]> => [],
      getJoinRequests: async (): Promise<JoinRequest[]> => [],
      saveMembership: async (): Promise<LeagueMembership> => {
        throw new Error('Not implemented');
      },
      removeMembership: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      saveJoinRequest: async (): Promise<JoinRequest> => {
        throw new Error('Not implemented');
      },
      removeJoinRequest: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
    };

    const raceRegistrationRepository = {
      isRegistered: async (): Promise<boolean> => false,
      getRegisteredDrivers: async (): Promise<string[]> => [],
      getRegistrationCount: async (): Promise<number> => 0,
      register: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      withdraw: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      getDriverRegistrations: async (): Promise<string[]> => [],
      clearRaceRegistrations: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      findByRaceId: async (): Promise<RaceRegistration[]> => [],
    };

    const feedRepository = {
      getFeedForDriver: async (): Promise<FeedItem[]> => [],
      getGlobalFeed: async (): Promise<FeedItem[]> => [],
    };

    const socialRepository = {
      getFriends: async (): Promise<Driver[]> => [],
      getFriendIds: async (): Promise<string[]> => [],
      getSuggestedFriends: async (): Promise<Driver[]> => [],
    };

    const getDriverAvatar = async (id: string): Promise<string> => `avatar-${id}`;

    const getDriverStats = () => null;

    // Mock output port to capture presented data
    const outputPort: UseCaseOutputPort<DashboardOverviewResult> = {
      present: (_data: DashboardOverviewResult) => {
        void _data;
      },
    };

    const useCase = new DashboardOverviewUseCase(
      driverRepository,
      raceRepository,
      resultRepository,
      leagueRepository,
      standingRepository,
      leagueMembershipRepository,
      raceRegistrationRepository,
      feedRepository,
      socialRepository,
      getDriverAvatar,
      getDriverStats,
      outputPort,
    );

    const input: DashboardOverviewInput = { driverId };

    const result: UseCaseResult<
      void,
      ApplicationErrorCode<'DRIVER_NOT_FOUND' | 'REPOSITORY_ERROR', { message: string }>
    > = await useCase.execute(input);

    expect(result.isErr()).toBe(true);
    const err = result.unwrapErr();
    expect(err.code).toBe('DRIVER_NOT_FOUND');
    expect(err.details?.message).toBe('Driver not found');
  });

  it('returns REPOSITORY_ERROR when an unexpected error occurs', async () => {
    const driverId = 'driver-error';

    const driver = Driver.create({ id: driverId, iracingId: '99999', name: 'Error Driver', country: 'GB' });

    const driverRepository = {
      findById: async (): Promise<Driver | null> => driver,
      findByIRacingId: async (): Promise<Driver | null> => null,
      findAll: async (): Promise<Driver[]> => [],
      create: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Driver> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByIRacingId: async (): Promise<boolean> => false,
    };

    const raceRepository = {
      findById: async (): Promise<Race | null> => null,
      findAll: async (): Promise<Race[]> => {
        throw new Error('DB failure');
      },
      findByLeagueId: async (): Promise<Race[]> => [],
      findUpcomingByLeagueId: async (): Promise<Race[]> => [],
      findCompletedByLeagueId: async (): Promise<Race[]> => [],
      findByStatus: async (): Promise<Race[]> => [],
      findByDateRange: async (): Promise<Race[]> => [],
      create: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<Race> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
    };

    const resultRepository = {
      findById: async (): Promise<RaceResult | null> => null,
      findAll: async (): Promise<RaceResult[]> => [],
      findByRaceId: async (): Promise<RaceResult[]> => [],
      findByDriverId: async (): Promise<RaceResult[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<RaceResult[]> => [],
      create: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      createMany: async (): Promise<RaceResult[]> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<RaceResult> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByRaceId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      existsByRaceId: async (): Promise<boolean> => false,
    };

    const leagueRepository = {
      findById: async (): Promise<League | null> => null,
      findAll: async (): Promise<League[]> => [],
      findByOwnerId: async (): Promise<League[]> => [],
      create: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      update: async (): Promise<League> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      searchByName: async (): Promise<League[]> => [],
    };

    const standingRepository = {
      findByLeagueId: async (): Promise<Standing[]> => [],
      findByDriverIdAndLeagueId: async (): Promise<Standing | null> => null,
      findAll: async (): Promise<Standing[]> => [],
      save: async (): Promise<Standing> => {
        throw new Error('Not implemented');
      },
      saveMany: async (): Promise<Standing[]> => {
        throw new Error('Not implemented');
      },
      delete: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      deleteByLeagueId: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      exists: async (): Promise<boolean> => false,
      recalculate: async (): Promise<Standing[]> => [],
    };

    const leagueMembershipRepository = {
      getMembership: async (): Promise<LeagueMembership | null> => null,
      getLeagueMembers: async (): Promise<LeagueMembership[]> => [],
      getJoinRequests: async (): Promise<JoinRequest[]> => [],
      saveMembership: async (): Promise<LeagueMembership> => {
        throw new Error('Not implemented');
      },
      removeMembership: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      saveJoinRequest: async (): Promise<JoinRequest> => {
        throw new Error('Not implemented');
      },
      removeJoinRequest: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
    };

    const raceRegistrationRepository = {
      isRegistered: async (): Promise<boolean> => false,
      getRegisteredDrivers: async (): Promise<string[]> => [],
      getRegistrationCount: async (): Promise<number> => 0,
      register: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      withdraw: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      getDriverRegistrations: async (): Promise<string[]> => [],
      clearRaceRegistrations: async (): Promise<void> => {
        throw new Error('Not implemented');
      },
      findByRaceId: async (): Promise<RaceRegistration[]> => [],
    };

    const feedRepository = {
      getFeedForDriver: async (): Promise<FeedItem[]> => [],
      getGlobalFeed: async (): Promise<FeedItem[]> => [],
    };

    const socialRepository = {
      getFriends: async (): Promise<Driver[]> => [],
      getFriendIds: async (): Promise<string[]> => [],
      getSuggestedFriends: async (): Promise<Driver[]> => [],
    };

    const getDriverAvatar = async (id: string): Promise<string> => `avatar-${id}`;

    const getDriverStats = () => null;

    // Mock output port to capture presented data
    const outputPort: UseCaseOutputPort<DashboardOverviewResult> = {
      present: (_data: DashboardOverviewResult) => {
        void _data;
      },
    };

    const useCase = new DashboardOverviewUseCase(
      driverRepository,
      raceRepository,
      resultRepository,
      leagueRepository,
      standingRepository,
      leagueMembershipRepository,
      raceRegistrationRepository,
      feedRepository,
      socialRepository,
      getDriverAvatar,
      getDriverStats,
      outputPort,
    );

    const input: DashboardOverviewInput = { driverId };

    const result: UseCaseResult<
      void,
      ApplicationErrorCode<'DRIVER_NOT_FOUND' | 'REPOSITORY_ERROR', { message: string }>
    > = await useCase.execute(input);

    expect(result.isErr()).toBe(true);
    const err = result.unwrapErr();
    expect(err.code).toBe('REPOSITORY_ERROR');
    expect(err.details?.message).toBe('DB failure');
  });
});
