import { useMemo } from 'react'
import { useLibraryItems, useLibraryByTmdbId } from '../../../hooks/use-jellyfin'
import { useTmdbMovie, useTmdbTvShow } from '../../../hooks/use-tmdb'
import { useWatchlist } from '../../../hooks/use-watchlist'
import { usePersonSpotlights } from '../../../hooks/use-person-spotlights'
import { mapTmdbToJf } from '../../../lib/tmdb-mapping'
import ContentRow from '../../../components/ui/ContentRow'
import PersonSpotlightRow from '../../../components/ui/PersonSpotlightRow'
import { pickTimeOfDaySlot } from '../home-utils'

/**
 * Library decade rows. Buckets the user's library into the chosen decade.
 * Hidden when a decade has fewer than 6 items so it doesn't feel sparse.
 */
export function DecadeRow({ decade }: { decade: number }) {
  const years = Array.from({ length: 10 }, (_, i) => decade + i)
  const { data } = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series'],
    years,
    sortBy: ['Random'],
    sortOrder: ['Descending'],
    limit: 18,
  })
  const items = data?.Items || []
  if (items.length < 6) return null
  const decadeLabel = `${decade}s`
  const subtitle =
    decade <= 1980
      ? 'Vintage finds from your library'
      : decade === 1990
        ? 'A nineties revival'
        : decade === 2000
          ? 'Y2K and after'
          : decade === 2010
            ? 'The streaming-era classics'
            : 'Recent canon'
  return <ContentRow title={decadeLabel} subtitle={subtitle} items={items} />
}

/**
 * Hidden gems. Library items the user has never opened, sorted by community
 * rating. The 7.5 threshold keeps the bar high enough that the row feels
 * curated.
 */
export function HiddenGemsRow() {
  const { data } = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series'],
    sortBy: ['CommunityRating'],
    sortOrder: ['Descending'],
    minCommunityRating: 7.5,
    filters: ['IsUnplayed'],
    limit: 16,
  })
  const items = data?.Items || []
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Hidden gems"
      subtitle="Highly rated and still unwatched in your library"
      items={items}
    />
  )
}

/**
 * Recently added items the user hasn't played at all. Distinct from
 * "Recently added" (any recent) and from "Continue watching" (already
 * started).
 */
export function UntouchedRow() {
  const { data } = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series'],
    sortBy: ['DateCreated'],
    sortOrder: ['Descending'],
    filters: ['IsUnplayed'],
    limit: 14,
  })
  const items = data?.Items || []
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Added but not yet started"
      subtitle="New arrivals you haven't opened"
      items={items}
    />
  )
}

/**
 * Time-of-day picker. The slot rotates between four moods based on local
 * time: morning calm, afternoon adventure, evening drama, late-night dark.
 */
export function TimeOfDayRow() {
  const slot = pickTimeOfDaySlot()
  const { data } = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series'],
    genres: slot.genres,
    sortBy: ['Random'],
    sortOrder: ['Descending'],
    limit: 14,
  })
  const items = data?.Items || []
  if (items.length === 0) return null
  return <ContentRow title={slot.title} subtitle={slot.subtitle} items={items} />
}

export function GenreRow({ genre, subtitle }: { genre: string; subtitle: string }) {
  const { data } = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series'],
    genres: [genre],
    sortBy: ['Random'],
    sortOrder: ['Descending'],
    limit: 16,
  })
  const items = data?.Items || []
  if (items.length === 0) return null
  return <ContentRow title={genre} subtitle={subtitle} items={items} />
}

/**
 * "Because you watched X". Picks the user's most recent finished item with
 * a TMDB id, fetches TMDB recommendations, filters out library items.
 */
export function BecauseYouWatchedRow() {
  const recentlyPlayed = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series'],
    sortBy: ['DatePlayed'],
    sortOrder: ['Descending'],
    filters: ['IsPlayed'],
    limit: 10,
  })
  const seed = useMemo(() => {
    const list = recentlyPlayed.data?.Items || []
    return list.find(it => !!(it.ProviderIds?.Tmdb)) || null
  }, [recentlyPlayed.data])

  const tmdbId = seed?.ProviderIds?.Tmdb ? Number(seed.ProviderIds.Tmdb) : null
  const isSeries = seed?.Type === 'Series'
  const movieFull = useTmdbMovie(!isSeries ? tmdbId : null)
  const tvFull = useTmdbTvShow(isSeries ? tmdbId : null)
  const libraryByTmdbId = useLibraryByTmdbId()

  const items = useMemo(() => {
    const recs = isSeries
      ? tvFull.data?.recommendations?.results
      : movieFull.data?.recommendations?.results
    if (!recs) return []
    const lib = libraryByTmdbId.data
    const filtered = recs.filter(r => !lib?.has(String(r.id)))
    return mapTmdbToJf(filtered, lib)
  }, [movieFull.data, tvFull.data, isSeries, libraryByTmdbId.data])

  if (!seed || items.length === 0) return null
  return (
    <ContentRow
      title={`Because you watched "${seed.Name}"`}
      subtitle="Picks from TMDB you don't have yet"
      items={items}
      layoutKey="because_you_watched"
    />
  )
}

/**
 * Director and actor spotlight rows. Aggregates the user's recently watched
 * library items, surfaces persons watched at least twice. Renders a row each
 * for the top director and top actor.
 */
export function PersonSpotlights() {
  const recentlyPlayed = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series'],
    sortBy: ['DatePlayed'],
    sortOrder: ['Descending'],
    filters: ['IsPlayed'],
    limit: 8,
  })
  const spotlights = usePersonSpotlights(recentlyPlayed.data?.Items)
  return (
    <>
      {spotlights.director && (
        <PersonSpotlightRow
          personId={spotlights.director.id}
          name={spotlights.director.name}
          profilePath={spotlights.director.profile_path}
          role="director"
          watchedCount={spotlights.director.count}
        />
      )}
      {spotlights.actor && (
        <PersonSpotlightRow
          personId={spotlights.actor.id}
          name={spotlights.actor.name}
          profilePath={spotlights.actor.profile_path}
          role="actor"
          watchedCount={spotlights.actor.count}
        />
      )}
    </>
  )
}

/**
 * Watchlist row. Reads from the user's "Watchlist" Jellyfin playlist.
 */
export function WatchlistRow() {
  const { items } = useWatchlist()
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Your watchlist"
      subtitle="Saved for later"
      items={items}
      seeAllHref="/playlists"
      layoutKey="watchlist"
    />
  )
}
