/**
 * TVmaze REST client. No API key required and no rate limit advertised.
 * Source: https://www.tvmaze.com/api
 *
 * Useful endpoints:
 *   - /lookup/shows?imdb=ttXXXXX           lookup by IMDB id (best match for our flow)
 *   - /lookup/shows?thetvdb=NNNNN          lookup by TVDB id
 *   - /shows/{id}?embed[]=...              detail with cast/episodes/seasons/network
 *   - /shows/{id}/episodes                 ordered episode list
 *   - /shows/{id}/episodebynumber?...      single episode by S/E
 *   - /schedule/web?country=US&date=...    streaming schedule
 *
 * Fields we actually surface: network name + logo + country, schedule
 * (`days` + `time`), official site, runtime, status, summary (HTML), and
 * `previousepisode` / `nextepisode` air dates.
 */

const BASE_URL = 'https://api.tvmaze.com'

export interface TvmazeNetwork {
  id: number
  name: string
  country?: { name: string; code: string; timezone: string }
  officialSite?: string | null
}

export interface TvmazeSchedule {
  time?: string
  days?: string[]
}

export interface TvmazeImage {
  medium?: string
  original?: string
}

export interface TvmazeShow {
  id: number
  url: string
  name: string
  type?: string
  language?: string
  genres?: string[]
  status?: string
  runtime?: number | null
  averageRuntime?: number | null
  premiered?: string | null
  ended?: string | null
  officialSite?: string | null
  schedule?: TvmazeSchedule
  rating?: { average: number | null }
  network?: TvmazeNetwork | null
  webChannel?: TvmazeNetwork | null
  image?: TvmazeImage | null
  summary?: string | null
  externals?: { tvrage?: number | null; thetvdb?: number | null; imdb?: string | null }
  _embedded?: {
    cast?: TvmazeCastMember[]
    episodes?: TvmazeEpisode[]
    nextepisode?: TvmazeEpisode | null
    previousepisode?: TvmazeEpisode | null
  }
}

export interface TvmazeCastMember {
  person: { id: number; name: string; image?: TvmazeImage }
  character: { id: number; name: string; image?: TvmazeImage }
}

export interface TvmazeEpisode {
  id: number
  name: string
  season: number
  number: number | null
  type?: string
  airdate?: string | null
  airtime?: string | null
  runtime?: number | null
  image?: TvmazeImage | null
  summary?: string | null
}

async function fetchJson<T>(path: string): Promise<T | null> {
  try {
    const res = await fetch(`${BASE_URL}${path}`)
    if (!res.ok) return null
    return (await res.json()) as T
  } catch {
    return null
  }
}

export function tvmazeLookupByImdbId(imdbId: string): Promise<TvmazeShow | null> {
  if (!imdbId) return Promise.resolve(null)
  return fetchJson<TvmazeShow>(`/lookup/shows?imdb=${encodeURIComponent(imdbId)}`)
}

export function tvmazeLookupByTvdbId(tvdbId: string | number): Promise<TvmazeShow | null> {
  if (!tvdbId) return Promise.resolve(null)
  return fetchJson<TvmazeShow>(`/lookup/shows?thetvdb=${tvdbId}`)
}

export function tvmazeShow(id: number, embed: string[] = ['cast', 'nextepisode', 'previousepisode']): Promise<TvmazeShow | null> {
  if (!id) return Promise.resolve(null)
  const embeds = embed.map(e => `embed[]=${e}`).join('&')
  return fetchJson<TvmazeShow>(`/shows/${id}?${embeds}`)
}

export function tvmazeStripHtml(s: string | null | undefined): string {
  if (!s) return ''
  return s.replace(/<[^>]+>/g, '').trim()
}
