import { useMemo } from 'react'
import {
  useTmdbTrending,
  useTmdbDiscoverMovies,
  useTmdbDiscoverTv,
  useTmdbUpcoming,
  useTmdbTopRatedMovies,
  useTmdbTopRatedTv,
} from '../../hooks/use-tmdb'
import { useLibraryByTmdbId } from '../../hooks/use-jellyfin'
import { mapTmdbToJf } from '../../lib/tmdb-mapping'
import type { TmdbDiscoverItem } from '../../api/tmdb'
import { tmdbMovieGenreId, tmdbTvGenreId } from '../../lib/tmdb-genres'
import ContentRow from '../../components/ui/ContentRow'
import { usePreferencesStore } from '../../stores/preferences-store'
import { filterToMissing } from './helpers'

export function TrendingDayRow() {
  const trending = useTmdbTrending('all', 'day')
  const lib = useLibraryByTmdbId()
  const hideAdult = usePreferencesStore(s => s.hideAdult)
  const items = useMemo(() => {
    const raw = (trending.data?.results || [])
    const filtered = filterToMissing(raw, lib.data, hideAdult, m => !!m.adult)
    return mapTmdbToJf(filtered, lib.data)
  }, [trending.data, lib.data, hideAdult])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Trending today"
      subtitle="Buzz on TMDB right now - things you don't have"
      items={items}
      layoutKey="discover_trending_day"
    />
  )
}

export function TrendingWeekRow() {
  const trending = useTmdbTrending('all', 'week')
  const lib = useLibraryByTmdbId()
  const hideAdult = usePreferencesStore(s => s.hideAdult)
  const items = useMemo(() => {
    const raw = (trending.data?.results || [])
    const filtered = filterToMissing(raw, lib.data, hideAdult, m => !!m.adult)
    return mapTmdbToJf(filtered, lib.data)
  }, [trending.data, lib.data, hideAdult])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Trending this week"
      subtitle="The week's biggest titles you're missing"
      items={items}
      layoutKey="discover_trending_week"
    />
  )
}

export function PopularMoviesRow() {
  const movies = useTmdbDiscoverMovies({ sort_by: 'popularity.desc' })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Popular movies"
      subtitle="Top of TMDB right now - missing from your library"
      items={items}
      layoutKey="discover_popular_movies"
    />
  )
}

