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

interface Decade {
  label: string
  /** Inclusive start + end years for the decade. */
  from: number
  to: number
  /** A short evocative subtitle used when this decade is expanded. */
  blurb: string
}

const CURRENT_YEAR = new Date().getFullYear()

const DECADES: Decade[] = [
  { label: '1950s', from: 1950, to: 1959, blurb: 'Studio system, Westerns, noir, the dawn of widescreen' },
  { label: '1960s', from: 1960, to: 1969, blurb: 'New Wave, counterculture cinema, epic spectacle' },
  { label: '1970s', from: 1970, to: 1979, blurb: 'New Hollywood - auteurs in charge of the asylum' },
  { label: '1980s', from: 1980, to: 1989, blurb: 'Blockbuster era, practical effects, neon everything' },
  { label: '1990s', from: 1990, to: 1999, blurb: 'Indie boom, CGI takes over, prestige cable begins' },
  { label: '2000s', from: 2000, to: 2009, blurb: 'Digital filmmaking, fantasy trilogies, mumblecore' },
  { label: '2010s', from: 2010, to: 2019, blurb: 'Streaming wars, MCU dominance, peak TV' },
  { label: '2020s', from: 2020, to: Math.max(CURRENT_YEAR, 2024), blurb: 'Post-streaming reshuffle, A24 era, global cinema' },
]

interface Props {
  kind: 'movie' | 'tv'
  active: string | null
  onChange: (decadeLabel: string | null) => void
}

/**
 * Time-based discovery surface. A horizontal strip of decades sits at
 * the top; click one to expand a row of the highest-rated titles from
 * that era. Different mental model from mood / genre - the user comes
 * in thinking "something from the 80s" and lands directly on it.
 */
export default function DecadeStrip({ kind, active, onChange }: Props) {
  return (
    <section className="px-7 mb-2">
      <div className="flex items-center gap-2 mb-3">
        <span className="w-1 h-3 rounded-full bg-accent" />
        <span className="text-[10.5px] uppercase tracking-[0.18em] font-semibold text-text-3">
          By decade
        </span>
      </div>
      <div className="-mx-7 px-7 pb-3 overflow-x-auto hide-scrollbar">
        <ul className="flex items-stretch gap-2 min-w-max">
          {DECADES.map(d => (
            <DecadeChip
              key={d.label}
              decade={d}
              active={active === d.label}
              onClick={() => onChange(active === d.label ? null : d.label)}
            />
          ))}
        </ul>
      </div>
      <AnimatePresence>
        {active && (
          <motion.div
            key={active + kind}
            initial={{ opacity: 0, y: 8 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -4 }}
            transition={{ duration: 0.28, ease: [0.16, 1, 0.3, 1] }}
            className="-mx-7 mt-4 min-h-[220px]"
          >
            <DecadeRow
              decade={DECADES.find(d => d.label === active)!}
              kind={kind}
            />
          </motion.div>
        )}
      </AnimatePresence>
    </section>
  )
}

function DecadeChip({
  decade,
  active,
  onClick,
}: {
  decade: Decade
  active: boolean
  onClick: () => void
}) {
  const startsAt = decade.from
  const isFuture = decade.to > CURRENT_YEAR - 1 && decade.from <= CURRENT_YEAR
  return (
    <li>
      <motion.button
        onClick={onClick}
        whileTap={{ scale: 0.96 }}
        aria-pressed={active}
        className={`relative inline-flex flex-col items-start h-[68px] w-[112px] px-3.5 py-2.5 rounded-xl border text-left transition-colors duration-200 focus-ring ${
          active
            ? 'bg-accent text-void border-accent shadow-[0_10px_24px_-10px_rgba(245,182,66,0.55)]'
            : 'bg-elevated/50 text-text-2 border-border hover:border-border-strong hover:text-text-1 hover:bg-elevated/80'
        }`}
      >
        <span className={`font-display text-[18px] font-bold leading-none tabular-nums ${
          active ? 'text-void' : 'text-text-1'
        }`}>
          {decade.label}
        </span>
        <span className={`mt-auto text-[10px] uppercase tracking-[0.14em] font-semibold ${
          active ? 'text-void/65' : 'text-text-4'
        }`}>
          {isFuture ? `${startsAt}-now` : `${startsAt}-${decade.to}`}
        </span>
      </motion.button>
    </li>
  )
}

function DecadeRow({ decade, kind }: { decade: Decade; kind: 'movie' | 'tv' }) {
  const lib = useLibraryByTmdbId()
  const hideAdult = usePreferencesStore(s => s.hideAdult)
  // The TMDB discover endpoints accept primary_release_year / first_air_date
  // ranges. We can use the .gte / .lte form to bracket the decade.
  const dateField = kind === 'movie' ? 'primary_release_date' : 'first_air_date'
  const params: Record<string, string> = {
    [`${dateField}.gte`]: `${decade.from}-01-01`,
    [`${dateField}.lte`]: `${decade.to}-12-31`,
    'vote_count.gte': '500',
    'vote_average.gte': '7',
    sort_by: 'vote_average.desc',
  }

  const movieQuery = useTmdbDiscoverMovies(kind === 'movie' ? params : {})
  const tvQuery = useTmdbDiscoverTv(kind === 'tv' ? params : {})
  const data = kind === 'movie' ? movieQuery.data : tvQuery.data

  const items = useMemo(() => {
    const raw = (data?.results || []).map(m => ({ ...m, media_type: kind }))
    return mapTmdbToJf(filterToMissing(raw, lib.data, hideAdult, m => !!m.adult), lib.data)
  }, [data, lib.data, hideAdult, kind])

  if (items.length === 0) return null
  return (
    <ContentRow
      title={`The ${decade.label}`}
      subtitle={decade.blurb}
      items={items}
      layoutKey={`decade_${decade.label}_${kind}`}
    />
  )
}
