import { useQuery } from '@tanstack/react-query'
import { usePreferencesStore } from '../stores/preferences-store'
import {
  tvmazeLookupByImdbId,
  tvmazeLookupByTvdbId,
  tvmazeShow,
} from '../api/tvmaze'
import { wikipediaResolve, wikipediaSection, wikipediaSummary } from '../api/wikipedia'
import { cinemetaMovie, cinemetaSeries } from '../api/cinemeta'
import { fanartMovie, fanartTv } from '../api/fanart'
import { getAwards, getAwardWinners, getFilmingLocations } from '../api/wikidata'
import { getMovieRating as rtMovie, getTvRating as rtTv } from '../api/rotten-tomatoes'

/**
 * React Query hooks for all the keyless / single-key external sources we
 * pull. Each is independent and silently no-ops when the input id is missing
 * or the source returns nothing - callers can chain them without guarding.
 */

const DAY = 24 * 60 * 60 * 1000

/* ── TVmaze ─────────────────────────────────────────────────── */

export function useTvmazeByImdbId(imdbId?: string | null) {
  return useQuery({
    queryKey: ['tvmaze', 'imdb', imdbId],
    queryFn: () => (imdbId ? tvmazeLookupByImdbId(imdbId) : null),
    enabled: !!imdbId,
    staleTime: DAY,
  })
}

export function useTvmazeByTvdbId(tvdbId?: string | number | null) {
  return useQuery({
    queryKey: ['tvmaze', 'tvdb', tvdbId],
    queryFn: () => (tvdbId ? tvmazeLookupByTvdbId(tvdbId) : null),
    enabled: !!tvdbId,
    staleTime: DAY,
  })
}

export function useTvmazeShow(id?: number | null) {
  return useQuery({
    queryKey: ['tvmaze', 'show', id],
    queryFn: () => (id ? tvmazeShow(id) : null),
    enabled: !!id,
    staleTime: DAY,
  })
}

/* ── Wikipedia ──────────────────────────────────────────────── */

export function useWikiSummary(title?: string | null) {
  return useQuery({
    queryKey: ['wiki', 'summary', title],
    queryFn: () => (title ? wikipediaSummary(title) : null),
    enabled: !!title,
    staleTime: 7 * DAY,
  })
}

/**
 * Resolves a free-text query (movie/show/person name) to a Wikipedia
 * article and returns its lead summary. Used when we don't already have
 * a known article title.
 */
export function useWikiResolve(query?: string | null, enabled = true) {
  return useQuery({
    queryKey: ['wiki', 'resolve', query],
    queryFn: () => (query ? wikipediaResolve(query) : null),
    enabled: !!query && enabled,
    staleTime: 7 * DAY,
  })
}

/**
 * Pull a specific top-level section's plain text from a Wikipedia article.
 * Used by the "Production trivia" block on detail pages, which surfaces
 * the article's "Production" section when present.
 */
export function useWikiSection(title?: string | null, sectionName?: string | null) {
  return useQuery({
    queryKey: ['wiki', 'section', title, sectionName],
    queryFn: () => (title && sectionName ? wikipediaSection(title, sectionName) : null),
    enabled: !!title && !!sectionName,
    staleTime: 7 * DAY,
  })
}

/* ── Wikidata (SPARQL) ──────────────────────────────────────── */

export function useWikidataAwards(qid?: string | null) {
  return useQuery({
    queryKey: ['wikidata', 'awards', qid],
    queryFn: () => (qid ? getAwards(qid) : []),
    enabled: !!qid,
    staleTime: 7 * DAY,
  })
}

export function useWikidataLocations(qid?: string | null) {
  return useQuery({
    queryKey: ['wikidata', 'locations', qid],
    queryFn: () => (qid ? getFilmingLocations(qid) : []),
    enabled: !!qid,
    staleTime: 7 * DAY,
  })
}

/**
 * All winners of the given award (Wikidata Q-id) with TMDB cross-refs
 * when available. Used by the "Award winners you're missing" home row.
 */
export function useWikidataAwardWinners(awardQid?: string | null) {
  return useQuery({
    queryKey: ['wikidata', 'award-winners', awardQid],
    queryFn: () => (awardQid ? getAwardWinners(awardQid) : []),
    enabled: !!awardQid,
    staleTime: 30 * DAY,
  })
}

/* ── Cinemeta (IMDB-style fallback) ─────────────────────────── */

export function useCinemeta(imdbId?: string | null, type?: 'movie' | 'series') {
  return useQuery({
    queryKey: ['cinemeta', type, imdbId],
    queryFn: () => {
      if (!imdbId || !type) return null
      return type === 'movie' ? cinemetaMovie(imdbId) : cinemetaSeries(imdbId)
    },
    enabled: !!imdbId && !!type,
    staleTime: DAY,
  })
}

/* ── Key-gated services (TMDB, Fanart.tv) ────────────────────── */

const BUILT_IN_TMDB_KEY_X = (import.meta.env.VITE_TMDB_API_KEY || '').trim()
const BUILT_IN_FANART_KEY = (import.meta.env.VITE_FANART_API_KEY || '').trim()

function effectiveFanartKey(userKey: string): string {
  return userKey || BUILT_IN_FANART_KEY
}

/**
 * Reactive: returns true when ANY TMDB key is available (user override
 * in prefs, mirror entry in localStorage, or build-time default). The
 * UI uses this to hide TMDB-dependent rows entirely so the user never
 * sees an empty "Trending today" header with no content underneath.
 */
export function useHasTmdbKey(): boolean {
  const userKey = usePreferencesStore(s => s.tmdbApiKey)
  if (userKey) return true
  try {
    if (localStorage.getItem('jf_tmdb_key')) return true
  } catch { /* ignore */ }
  return !!BUILT_IN_TMDB_KEY_X
}

export function useHasFanartKey(): boolean {
  const userKey = usePreferencesStore(s => s.fanartApiKey)
  return !!userKey || !!BUILT_IN_FANART_KEY
}

export function useFanartMovie(idTmdbOrImdb?: string | null) {
  const userKey = usePreferencesStore(s => s.fanartApiKey)
  const apiKey = effectiveFanartKey(userKey)
  return useQuery({
    queryKey: ['fanart', 'movie', idTmdbOrImdb, apiKey],
    queryFn: () => (idTmdbOrImdb && apiKey ? fanartMovie(idTmdbOrImdb, apiKey) : null),
    enabled: !!idTmdbOrImdb && !!apiKey,
    staleTime: 3 * DAY,
  })
}

export function useFanartTv(tvdbId?: string | null) {
  const userKey = usePreferencesStore(s => s.fanartApiKey)
  const apiKey = effectiveFanartKey(userKey)
  return useQuery({
    queryKey: ['fanart', 'tv', tvdbId, apiKey],
    queryFn: () => (tvdbId && apiKey ? fanartTv(tvdbId, apiKey) : null),
    enabled: !!tvdbId && !!apiKey,
    staleTime: 3 * DAY,
  })
}

/* ── Rotten Tomatoes (private Algolia, no key required) ───── */

export function useRottenTomatoes(
  name?: string | null,
  year?: number | null,
  kind?: 'movie' | 'tv' | null,
) {
  return useQuery({
    queryKey: ['rt', kind, name, year],
    queryFn: () =>
      name && kind
        ? kind === 'movie'
          ? rtMovie(name, year || undefined)
          : rtTv(name, year || undefined)
        : null,
    enabled: !!name && !!kind,
    staleTime: 7 * DAY,
  })
}
