import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import type { GetAllLeaguesWithCapacityAndScoringResult } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityAndScoringUseCase';
import type {
  AllLeaguesWithCapacityAndScoringDTO,
  LeagueWithCapacityAndScoringDTO,
} from '../dtos/AllLeaguesWithCapacityAndScoringDTO';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import { MediaReference } from '@core/domain/media/MediaReference';

export class AllLeaguesWithCapacityAndScoringPresenter
  implements UseCaseOutputPort<GetAllLeaguesWithCapacityAndScoringResult>
{
  private result: AllLeaguesWithCapacityAndScoringDTO | null = null;
  private mediaResolver?: MediaResolverPort;

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

  async present(result: GetAllLeaguesWithCapacityAndScoringResult): Promise<void> {
    const leagues: LeagueWithCapacityAndScoringDTO[] = await Promise.all(
      result.leagues.map(async (summary) => {
        const timingSummary = summary.preset
          ? formatTimingSummary(summary.preset.defaultTimings.mainRaceMinutes)
          : undefined;

        // Resolve logo URL
        let logoUrl: string | null | undefined;
        if (summary.league.logoRef) {
          const ref = summary.league.logoRef instanceof MediaReference 
            ? summary.league.logoRef 
            : MediaReference.fromJSON(summary.league.logoRef);
          
          if (this.mediaResolver) {
            logoUrl = await this.mediaResolver.resolve(ref);
          } else {
            // Fallback to manual construction
            if (ref.type === 'generated' && ref.generationRequestId) {
              const requestId = ref.generationRequestId;
              const firstHyphenIndex = requestId.indexOf('-');
              if (firstHyphenIndex !== -1) {
                const type = requestId.substring(0, firstHyphenIndex);
                const id = requestId.substring(firstHyphenIndex + 1);
                
                if (type === 'league') {
                  logoUrl = `/media/leagues/${id}/logo`;
                }
              }
            } else if (ref.type === 'uploaded' && ref.mediaId) {
              logoUrl = `/media/uploaded/${ref.mediaId}`;
            } else if (ref.type === 'system-default') {
              logoUrl = null;
            }
          }
        }

        return {
          id: summary.league.id.toString(),
          name: summary.league.name.toString(),
          description: summary.league.description?.toString() || '',
          ownerId: summary.league.ownerId.toString(),
          createdAt: summary.league.createdAt.toDate().toISOString(),
          settings: {
            maxDrivers: summary.maxDrivers,
            ...(summary.league.settings.sessionDuration !== undefined
              ? { sessionDuration: summary.league.settings.sessionDuration }
              : {}),
            ...(summary.league.settings.qualifyingFormat !== undefined
              ? { qualifyingFormat: summary.league.settings.qualifyingFormat.toString() }
              : {}),
          },
          usedSlots: summary.currentDrivers,
          ...(summary.league.category ? { category: summary.league.category } : {}),
          ...mapSocialLinks(summary.league.socialLinks),
          ...(summary.scoringConfig && summary.game && summary.preset
            ? {
                scoring: {
                  gameId: summary.game.id.toString(),
                  gameName: summary.game.name.toString(),
                  primaryChampionshipType: summary.preset.primaryChampionshipType,
                  scoringPresetId: summary.scoringConfig.scoringPresetId?.toString() ?? 'custom',
                  scoringPresetName: summary.preset.name,
                  dropPolicySummary: summary.preset.dropPolicySummary,
                  scoringPatternSummary: summary.preset.sessionSummary,
                },
              }
            : {}),
        ...(timingSummary ? { timingSummary } : {}),
        ...(logoUrl !== undefined ? { logoUrl } : {}),
        };
      })
    );

    this.result = {
      leagues,
      totalCount: leagues.length,
    };
  }

  getViewModel(): AllLeaguesWithCapacityAndScoringDTO {
    if (!this.result) throw new Error('Presenter not presented');
    return this.result;
  }
}

function formatTimingSummary(mainRaceMinutes: number): string {
  if (!Number.isFinite(mainRaceMinutes) || mainRaceMinutes <= 0) return '';

  if (mainRaceMinutes >= 60 && mainRaceMinutes % 60 === 0) {
    return `${mainRaceMinutes / 60}h Race`;
  }

  return `${mainRaceMinutes}m Race`;
}

type SocialLinksInput = {
  discordUrl?: string | undefined;
  youtubeUrl?: string | undefined;
  websiteUrl?: string | undefined;
};

type SocialLinksOutput = {
  discordUrl?: string;
  youtubeUrl?: string;
  websiteUrl?: string;
};

function mapSocialLinks(socialLinks: SocialLinksInput | undefined): { socialLinks: SocialLinksOutput } | {} {
  if (!socialLinks) return {};

  const mapped: SocialLinksOutput = {
    ...(socialLinks.discordUrl ? { discordUrl: socialLinks.discordUrl } : {}),
    ...(socialLinks.youtubeUrl ? { youtubeUrl: socialLinks.youtubeUrl } : {}),
    ...(socialLinks.websiteUrl ? { websiteUrl: socialLinks.websiteUrl } : {}),
  };

  return Object.keys(mapped).length > 0 ? { socialLinks: mapped } : {};
}