export function PopularTvRow() {
  const tv = useTmdbDiscoverTv({ sort_by: 'popularity.desc' })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (tv.data?.results || []).map(m => ({ ...m, media_type: 'tv' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [tv.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Popular shows"
      subtitle="Top of TMDB right now - missing from your library"
      items={items}
      layoutKey="discover_popular_tv"
    />
  )
}

export function UpcomingMoviesRow({ region }: { region: string }) {
  const upcoming = useTmdbUpcoming(region)
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (upcoming.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [upcoming.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Coming soon"
      subtitle={`New theatrical and streaming releases${region ? ` in ${region}` : ''}`}
      items={items}
      layoutKey={`discover_upcoming_${region}`}
    />
  )
}

export function TopRatedMoviesRow() {
  const movies = useTmdbTopRatedMovies()
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Critically acclaimed movies"
      subtitle="The highest-rated films on TMDB you don't yet own"
      items={items}
      layoutKey="discover_top_rated_movies"
    />
  )
}

export function TopRatedTvRow() {
  const tv = useTmdbTopRatedTv()
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (tv.data?.results || []).map(m => ({ ...m, media_type: 'tv' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [tv.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Critically acclaimed shows"
      subtitle="The highest-rated series on TMDB you don't yet own"
      items={items}
      layoutKey="discover_top_rated_tv"
    />
  )
}

export function CultClassicsRow() {
  const movies = useTmdbDiscoverMovies({
    'vote_count.gte': '10000',
    'vote_average.gte': '8',
    'popularity.lte': '20',
    sort_by: 'vote_average.desc',
  })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Cult classics"
      subtitle="Highly rated films flying under the radar"
      items={items}
      layoutKey="discover_cult"
    />
  )
}

export function HighlyRatedThisYearRow() {
  const year = new Date().getFullYear()
  const movies = useTmdbDiscoverMovies({
    primary_release_year: String(year),
    'vote_count.gte': '200',
    sort_by: 'vote_average.desc',
  })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title={`Highly rated this year (${year})`}
      subtitle="The best-rated theatrical and streaming releases of the year"
      items={items}
      layoutKey={`discover_year_${year}`}
    />
  )
}

export function ForeignFilmsRow() {
  const movies = useTmdbDiscoverMovies({
    'vote_count.gte': '500',
    sort_by: 'vote_average.desc',
  })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || [])
      .filter(m => m.original_language && m.original_language !== 'en')
      .slice(0, 20)
      .map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Foreign cinema"
      subtitle="Top-rated non-English films you don't own"
      items={items}
      layoutKey="discover_foreign"
    />
  )
}

export function DocumentariesRow() {
  const movies = useTmdbDiscoverMovies({
    with_genres: '99',
    'vote_count.gte': '300',
    sort_by: 'vote_average.desc',
  })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title="Documentaries"
      subtitle="The best-rated docs on TMDB you don't have"
      items={items}
      layoutKey="discover_docs"
    />
  )
}

export function GenreRow({ genre }: { genre: { label: string; subtitle: string } }) {
  const movieGenreId = tmdbMovieGenreId(genre.label)
  const tvGenreId = tmdbTvGenreId(genre.label)
  const movies = useTmdbDiscoverMovies(
    movieGenreId
      ? { with_genres: String(movieGenreId), 'vote_count.gte': '500', sort_by: 'vote_average.desc' }
      : ({} as Record<string, string>),
  )
  const tv = useTmdbDiscoverTv(
    tvGenreId
      ? { with_genres: String(tvGenreId), 'vote_count.gte': '200', sort_by: 'vote_average.desc' }
      : ({} as Record<string, string>),
  )
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const m = (movies.data?.results || []).map(x => ({ ...x, media_type: 'movie' }))
    const t = (tv.data?.results || []).map(x => ({ ...x, media_type: 'tv' }))
    const out: TmdbDiscoverItem[] = []
    const max = Math.max(m.length, t.length)
    for (let i = 0; i < max && out.length < 20; i++) {
      if (m[i]) out.push(m[i])
      if (t[i]) out.push(t[i])
    }
    return mapTmdbToJf(filterToMissing(out, lib.data), lib.data)
  }, [movies.data, tv.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title={genre.label}
      subtitle={genre.subtitle}
      items={items}
      layoutKey={`discover_genre_${genre.label}`}
    />
  )
}

export function LanguageRow({ lang }: { lang: { code: string; label: string; subtitle: string } }) {
  const movies = useTmdbDiscoverMovies({
    with_original_language: lang.code,
    'vote_count.gte': '200',
    sort_by: 'vote_average.desc',
  })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title={lang.label}
      subtitle={lang.subtitle}
      items={items}
      layoutKey={`discover_lang_${lang.code}`}
    />
  )
}

export function StudioRow({ brandId, label, subtitle }: { brandId: number; label: string; subtitle: string }) {
  const movies = useTmdbDiscoverMovies({
    with_companies: String(brandId),
    sort_by: 'popularity.desc',
  })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (movies.data?.results || []).slice(0, 18).map(m => ({ ...m, media_type: 'movie' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [movies.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title={label}
      subtitle={subtitle}
      items={items}
      layoutKey={`discover_studio_${brandId}`}
    />
  )
}

export function NetworkRow({ brandId, label, subtitle }: { brandId: number; label: string; subtitle: string }) {
  const tv = useTmdbDiscoverTv({
    with_networks: String(brandId),
    sort_by: 'popularity.desc',
  })
  const lib = useLibraryByTmdbId()
  const items = useMemo(() => {
    const raw = (tv.data?.results || []).slice(0, 18).map(m => ({ ...m, media_type: 'tv' }))
    return mapTmdbToJf(filterToMissing(raw, lib.data), lib.data)
  }, [tv.data, lib.data])
  if (items.length === 0) return null
  return (
    <ContentRow
      title={label}
      subtitle={subtitle}
      items={items}
      layoutKey={`discover_network_${brandId}`}
    />
  )
}
