import { DriversApiClient } from '@/lib/api/drivers/DriversApiClient';
import type { CompleteOnboardingInputDTO } from '@/lib/types/generated/CompleteOnboardingInputDTO';
import type { GetDriverOutputDTO } from '@/lib/types/generated/GetDriverOutputDTO';
import { CompleteOnboardingViewModel } from "@/lib/view-models/CompleteOnboardingViewModel";
import { DriverLeaderboardViewModel } from "@/lib/view-models/DriverLeaderboardViewModel";
import { DriverViewModel } from "@/lib/view-models/DriverViewModel";
import { DriverProfileViewModel } from "@/lib/view-models/DriverProfileViewModel";

/**
 * Driver Service
 *
 * Orchestrates driver operations by coordinating API calls and view model creation.
 * All dependencies are injected via constructor.
 */
export class DriverService {
  constructor(
    private readonly apiClient: DriversApiClient
  ) {}

  /**
   * Get driver leaderboard with view model transformation
   */
  async getDriverLeaderboard(): Promise<DriverLeaderboardViewModel> {
    const dto = await this.apiClient.getLeaderboard();
    return new DriverLeaderboardViewModel(dto);
  }

  /**
   * Complete driver onboarding with view model transformation
   */
  async completeDriverOnboarding(input: CompleteOnboardingInputDTO): Promise<CompleteOnboardingViewModel> {
    const dto = await this.apiClient.completeOnboarding(input);
    return new CompleteOnboardingViewModel(dto);
  }

  /**
    * Get current driver with view model transformation
    */
  async getCurrentDriver(): Promise<DriverViewModel | null> {
    const dto = await this.apiClient.getCurrent();
    if (!dto) {
      return null;
    }
    return new DriverViewModel({ ...dto, avatarUrl: (dto as any).avatarUrl ?? null });
  }

  /**
    * Get driver profile with full details and view model transformation
    */
  async getDriverProfile(driverId: string): Promise<DriverProfileViewModel> {
    const dto = await this.apiClient.getDriverProfile(driverId);
    return new DriverProfileViewModel({
      currentDriver: dto.currentDriver
        ? {
            id: dto.currentDriver.id,
            name: dto.currentDriver.name,
            country: dto.currentDriver.country,
            avatarUrl: dto.currentDriver.avatarUrl || '',
            iracingId: dto.currentDriver.iracingId ?? null,
            joinedAt: dto.currentDriver.joinedAt,
            rating: dto.currentDriver.rating ?? null,
            globalRank: dto.currentDriver.globalRank ?? null,
            consistency: dto.currentDriver.consistency ?? null,
            bio: dto.currentDriver.bio ?? null,
            totalDrivers: dto.currentDriver.totalDrivers ?? null,
          }
        : null,
      stats: dto.stats
        ? {
            totalRaces: dto.stats.totalRaces,
            wins: dto.stats.wins,
            podiums: dto.stats.podiums,
            dnfs: dto.stats.dnfs,
            avgFinish: dto.stats.avgFinish ?? null,
            bestFinish: dto.stats.bestFinish ?? null,
            worstFinish: dto.stats.worstFinish ?? null,
            finishRate: dto.stats.finishRate ?? null,
            winRate: dto.stats.winRate ?? null,
            podiumRate: dto.stats.podiumRate ?? null,
            percentile: dto.stats.percentile ?? null,
            rating: dto.stats.rating ?? null,
            consistency: dto.stats.consistency ?? null,
            overallRank: dto.stats.overallRank ?? null,
          }
        : null,
      finishDistribution: dto.finishDistribution
        ? {
            totalRaces: dto.finishDistribution.totalRaces,
            wins: dto.finishDistribution.wins,
            podiums: dto.finishDistribution.podiums,
            topTen: dto.finishDistribution.topTen,
            dnfs: dto.finishDistribution.dnfs,
            other: dto.finishDistribution.other,
          }
        : null,
      teamMemberships: dto.teamMemberships.map((m) => ({
        teamId: m.teamId,
        teamName: m.teamName,
        teamTag: m.teamTag ?? null,
        role: m.role,
        joinedAt: m.joinedAt,
        isCurrent: m.isCurrent,
      })),
      socialSummary: {
        friendsCount: dto.socialSummary.friendsCount,
        friends: dto.socialSummary.friends.map((f) => ({
          id: f.id,
          name: f.name,
          country: f.country,
          avatarUrl: f.avatarUrl || '',
        })),
      },
      extendedProfile: dto.extendedProfile
        ? {
            socialHandles: dto.extendedProfile.socialHandles.map((h) => ({
              platform: h.platform as any,
              handle: h.handle,
              url: h.url,
            })),
            achievements: dto.extendedProfile.achievements.map((a) => ({
              id: a.id,
              title: a.title,
              description: a.description,
              icon: a.icon as any,
              rarity: a.rarity as any,
              earnedAt: a.earnedAt,
            })),
            racingStyle: dto.extendedProfile.racingStyle,
            favoriteTrack: dto.extendedProfile.favoriteTrack,
            favoriteCar: dto.extendedProfile.favoriteCar,
            timezone: dto.extendedProfile.timezone,
            availableHours: dto.extendedProfile.availableHours,
            lookingForTeam: dto.extendedProfile.lookingForTeam,
            openToRequests: dto.extendedProfile.openToRequests,
          }
        : null,
    });
  }

  /**
    * Update current driver profile with view model transformation
    */
   async updateProfile(updates: { bio?: string; country?: string }): Promise<DriverProfileViewModel> {
     const dto = await this.apiClient.updateProfile(updates);
     // After updating, get the full profile again to return updated view model
     return this.getDriverProfile(dto.id);
   }

  /**
   * Find driver by ID
   */
  async findById(id: string): Promise<GetDriverOutputDTO | null> {
    return this.apiClient.getDriver(id);
  }

  /**
   * Find multiple drivers by IDs
   */
  async findByIds(ids: string[]): Promise<GetDriverOutputDTO[]> {
    const drivers = await Promise.all(ids.map(id => this.apiClient.getDriver(id)));
    return drivers.filter((d): d is GetDriverOutputDTO => d !== null);
  }
}
