import { useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { motion } from 'framer-motion'
import {
  ArrowLeft, Clock, Star, Calendar, ExternalLink, Globe, Library,
} from '../lib/icons'
import { useTmdbDetailEnrichment } from '../hooks/use-tmdb-detail'
import { useLibraryByTmdbId } from '../hooks/use-jellyfin'
import { useFanartMovie, useFanartTv } from '../hooks/use-external'
import { getTmdbImageUrl, pickTmdbLogo } from '../api/tmdb'
import type { TmdbMovie, TmdbTvShow } from '../api/tmdb'
import { pickBestFanartImage } from '../api/fanart'
import { mapTmdbToJf } from '../lib/tmdb-mapping'
import ContentRow from '../components/ui/ContentRow'
import CrewGrid from '../components/detail/CrewGrid'
import ComposerBlock from '../components/detail/ComposerBlock'
import VideosSection from '../components/detail/VideosSection'
import AwardsBlock from '../components/detail/AwardsBlock'
import ProductionTrivia from '../components/detail/ProductionTrivia'
import FilmingLocationsMap from '../components/detail/FilmingLocationsMap'
import CollectionStrip from '../components/detail/CollectionStrip'
import ReadingMode from '../components/detail/ReadingMode'
import DetailStickyBar from '../components/detail/DetailStickyBar'
import { usePastSentinel } from '../hooks/use-past-sentinel'
import RequestButton from '../components/request/RequestButton'
import AvailabilityChip from '../components/ui/AvailabilityChip'
import HorizontalScroller from '../components/ui/HorizontalScroller'

interface Props {
  tmdbId: number
  kind: 'movie' | 'tv'
}

/**
 * Detail page for items the user does NOT have in their library. We
 * render purely from TMDB metadata so users can browse missing canon,
 * recommendations, awards-row picks, etc. without hitting Jellyfin.
 *
 * Mirrors the local DetailPage's chrome where it makes sense (cast,
 * crew, videos, awards, trivia) but drops sections that need a local
 * file (Play, Resume, Personal, Diary, Episodes list). The primary
 * action becomes Request when *arr is configured.
 */
export default function TmdbDetailPage({ tmdbId, kind }: Props) {
  const navigate = useNavigate()
  const { sentinelRef: stickySentinelRef, past: pastHero } = usePastSentinel()
  const enrichment = useTmdbDetailEnrichment({ kind, tmdbId })
  const { data, isLoading, collection: tmdbCollection, awards: awardsQuery, locations: locationsQuery, wikiProduction: wikiProductionQuery } = enrichment

  const libraryByTmdbId = useLibraryByTmdbId()

  // Logo source priority: fanart.tv (cleaner art, typically transparent
  // PNG wordmarks) → TMDB logos. Mirrors the library DetailHero's chain
  // (jellyfin → fanart) but without the jellyfin source since this page
  // exists precisely for items not in the library.
  const tvdbId = enrichment.data?.external_ids?.tvdb_id
  const fanartMovieQuery = useFanartMovie(kind === 'movie' ? String(tmdbId) : null)
  const fanartTvQuery = useFanartTv(kind === 'tv' && tvdbId ? String(tvdbId) : null)
  const fanartLogo = pickBestFanartImage(
    kind === 'movie'
      ? fanartMovieQuery.data?.hdmovielogo || fanartMovieQuery.data?.movielogo
      : fanartTvQuery.data?.hdtvlogo || fanartTvQuery.data?.clearlogo,
  )
  const tmdbLogo = pickTmdbLogo(enrichment.data?.images?.logos)
  const logoUrl =
    fanartLogo?.url ||
    (tmdbLogo ? getTmdbImageUrl(tmdbLogo.file_path, 'w500') : null)

  const [readingModeOpen, setReadingModeOpen] = useState(false)

  // Library cross-reference: did the item get pulled into Jellyfin since
  // we landed on this page? If so, offer a "View in your library" button.
  const matchedLocal = libraryByTmdbId.data?.get(String(tmdbId)) || null

  // Recommendations + similar rows (cross-referenced with library so
  // already-owned items get the In Library indicator).
  const recommendations = useMemo(() => {
    const list = data?.recommendations?.results || []
    return mapTmdbToJf(list.slice(0, 18), libraryByTmdbId.data)
  }, [data, libraryByTmdbId.data])
  const similar = useMemo(() => {
    const list = data?.similar?.results || []
    return mapTmdbToJf(list.slice(0, 18), libraryByTmdbId.data)
  }, [data, libraryByTmdbId.data])

  if (isLoading) {
    return <Skeleton />
  }
  if (!data) {
    return (
      <div className="flex flex-col items-center justify-center min-h-[60vh] text-center px-6">
        <p className="text-[15px] text-text-1 font-medium mb-1.5">No TMDB record</p>
        <p className="text-[12px] text-text-3 max-w-md leading-relaxed mb-5">
          We couldn't load metadata for this title. It may have been removed from TMDB.
        </p>
        <button
          onClick={() => navigate(-1)}
          className="inline-flex items-center gap-2 h-10 px-4 rounded-full bg-elevated/60 ring-1 ring-border hover:ring-border-strong text-[12px] text-text-2 hover:text-text-1 transition focus-ring"
        >
          <ArrowLeft size={12} stroke={2} />
          Back
        </button>
      </div>
    )
  }

  const title = data.title || data.name || ''
  const year = (data.release_date || data.first_air_date || '').slice(0, 4)
  const runtime = kind === 'movie'
    ? data.runtime
    : data.episode_run_time?.[0]
  const overview = data.overview || ''
  const tagline = data.tagline
  const genres = data.genres || []
  const community = data.vote_average
  const certification = (() => {
    if (kind === 'movie') {
      const us = data.release_dates?.results?.find(r => r.iso_3166_1 === 'US')
      return us?.release_dates?.find(d => d.certification)?.certification
    }
    return data.content_ratings?.results?.find(r => r.iso_3166_1 === 'US')?.rating
  })()
  const credits = data.credits
  const cast = (credits?.cast || []).slice(0, 18)
  const crew = credits?.crew || []
  const backdrop = data.backdrop_path
    ? getTmdbImageUrl(data.backdrop_path, 'original')
    : null
  const poster = data.poster_path
    ? getTmdbImageUrl(data.poster_path, 'w500')
    : null
  const tmdbWatchUrl = `https://www.themoviedb.org/${kind === 'movie' ? 'movie' : 'tv'}/${tmdbId}`
  const keywords = (data.keywords?.keywords || data.keywords?.results || []) as Array<{ id: number; name: string }>

  // If the item was pulled into the library, route Play to the local
  // playback URL; otherwise the sticky bar's Play button has nothing
  // to do, so we hide it by passing an empty url and a no-op resume.
  const playUrl = matchedLocal ? `/play/${matchedLocal.id}` : ''
  const tmdbImdbId = data.external_ids?.imdb_id || null

  return (
    <div className="pb-12">
      {matchedLocal && (
        <DetailStickyBar
          visible={pastHero}
          title={title}
          logoUrl={logoUrl}
          posterUrl={poster}
          progress={null}
          isFavorite={false}
          playUrl={playUrl}
          resumeUrl={playUrl}
          tmdbId={tmdbId}
          imdbId={tmdbImdbId}
          itemType={kind === 'tv' ? 'Series' : 'Movie'}
        />
      )}
      {/* Hero */}
      <section className="relative -mt-14 mb-2 overflow-hidden">
        {backdrop && (
          <motion.div
            initial={{ opacity: 0, scale: 1.04 }}
            animate={{ opacity: 1, scale: 1 }}
            transition={{ duration: 0.7, ease: [0.16, 1, 0.3, 1] }}
            className="absolute inset-0 bg-cover bg-top will-change-transform"
            style={{ backgroundImage: `url(${backdrop})` }}
          />
        )}
        <div className="absolute inset-0 bg-gradient-to-r from-void via-void/60 to-transparent" />
        <div className="absolute inset-0 bg-gradient-to-t from-void via-void/30 to-transparent" />

        <div className="relative px-7 pt-32 pb-10 grid grid-cols-1 md:grid-cols-[180px_1fr] gap-8">
          {poster && (
            <motion.img
              initial={{ opacity: 0, y: 12 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ duration: 0.5, ease: [0.16, 1, 0.3, 1] }}
              src={poster}
              alt={title}
              className="w-[180px] aspect-[2/3] rounded-xl object-cover ring-1 ring-border-strong shadow-[0_30px_80px_-20px_rgba(0,0,0,0.85)] hidden md:block"
            />
          )}
          <motion.div
            initial={{ opacity: 0, y: 16 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1], delay: 0.1 }}
            className="max-w-3xl"
          >
            <div className="flex items-center gap-2 mb-3 flex-wrap">
              <span className="inline-flex items-center gap-1.5 h-6 px-2.5 rounded-full bg-cool/12 border border-cool/30 text-cool text-[10px] font-semibold uppercase tracking-[0.14em]">
                <Globe size={10} />
                Discovery
              </span>
              <AvailabilityChip tmdbId={tmdbId} />
              {matchedLocal && (
                <button
                  onClick={() => navigate(`/item/${matchedLocal.id}`)}
                  className="inline-flex items-center gap-1.5 h-6 px-2.5 rounded-full bg-accent text-void text-[10px] font-bold uppercase tracking-[0.06em] hover:bg-accent-hover transition"
                >
                  <Library size={10} strokeWidth={2.5} />
                  In your library
                </button>
              )}
            </div>

            {logoUrl ? (
              <div className="mb-4 flex justify-start">
                <img
                  src={logoUrl}
                  alt={title}
                  className="block h-auto max-h-32 md:max-h-40 max-w-[460px] w-auto drop-shadow-[0_4px_24px_rgba(0,0,0,0.7)]"
                  onError={e => {
                    const el = e.target as HTMLImageElement
                    el.style.display = 'none'
                    // Reveal the text fallback if the image fails to load.
                    const fallback = el.nextElementSibling as HTMLElement | null
                    if (fallback) fallback.style.display = 'block'
                  }}
                />
                <h1
                  className="font-display text-4xl md:text-5xl font-bold text-white leading-[0.98] tracking-tight mb-3 drop-shadow-[0_4px_16px_rgba(0,0,0,0.6)] hidden"
                >
                  {title}
                </h1>
              </div>
            ) : (
              <h1 className="font-display text-4xl md:text-5xl font-bold text-white leading-[0.98] tracking-tight mb-3 drop-shadow-[0_4px_16px_rgba(0,0,0,0.6)]">
                {title}
              </h1>
            )}

            {tagline && (
              <p className="text-[15px] text-white/70 italic mb-3 max-w-xl font-display">
                "{tagline}"
              </p>
            )}

            <div className="flex items-center gap-2.5 text-[12px] text-white/75 mb-3 flex-wrap font-medium">
              {year && <span className="tabular-nums">{year}</span>}
              {certification && (
                <>
                  <Dot />
                  <span className="px-1.5 py-0.5 border border-white/25 rounded text-[10px] font-semibold tracking-wide">
                    {certification}
                  </span>
                </>
              )}
              {runtime != null && runtime > 0 && (
                <>
                  <Dot />
                  <span className="inline-flex items-center gap-1 tabular-nums">
                    <Clock size={11} stroke={2} />
                    {runtime}m
                  </span>
                </>
              )}
              {community != null && community > 0 && (
                <>
                  <Dot />
                  <span className="inline-flex items-center gap-1">
                    <Star size={11} className="text-accent" fill="currentColor" stroke={0} />
                    <span className="tabular-nums">{Number(community).toFixed(1)}</span>
                  </span>
                </>
              )}
              {kind === 'tv' && (data.number_of_seasons ?? 0) > 0 && (
                <>
                  <Dot />
                  <span className="inline-flex items-center gap-1 tabular-nums">
                    <Calendar size={11} stroke={2} />
                    {data.number_of_seasons} season{data.number_of_seasons === 1 ? '' : 's'}
                  </span>
                </>
              )}
            </div>

            {genres.length > 0 && (
              <div className="flex flex-wrap gap-1.5 mb-5">
                {genres.slice(0, 5).map(g => (
                  <span
                    key={g.id}
                    className="px-2.5 h-6 inline-flex items-center bg-white/8 backdrop-blur text-white/85 text-[11px] rounded-full border border-white/8"
                  >
                    {g.name}
                  </span>
                ))}
              </div>
            )}

            <div className="flex items-center gap-2.5 flex-wrap">
              <RequestButton tmdbId={tmdbId} kind={kind} tmdbData={data as TmdbMovie | TmdbTvShow | null} />
              {matchedLocal && (
                <button
                  onClick={() => navigate(`/item/${matchedLocal.id}`)}
                  className="h-11 px-5 bg-white/10 text-white border border-white/20 backdrop-blur rounded-lg flex items-center gap-2 text-[13px] font-medium transition-all duration-200 hover:bg-white/15 hover:border-white/30 hover:scale-[1.02] active:scale-[0.98] focus-ring"
                >
                  <Library size={14} stroke={2} />
                  Open in library
                </button>
              )}
              <a
                href={tmdbWatchUrl}
                target="_blank"
                rel="noopener noreferrer"
                className="h-11 px-4 bg-white/10 hover:bg-white/15 text-white border border-white/15 backdrop-blur rounded-lg flex items-center gap-2 text-[13px] font-medium transition-all duration-200 hover:scale-[1.02] active:scale-[0.98] focus-ring"
              >
                Open on TMDB
                <ExternalLink size={12} />
              </a>
            </div>
          </motion.div>
        </div>
      </section>

      <div ref={stickySentinelRef} aria-hidden className="h-px -mt-px" />

      {/* Body */}
      <div className="px-7 space-y-12 pt-4">
        {overview && (
          <Section label="Overview">
            <p className="text-[15px] text-text-2 leading-[1.7] max-w-[68ch] tracking-[-0.005em]">
              {overview}
            </p>
            {overview.length > 600 && (
              <button
                onClick={() => setReadingModeOpen(true)}
                className="mt-2 text-[11.5px] text-accent hover:text-accent-hover transition tracking-tight focus-ring rounded"
              >
                Open in reader
              </button>
            )}
          </Section>
        )}
        <ReadingMode
          open={readingModeOpen}
          onClose={() => setReadingModeOpen(false)}
          title={title}
          body={overview}
        />

        {cast.length > 0 && (
          <Section label="Cast">
            <CastStrip cast={cast} />
          </Section>
        )}

        {crew.length > 0 && (
          <Section label="Crew">
            <CrewGrid crew={crew} />
            <div className="mt-3">
              <ComposerBlock crew={crew} />
            </div>
          </Section>
        )}

        {(data.videos?.results?.length ?? 0) > 0 && (
          <Section label="Videos">
            <VideosSection videos={data.videos?.results} />
          </Section>
        )}

        {(awardsQuery.data?.length ?? 0) > 0 && (
          <Section label="Awards">
            <AwardsBlock awards={awardsQuery.data} />
          </Section>
        )}

        {(wikiProductionQuery.data?.extract || (keywords.length > 0 && wikiProductionQuery.data)) && (
          <Section label="Trivia">
            <ProductionTrivia keywords={keywords} wikiProduction={wikiProductionQuery.data} />
          </Section>
        )}

        {(locationsQuery.data?.length ?? 0) > 0 && (
          <Section label="Filming locations">
            <FilmingLocationsMap locations={locationsQuery.data} />
          </Section>
        )}

        {kind === 'movie' && data.belongs_to_collection && (
          <Section label="Collection">
            <CollectionStrip
              collectionRef={data.belongs_to_collection}
              collection={tmdbCollection.data}
              currentMovieId={tmdbId}
            />
          </Section>
        )}
      </div>

      {/* Recommendations / similar */}
      {recommendations.length > 0 && (
        <div className="mt-10">
          <ContentRow
            title="More like this"
            subtitle="TMDB recommendations"
            items={recommendations}
            layoutKey={`tmdb_${kind}_${tmdbId}_recs`}
          />
        </div>
      )}
      {similar.length > 0 && (
        <ContentRow
          title="Similar"
          subtitle="Same flavour, different titles"
          items={similar}
          layoutKey={`tmdb_${kind}_${tmdbId}_similar`}
        />
      )}
    </div>
  )
}

