import { useEffect, useMemo, useRef, useState } from 'react'
import { useCanonListResolved } from '../../hooks/use-canon-list'
import { useLibraryByTmdbId } from '../../hooks/use-jellyfin'
import { mapTmdbToJf } from '../../lib/tmdb-mapping'
import type { CanonList } from '../../lib/canon-lists'
import ContentRow from './ContentRow'

interface Props {
  list: CanonList
}

/**
 * Renders one bundled canon list as a row. Lazy-mounts so we don't fire
 * 20+ TMDB requests on home page load - each row only resolves once
 * scrolled near the viewport. The user's library is cross-referenced
 * so in-library entries get the accent ring naturally and missing
 * entries are visible as the row's main story.
 */
export default function CanonListRow({ list }: 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 ? <CanonListRowMounted list={list} /> : <RowPlaceholder list={list} />}
    </div>
  )
}

// Cap the resolved list at 12 entries so each canon row triggers at
// most ~12 TMDB lookups on first scroll-into-view. Anyone curious about
// the rest can follow the source link in the row subtitle.
const MAX_CANON_RESOLVES = 12

function CanonListRowMounted({ list }: Props) {
  const ids = useMemo(
    () => list.tmdbMovieIds.slice(0, MAX_CANON_RESOLVES),
    [list.tmdbMovieIds],
  )
  const { items: tmdbItems } = useCanonListResolved(ids)
  const libraryByTmdbId = useLibraryByTmdbId()
  const items = useMemo(
    () => mapTmdbToJf(tmdbItems, libraryByTmdbId.data),
    [tmdbItems, libraryByTmdbId.data],
  )
  if (items.length === 0) return <RowPlaceholder list={list} />
  return (
    <ContentRow
      title={list.title}
      subtitle={list.subtitle}
      items={items}
      layoutKey={`canon_${list.id}`}
    />
  )
}

function RowPlaceholder({ list }: Props) {
  return (
    <section className="mb-10">
      <div className="px-7 mb-3.5">
        <h2 className="text-[18px] font-semibold text-text-1 tracking-tight">{list.title}</h2>
        <p className="text-[12px] text-text-3 mt-0.5">{list.subtitle}</p>
      </div>
      <div className="px-7 flex gap-3">
        {Array.from({ length: 8 }).map((_, j) => (
          <div key={j} className="shrink-0 w-[160px]">
            <div className="skeleton aspect-[2/3] rounded-lg" />
          </div>
        ))}
      </div>
    </section>
  )
}
