import type {
  GetProfileOverviewResult,
} from '@core/racing/application/use-cases/GetProfileOverviewUseCase';
import type { GetDriverProfileOutputDTO } from '../dtos/GetDriverProfileOutputDTO';
import type { DriverProfileExtendedProfileDTO } from '../dtos/DriverProfileExtendedProfileDTO';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import { MediaReference } from '@core/domain/media/MediaReference';

export class DriverProfilePresenter {
  private responseModel: GetDriverProfileOutputDTO | null = null;
  private mediaResolver: MediaResolverPort | undefined;

  constructor(mediaResolver?: MediaResolverPort) {
    this.mediaResolver = mediaResolver;
  }

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

  async present(result: GetProfileOverviewResult): Promise<void> {
    // Resolve current driver avatar
    let currentDriverAvatarUrl: string | null = null;
    if (this.mediaResolver && result.driverInfo?.driver.avatarRef) {
      const ref = result.driverInfo.driver.avatarRef instanceof MediaReference
        ? result.driverInfo.driver.avatarRef
        : MediaReference.fromJSON(result.driverInfo.driver.avatarRef);
      currentDriverAvatarUrl = await this.mediaResolver.resolve(ref);
    }

    // Resolve friend avatars
    let friendAvatars: Record<string, string | null> = {};
    if (this.mediaResolver) {
      for (const friend of result.socialSummary.friends) {
        const ref = friend.avatarRef instanceof MediaReference
          ? friend.avatarRef
          : MediaReference.fromJSON(friend.avatarRef);
        friendAvatars[friend.id] = await this.mediaResolver.resolve(ref);
      }
    }

    this.responseModel = {
      currentDriver: result.driverInfo
        ? {
            id: result.driverInfo.driver.id,
            name: result.driverInfo.driver.name.toString(),
            country: result.driverInfo.driver.country.toString(),
            avatarUrl: currentDriverAvatarUrl,
            iracingId: result.driverInfo.driver.iracingId.toString(),
            joinedAt: result.driverInfo.driver.joinedAt.toDate().toISOString(),
            category: result.driverInfo.driver.category || null,
            rating: result.driverInfo.rating,
            globalRank: result.driverInfo.globalRank,
            consistency: result.driverInfo.consistency,
            bio: result.driverInfo.driver.bio?.toString() || null,
            totalDrivers: result.driverInfo.totalDrivers,
          }
        : null,
      stats: result.stats,
      finishDistribution: result.finishDistribution,
      teamMemberships: result.teamMemberships.map(membership => ({
        teamId: membership.team.id,
        teamName: membership.team.name.toString(),
        teamTag: membership.team.tag.toString(),
        role: membership.membership.role,
        joinedAt: membership.membership.joinedAt.toISOString(),
        isCurrent: true, // TODO: check membership status
      })),
      socialSummary: {
        friendsCount: result.socialSummary.friendsCount,
        friends: result.socialSummary.friends.map(friend => ({
          id: friend.id,
          name: friend.name.toString(),
          country: friend.country.toString(),
          avatarUrl: friendAvatars[friend.id] ?? null,
        })),
      },
      extendedProfile: result.extendedProfile as DriverProfileExtendedProfileDTO | null,
    };
  }

  getResponseModel(): GetDriverProfileOutputDTO {
    if (!this.responseModel) throw new Error('Presenter not presented');
    return this.responseModel;
  }
}