import type { BaseItemDto } from '../api/types'
import type { CinemetaEpisode } from '../api/cinemeta'
import type { TmdbCastMember, TmdbEpisode } from '../api/tmdb'
import type { FillerFlag } from './anime-filler'

/**
 * Combined view of a Jellyfin episode plus enrichments from external
 * sources (Cinemeta IMDB rating, TMDB per-episode credits, anime-filler
 * classification). Components render from this normalised shape so they
 * don't have to juggle three sources.
 */
export interface EnrichedEpisode {
  jf: BaseItemDto
  imdbRating: number | null
  imdbId: string | null
  guestStars: TmdbCastMember[]
  director: TmdbCastMember | null
  writer: TmdbCastMember | null
  fillerFlag: FillerFlag
}

/** Parse Cinemeta's stringy rating, return null on garbage. */
export function parseImdbRating(raw: string | undefined | null): number | null {
  if (!raw) return null
  const n = Number(raw)
  return Number.isFinite(n) && n > 0 ? n : null
}

/**
 * Build the EnrichedEpisode for a single Jellyfin episode. All inputs are
 * optional - missing pieces just produce nulls / empty arrays.
 */
export function deriveEpisodeMeta(
  jf: BaseItemDto,
  cinemetaEpisode: CinemetaEpisode | null | undefined,
  tmdbEpisode: TmdbEpisode | null | undefined,
  fillerFlag: FillerFlag,
): EnrichedEpisode {
  const credits = tmdbEpisode?.credits
  // Episode-level credits come back with `cast` (regulars) + `guest_stars`.
  // We surface a unified "featured cast" from guest_stars first, then any
  // cast members not present in the show's main ensemble. The filtering
  // against the main ensemble happens at the consuming component.
  const guests = (credits?.cast || []).slice(0, 8)
  const crew = credits?.crew || []
  const director = crew.find(c => c.job === 'Director') || null
  const writer = crew.find(
    c => c.job === 'Writer' || c.job === 'Screenplay',
  ) || null

  return {
    jf,
    imdbRating: parseImdbRating(cinemetaEpisode?.imdbRating),
    imdbId: cinemetaEpisode?.imdb_id || tmdbEpisode?.external_ids?.imdb_id || null,
    guestStars: guests,
    director: director as TmdbCastMember | null,
    writer: writer as TmdbCastMember | null,
    fillerFlag,
  }
}
