import { useEffect, useMemo, useRef, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useQueries } from '@tanstack/react-query'
import { Trash2 } from '../../lib/icons'
import { fetchLetterboxdList, type LetterboxdListItem } from '../../api/letterboxd'
import { getMovieFull } from '../../api/tmdb'
import { useLibraryByTmdbId } from '../../hooks/use-jellyfin'
import { mapTmdbToJf } from '../../lib/tmdb-mapping'
import { useLetterboxdLists, type SavedLetterboxdList } from '../../stores/letterboxd-lists-store'
import ContentRow from './ContentRow'

interface Props {
  saved: SavedLetterboxdList
}

const RSS_STALE = 6 * 60 * 60 * 1000

/**
 * One imported Letterboxd list rendered as a content row. Lazy-mounts
 * once scrolled near the viewport so importing 5 lists doesn't burn
 * 100+ TMDB requests on home page load.
 */
export default function LetterboxdListRow({ saved }: Props) {
  const containerRef = useRef<HTMLDivElement>(null)
  const [near, setNear] = useState(false)

  useEffect(() => {
    if (!containerRef.current) return
    const el = containerRef.current
    const obs = new IntersectionObserver(
      entries => {
        for (const e of entries) {
          if (e.isIntersecting) {
            setNear(true)
            obs.disconnect()
            return
          }
        }
      },
      { rootMargin: '200px' },
    )
    obs.observe(el)
    return () => obs.disconnect()
  }, [])

  return (
    <div ref={containerRef}>
      {near ? <Mounted saved={saved} /> : <Placeholder saved={saved} />}
    </div>
  )
}

function Mounted({ saved }: Props) {
  const remove = useLetterboxdLists(s => s.remove)
  const rss = useQuery({
    queryKey: ['letterboxd', 'list', saved.url],
    queryFn: () => fetchLetterboxdList(saved.url),
    staleTime: RSS_STALE,
  })
  const data = rss.data
  // Cap at 30 entries to keep the request burst reasonable; serious
  // lists with 100 films would slam TMDB on first mount otherwise.
  const entries: LetterboxdListItem[] = useMemo(
    () => (data?.items || []).slice(0, 30),
    [data?.items],
  )
  const ids = useMemo(
    () => entries.map(e => e.tmdbId).filter((x): x is string => !!x).map(Number),
    [entries],
  )
  const tmdbQueries = useQueries({
    queries: ids.map(id => ({
      queryKey: ['tmdb', 'movie-full', id],
      queryFn: () => getMovieFull(id),
      staleTime: 24 * 60 * 60 * 1000,
    })),
  })
  const libraryByTmdbId = useLibraryByTmdbId()
  const items = useMemo(() => {
    const tmdbMap = new Map<number, any>()
    ids.forEach((id, i) => {
      const d = tmdbQueries[i]?.data
      if (d) tmdbMap.set(id, { ...d, media_type: 'movie' })
    })
    // Preserve list order; drop items the proxy returned without a TMDB id.
    const ordered: any[] = []
    for (const e of entries) {
      if (!e.tmdbId) continue
      const d = tmdbMap.get(Number(e.tmdbId))
      if (d) ordered.push(d)
    }
    return mapTmdbToJf(ordered, libraryByTmdbId.data)
  }, [entries, ids, tmdbQueries, libraryByTmdbId.data])

  if (rss.isLoading) return <Placeholder saved={saved} />
  if (!data) {
    return (
      <section className="mb-10 px-7">
        <h2 className="text-[18px] font-semibold text-text-1 tracking-tight mb-1">
          {saved.customTitle || 'Letterboxd list'}
        </h2>
        <p className="text-[12px] text-text-3 mb-3">
          Couldn't load this list. The proxy may be down, or the URL is private.
        </p>
        <button
          onClick={() => remove(saved.url)}
          className="text-[11px] text-text-4 hover:text-red-300 transition tracking-tight focus-ring rounded"
        >
          Remove
        </button>
      </section>
    )
  }
  if (items.length === 0) return null

  const matched = items.filter(i => (i as any)._inLibrary).length
  const subtitle = `${matched} of ${items.length} in your library · from Letterboxd`

  return (
    <div className="relative group/llb">
      <ContentRow
        title={saved.customTitle || data.title}
        subtitle={subtitle}
        items={items}
        layoutKey={`letterboxd_${saved.url}`}
      />
      <button
        onClick={() => {
          if (confirm('Remove this Letterboxd list?')) remove(saved.url)
        }}
        title="Remove this list"
        className="absolute top-3 right-7 w-8 h-8 grid place-items-center rounded-full text-text-3 hover:text-red-300 hover:bg-elevated/80 opacity-0 group-hover/llb:opacity-100 transition focus-ring"
      >
        <Trash2 size={13} stroke={2} />
      </button>
    </div>
  )
}

function Placeholder({ saved }: Props) {
  return (
    <section className="mb-10">
      <div className="px-7 mb-3.5">
        <h2 className="text-[18px] font-semibold text-text-1 tracking-tight">
          {saved.customTitle || 'Letterboxd list'}
        </h2>
        <p className="text-[12px] text-text-3 mt-0.5 truncate max-w-md">{saved.url}</p>
      </div>
      <div className="px-7 flex gap-3">
        {Array.from({ length: 6 }).map((_, j) => (
          <div key={j} className="shrink-0 w-[160px]">
            <div className="skeleton aspect-[2/3] rounded-lg" />
          </div>
        ))}
      </div>
    </section>
  )
}
