import { useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import { motion } from 'framer-motion'
import { useTmdbPerson } from '../../hooks/use-tmdb'
import { useLibraryByTmdbId } from '../../hooks/use-jellyfin'
import { mapTmdbToJf } from '../../lib/tmdb-mapping'
import { getTmdbImageUrl } from '../../api/tmdb'
import ContentRow from './ContentRow'

interface Props {
  /** TMDB person id. */
  personId: number
  /** Display name; pre-known from the spotlight aggregation. */
  name: string
  /** "Director" or "Actor" - drives the credit filter. */
  role: 'director' | 'actor'
  profilePath?: string | null
  /** How many of this person's titles the user has already watched. */
  watchedCount: number
}

const COMMERCIAL_DEPARTMENTS = ['Acting', 'Directing']

/**
 * Renders a personal-pick row sourced from a TMDB person's filmography.
 *
 * Strategy:
 *  - Director: pull from `combined_credits.crew` filtered to job="Director",
 *    sorted by release date descending.
 *  - Actor: pull from `combined_credits.cast`, dropping low-billed
 *    appearances (one-line cameos), sorted by popularity then date.
 *
 * In-library matches show the accent ring naturally via PosterCard's
 * `_inLibrary` honoring; missing items render in the row beside them.
 */
export default function PersonSpotlightRow({ personId, name, role, profilePath, watchedCount }: Props) {
  const person = useTmdbPerson(personId)
  const libraryByTmdbId = useLibraryByTmdbId()

  const items = useMemo(() => {
    const credits = person.data?.combined_credits
    if (!credits) return []
    const list =
      role === 'director'
        ? (credits.crew || []).filter(c => c.job === 'Director')
        : (credits.cast || [])
            // Drop trivia / archival appearances and ultra-deep cuts.
            .filter(c => COMMERCIAL_DEPARTMENTS.includes((c as { department?: string }).department || 'Acting'))

    // De-dupe by id (a director may have multiple crew credits on one film
    // when they're also writer; a cast member may appear twice for episodic
    // tv guest spots).
    const seen = new Set<number>()
    const unique = list.filter(c => {
      if (seen.has(c.id)) return false
      seen.add(c.id)
      return true
    })

    // Sort: newest first, but with low-popularity entries pushed to the end.
    const sorted = [...unique].sort((a, b) => {
      const ap = a.popularity ?? 0
      const bp = b.popularity ?? 0
      // Bucket popularity so date dominates within "famous-enough" tiers.
      const ab = ap >= 5 ? 0 : 1
      const bb = bp >= 5 ? 0 : 1
      if (ab !== bb) return ab - bb
      const ad = (a.release_date || a.first_air_date || '').slice(0, 10)
      const bd = (b.release_date || b.first_air_date || '').slice(0, 10)
      return bd.localeCompare(ad)
    })

    return mapTmdbToJf(sorted.slice(0, 24), libraryByTmdbId.data)
  }, [person.data, libraryByTmdbId.data, role])

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

  const totalCount = items.length
  const remaining = Math.max(0, totalCount - watchedCount)

  return (
    <section className="mb-10">
      <div className="px-7 mb-3.5 flex items-end justify-between gap-3">
        <div className="flex items-center gap-3 min-w-0">
          {profilePath && (
            <motion.img
              initial={{ opacity: 0, scale: 0.95 }}
              animate={{ opacity: 1, scale: 1 }}
              transition={{ duration: 0.3 }}
              src={getTmdbImageUrl(profilePath, 'w185')}
              alt=""
              className="w-12 h-12 rounded-full object-cover ring-1 ring-border shrink-0"
            />
          )}
          <div className="min-w-0">
            <p className="text-[10px] uppercase tracking-[0.18em] font-semibold text-text-3 mb-0.5">
              {role === 'director' ? 'Director spotlight' : 'Following the actor'}
            </p>
            <h2 className="text-[18px] font-semibold text-text-1 tracking-tight leading-tight">
              <PersonName personId={personId} name={name} />
            </h2>
            <p className="text-[12px] text-text-3 mt-0.5">
              <span className="tabular-nums text-text-2 font-medium">{watchedCount}</span> watched
              {' · '}
              <span className="tabular-nums text-text-2 font-medium">{remaining}</span> remaining
            </p>
          </div>
        </div>
      </div>
      <ContentRow
        title=""
        items={items}
        layoutKey={`spotlight_${role}_${personId}`}
      />
    </section>
  )
}

function PersonName({ personId, name }: { personId: number; name: string }) {
  const navigate = useNavigate()
  return (
    <button
      onClick={() => navigate(`/person/${personId}`)}
      className="hover:text-accent transition focus-ring rounded"
    >
      {name}
    </button>
  )
}