function Section({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <section>
      <p className="text-[10px] uppercase tracking-[0.18em] font-semibold text-text-3 mb-4 leading-none">
        {label}
      </p>
      {children}
    </section>
  )
}

function CastStrip({ cast }: { cast: any[] }) {
  const navigate = useNavigate()
  return (
    <div className="-mx-7">
      <HorizontalScroller gap="gap-3" arrowsBottomInset="bottom-12">
        {cast.map(c => (
          <button
            key={c.id}
            onClick={() => navigate(`/person/${c.id}`)}
            className="shrink-0 w-[112px] text-left focus-ring rounded-lg group"
          >
            <div className="aspect-[2/3] rounded-lg overflow-hidden bg-elevated ring-1 ring-border group-hover:ring-border-strong mb-1.5 transition">
              {c.profile_path ? (
                <img
                  src={getTmdbImageUrl(c.profile_path, 'w185')}
                  alt={c.name}
                  className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
                  loading="lazy"
                />
              ) : (
                <div className="w-full h-full grid place-items-center text-text-4 text-2xl font-display font-semibold opacity-40">
                  {c.name?.[0]?.toUpperCase() || '?'}
                </div>
              )}
            </div>
            <p className="text-[12px] text-text-1 font-medium leading-tight tracking-tight truncate">
              {c.name}
            </p>
            {c.character && (
              <p className="text-[10.5px] text-text-3 leading-tight truncate">
                {c.character}
              </p>
            )}
          </button>
        ))}
      </HorizontalScroller>
    </div>
  )
}

function Skeleton() {
  return (
    <div className="pb-12">
      <div className="relative -mt-14 mb-2 h-[60vh] min-h-[440px] overflow-hidden">
        <div className="absolute inset-0 skeleton" />
        <div className="absolute inset-0 bg-gradient-to-r from-void via-void/55 to-transparent" />
      </div>
      <div className="px-7 space-y-8 pt-6">
        <div className="skeleton h-5 w-32 rounded" />
        <div className="skeleton h-4 w-full rounded" />
        <div className="skeleton h-4 w-5/6 rounded" />
        <div className="skeleton h-4 w-2/3 rounded" />
      </div>
    </div>
  )
}

function Dot() {
  return <span className="text-white/30">·</span>
}
