import { MediaReference } from '@core/domain/media/MediaReference';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import type { Driver } from '@core/racing/domain/entities/Driver';
import type { DriverStatsRepository } from '@core/racing/domain/repositories/DriverStatsRepository';
import { Result } from '@core/shared/domain/Result';
import type { GetDriverOutputDTO } from '../dtos/GetDriverOutputDTO';

export class DriverPresenter {
  private responseModel: GetDriverOutputDTO | null = null;
  private mediaResolver: MediaResolverPort | undefined;

  constructor(
    private readonly driverStatsRepository: DriverStatsRepository,
    mediaResolver?: MediaResolverPort
  ) {
    this.mediaResolver = mediaResolver;
  }

  setMediaResolver(resolver: MediaResolverPort | undefined): void {
    this.mediaResolver = resolver;
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  async present(result: Result<Driver | null, any>): Promise<void> {
    if (result.isErr()) {
      const error = result.unwrapErr();
      throw new Error(error.details?.message ?? 'Failed to get driver');
    }

    const driver = result.unwrap();
    if (!driver) {
      this.responseModel = null;
      return;
    }

    // Get stats from repository (synchronously for now, could be async)
    const stats = this.driverStatsRepository.getDriverStatsSync(driver.id);

    // Resolve avatar URL using MediaResolverPort
    let avatarUrl: string | null = null;
    if (this.mediaResolver) {
      const ref = driver.avatarRef ?? MediaReference.createNone();
      const resolvedRef = ref instanceof MediaReference ? ref : MediaReference.fromJSON(ref);
      const resolvedUrl = await this.mediaResolver.resolve(resolvedRef);
      avatarUrl = resolvedUrl ?? null;
    }

    const dto: GetDriverOutputDTO = {
      id: driver.id,
      iracingId: driver.iracingId.toString(),
      name: driver.name.toString(),
      country: driver.country.toString(),
      joinedAt: driver.joinedAt.toDate().toISOString(),
      avatarUrl,
      ...(driver.bio ? { bio: driver.bio.toString() } : {}),
      ...(driver.category ? { category: driver.category } : {}),
      // Add stats fields
      ...(stats ? {
        rating: stats.rating,
        wins: stats.wins,
        podiums: stats.podiums,
        totalRaces: stats.totalRaces,
        experienceLevel: this.getExperienceLevel(stats.rating),
      } : {}),
    };

    this.responseModel = dto;
  }

  getResponseModel(): GetDriverOutputDTO | null {
    return this.responseModel;
  }

  private getExperienceLevel(rating: number): string {
    if (rating >= 1700) return 'veteran';
    if (rating >= 1300) return 'advanced';
    if (rating >= 1000) return 'intermediate';
    return 'beginner';
  }
}