import { useMemo } from 'react'
import { useLibraryGenreDistribution, useLibraryByTmdbId } from '../../hooks/use-jellyfin'
import { useTmdbDiscoverMovies } from '../../hooks/use-tmdb'
import { usePreferencesStore } from '../../stores/preferences-store'
import { mapTmdbToJf } from '../../lib/tmdb-mapping'
import { tmdbMovieGenreId } from '../../lib/tmdb-genres'
import { filterToMissing } from '../../pages/discover/helpers'
import ContentRow from '../ui/ContentRow'

/**
 * Set of "interesting" genres we consider when looking for library
 * gaps. Limited to the ones that have a clear TMDB equivalent and are
 * reasonable to recommend in - "Music" or "TV Movie" are excluded
 * because suggestions there are usually noise.
 */
const INTERESTING_GENRES = [
  'Documentary',
  'Animation',
  'Horror',
  'Romance',
  'Thriller',
  'Science Fiction',
  'Mystery',
  'Fantasy',
  'Drama',
  'Comedy',
  'Action',
  'Adventure',
  'Crime',
  'Family',
  'War',
  'Western',
  'History',
]

/**
 * "Your library is heavy on X, light on Y" finder. Computes the genre
 * distribution across the user's Movie + Series catalogue, picks the
 * underrepresented INTERESTING_GENRES (definition: < 30% of the
 * top-genre count AND fewer than 12 absolute items), and surfaces a
 * top-rated TMDB row for each one.
 *
 * Hides itself when:
 *  - The user has fewer than 30 items total (results would be noise)
 *  - No genre crosses the under-representation threshold
 */
export default function LibraryGapFinder() {
  const distQuery = useLibraryGenreDistribution()
  const lib = useLibraryByTmdbId()

  const gaps = useMemo(() => {
    const data = distQuery.data
    if (!data || data.total < 30) return [] as Array<{ genre: string; count: number; top: number }>
    const top = Math.max(...Array.from(data.counts.values()), 1)
    return INTERESTING_GENRES
      .map(g => {
        const count = data.counts.get(g) || 0
        return { genre: g, count, top }
      })
      .filter(g => g.count < 12 && g.count < top * 0.3)
      // Most-glaring gaps first (the ones with the biggest delta from top).
      .sort((a, b) => a.count - b.count)
      .slice(0, 3)
  }, [distQuery.data])

  if (gaps.length === 0) return null

  const data = distQuery.data!
  const topEntry = [...data.counts.entries()].sort((a, b) => b[1] - a[1])[0]
  const topGenre = topEntry ? topEntry[0] : null

  return (
    <section className="pt-2 pb-2">
      <div className="px-7 mb-5">
        <div className="flex items-center gap-2 mb-1">
          <span className="w-1 h-3.5 rounded-full bg-accent" />
          <span className="text-[10.5px] font-semibold text-text-3 uppercase tracking-[0.18em]">
            Library gaps
          </span>
        </div>
        <h2 className="font-display text-[20px] font-bold tracking-tight text-text-1 leading-tight">
          What your shelves are missing
        </h2>
        <p className="text-[12px] text-text-3 mt-0.5 max-w-2xl">
          You have plenty of <span className="text-text-2 font-medium">{topGenre || '...'}</span>{' '}
          but barely anything in {gaps.map((g, i) => (
            <span key={g.genre}>
              {i > 0 && (i === gaps.length - 1 ? ' or ' : ', ')}
              <span className="text-text-2 font-medium">{g.genre.toLowerCase()}</span>
              <span className="text-text-4 tabular-nums"> ({g.count})</span>
            </span>
          ))}. A few top-rated picks worth adding:
        </p>
      </div>
      {gaps.map(g => (
        <GapRow key={g.genre} genre={g.genre} libraryMap={lib.data} />
      ))}
      <CuratedGapRow
        title="IMDb Top 250"
        subtitle="Highest-rated films of all time you don't have"
        params={{
          sort_by: 'vote_average.desc',
          'vote_count.gte': '5000',
          'vote_average.gte': '8.0',
          page: '1',
        }}
        libraryMap={lib.data}
      />
      <CuratedGapRow
        title="A24"
        subtitle="Essential films from the acclaimed studio"
        params={{
          with_companies: A24_COMPANY_ID,
          sort_by: 'vote_average.desc',
          'vote_count.gte': '100',
          page: '1',
        }}
        libraryMap={lib.data}
      />
      <CuratedGapRow
        title="Oscar Best Picture"
        subtitle="Academy Award winners worth owning"
        params={{
          with_keywords: OSCAR_KEYWORD_ID,
          sort_by: 'vote_average.desc',
          'vote_count.gte': '500',
          'vote_average.gte': '7.0',
          page: '1',
        }}
        libraryMap={lib.data}
      />
    </section>
  )
}

const A24_COMPANY_ID = '41077'
const OSCAR_KEYWORD_ID = '10271' // Academy Awards

function CuratedGapRow({
  title,
  subtitle,
  params,
  libraryMap,
}: {
  title: string
  subtitle: string
  params: Record<string, string>
  libraryMap?: Map<string, { id: string; name: string; type: string }>
}) {
  const movies = useTmdbDiscoverMovies(params)
  const hideAdult = usePreferencesStore(s => s.hideAdult)
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, libraryMap, hideAdult, m => !!(m as any).adult), libraryMap)
  }, [movies.data, libraryMap, hideAdult])
  if (items.length === 0) return null
  return (
    <ContentRow
      title={title}
      subtitle={subtitle}
      items={items}
      layoutKey={`gap_${title}`}
    />
  )
}

function GapRow({
  genre,
  libraryMap,
}: {
  genre: string
  libraryMap?: Map<string, { id: string; name: string; type: string }>
}) {
  const genreId = tmdbMovieGenreId(genre)
  const params = genreId
    ? {
        with_genres: String(genreId),
        'vote_count.gte': '1000',
        'vote_average.gte': '7.2',
        sort_by: 'vote_average.desc',
      }
    : ({} as Record<string, string>)
  const movies = useTmdbDiscoverMovies(params)
  const hideAdult = usePreferencesStore(s => s.hideAdult)
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, libraryMap, hideAdult, m => !!(m as any).adult), libraryMap)
  }, [movies.data, libraryMap, hideAdult])
  if (items.length === 0) return null
  return (
    <ContentRow
      title={`Try some ${genre.toLowerCase()}`}
      subtitle={`Top-rated ${genre.toLowerCase()} films you don't have`}
      items={items}
      layoutKey={`gap_${genre}`}
    />
  )
}
