import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
  GetProfileOverviewUseCase,
  type GetProfileOverviewResult,
} from './GetProfileOverviewUseCase';
import { IDriverRepository } from '../../domain/repositories/IDriverRepository';
import { ITeamRepository } from '../../domain/repositories/ITeamRepository';
import { ITeamMembershipRepository } from '../../domain/repositories/ITeamMembershipRepository';
import { ISocialGraphRepository } from '@core/social/domain/repositories/ISocialGraphRepository';
import { Driver } from '../../domain/entities/Driver';
import type { UseCaseOutputPort } from '@core/shared/application';

describe('GetProfileOverviewUseCase', () => {
  let useCase: GetProfileOverviewUseCase;
  let driverRepository: {
    findById: Mock;
  };
  let teamRepository: {
    findAll: Mock;
  };
  let teamMembershipRepository: {
    getMembership: Mock;
  };
  let socialRepository: {
    getFriends: Mock;
  };
  let driverStatsUseCase: {
    getDriverStats: Mock;
  };
  let rankingUseCase: {
    getAllDriverRankings: Mock;
  };
  let driverExtendedProfileProvider: {
    getExtendedProfile: Mock;
  };
  let output: UseCaseOutputPort<GetProfileOverviewResult> & { present: Mock };

  beforeEach(() => {
    driverRepository = {
      findById: vi.fn(),
    };

    teamRepository = {
      findAll: vi.fn(),
    };

    teamMembershipRepository = {
      getMembership: vi.fn(),
    };

    socialRepository = {
      getFriends: vi.fn(),
    };

    driverStatsUseCase = {
      getDriverStats: vi.fn(),
    };

    rankingUseCase = {
      getAllDriverRankings: vi.fn(),
    };

    driverExtendedProfileProvider = {
      getExtendedProfile: vi.fn(),
    };

    output = {
      present: vi.fn(),
    } as unknown as UseCaseOutputPort<GetProfileOverviewResult> & { present: Mock };

    useCase = new GetProfileOverviewUseCase(
      driverRepository as unknown as IDriverRepository,
      teamRepository as unknown as ITeamRepository,
      teamMembershipRepository as unknown as ITeamMembershipRepository,
      socialRepository as unknown as ISocialGraphRepository,
      driverExtendedProfileProvider,
      driverStatsUseCase as unknown as any,
      rankingUseCase as unknown as any,
      output,
    );
  });

  it('should return profile overview for existing driver', async () => {
    const driverId = 'driver-1';
    const driver = Driver.create({
      id: driverId,
      iracingId: '12345',
      name: 'Test Driver',
      country: 'US',
      joinedAt: new Date('2023-01-01'),
    });

    driverRepository.findById.mockResolvedValue(driver);
    driverStatsUseCase.getDriverStats.mockResolvedValue({
      rating: 1500,
      wins: 5,
      podiums: 10,
      dnfs: 2,
      totalRaces: 20,
      avgFinish: 8.5,
      bestFinish: 1,
      worstFinish: 15,
      overallRank: 50,
      consistency: 85,
    });
    rankingUseCase.getAllDriverRankings.mockResolvedValue([
      { driverId: 'driver-1', rating: 1500, wins: 5, totalRaces: 20, overallRank: 50 },
      { driverId: 'driver-2', rating: 1400, wins: 3, totalRaces: 18, overallRank: 75 },
    ]);
    teamRepository.findAll.mockResolvedValue([]);
    socialRepository.getFriends.mockResolvedValue([]);
    driverExtendedProfileProvider.getExtendedProfile.mockReturnValue({
      bio: 'Test bio',
      location: 'Test location',
      favoriteTrack: 'Test track',
    });

    const result = await useCase.execute({ driverId });

    expect(result.isOk()).toBe(true);
    expect(output.present).toHaveBeenCalled();
  });
});
