import { useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import { motion } from 'framer-motion'
import { Clock, Flame, Film, Tv, Award, Activity, CalendarStar } from '../lib/icons'
import { useLibraryItems } from '../hooks/use-jellyfin'
import { useDiary } from '../stores/diary-store'
import { genreBreakdown, totalHoursWatched, longestBinge, watchStreak } from '../lib/watch-stats'
import {
  hoursPerGenre,
  hoursPerStudio,
  completion,
  topByPersonRole,
  totalTimeSavedSeconds,
} from '../lib/stats'
import { formatTimeSaved } from '../lib/time-saved'

const CURRENT_YEAR = new Date().getFullYear()

/**
 * Detailed stats / year-in-watching. Profile page surfaces the at-a-glance
 * summary; this one digs deeper into hours-weighted breakdowns, top
 * directors / actors, completion ratios, and the time-saved-by-skipping
 * total across every series.
 */
export default function StatsPage() {
  const navigate = useNavigate()
  const { data, isLoading } = useLibraryItems(undefined, {
    includeItemTypes: ['Movie', 'Series', 'Episode'],
    sortBy: ['DatePlayed'],
    sortOrder: ['Descending'],
    filters: ['IsPlayed'],
    limit: 2000,
    includePeople: true,
  })
  const items = useMemo(() => data?.Items || [], [data?.Items])

  const yearItems = useMemo(
    () =>
      items.filter(it => {
        const raw = it.UserData?.LastPlayedDate
        if (!raw) return false
        return new Date(raw).getFullYear() === CURRENT_YEAR
      }),
    [items],
  )

  const totalHoursAll = useMemo(() => totalHoursWatched(items), [items])
  const totalHoursYear = useMemo(() => totalHoursWatched(yearItems), [yearItems])
  const streak = useMemo(() => watchStreak(items), [items])
  const binge = useMemo(() => longestBinge(items), [items])
  const genreShare = useMemo(() => genreBreakdown(items).slice(0, 10), [items])
  const hoursGenre = useMemo(() => hoursPerGenre(items).slice(0, 10), [items])
  const hoursStudio = useMemo(() => hoursPerStudio(items).slice(0, 8), [items])
  const comp = useMemo(() => completion(items), [items])
  const topDirectors = useMemo(
    () => topByPersonRole(items, (_role, type) => type === 'Director', 8),
    [items],
  )
  const topActors = useMemo(
    () => topByPersonRole(items, (_role, type) => type === 'Actor', 10),
    [items],
  )
  const timeSaved = useMemo(() => totalTimeSavedSeconds(), [])
  const diary = useDiary(s => s.entries)
  const diaryYearCount = useMemo(
    () =>
      diary.filter(d => {
        const t = Date.parse(d.watchedAt)
        return Number.isFinite(t) && new Date(t).getFullYear() === CURRENT_YEAR
      }).length,
    [diary],
  )

  const moviesCount = useMemo(() => items.filter(i => i.Type === 'Movie').length, [items])
  const episodesCount = useMemo(() => items.filter(i => i.Type === 'Episode').length, [items])

  return (
    <div className="px-7 pb-12 pt-6">
      <header className="mb-8">
        <p className="text-[11px] uppercase tracking-[0.18em] font-semibold text-text-3 mb-1.5">
          Stats
        </p>
        <h1 className="font-display text-3xl font-bold tracking-tight text-text-1 leading-tight">
          Your year in watching
        </h1>
        <p className="text-[13px] text-text-3 mt-1.5">
          A deeper look at everything you've played - {items.length.toLocaleString()} {items.length === 1 ? 'item' : 'items'} tracked.
        </p>
      </header>

      {isLoading && items.length === 0 && (
        <div className="rounded-xl bg-elevated/30 border border-border p-8 text-center mb-8">
          <p className="text-[13px] text-text-2 font-medium">Crunching the numbers...</p>
        </div>
      )}

      {/* Headline tiles */}
      <div className="grid grid-cols-2 md:grid-cols-3 xl:grid-cols-6 gap-3 mb-10">
        <StatTile
          label={`Hours in ${CURRENT_YEAR}`}
          value={totalHoursYear.toFixed(0)}
          unit="hours"
          icon={<Clock size={14} className="text-accent" />}
          hint={`${totalHoursAll.toFixed(0)} all-time`}
          accent
        />
        <StatTile
          label="Movies played"
          value={moviesCount.toString()}
          icon={<Film size={14} className="text-accent" />}
        />
        <StatTile
          label="Episodes played"
          value={episodesCount.toString()}
          icon={<Tv size={14} className="text-accent" />}
        />
        <StatTile
          label="Time saved skipping"
          value={formatTimeSaved(timeSaved.total)}
          icon={<Activity size={14} className="text-accent" />}
          hint={timeSaved.series > 0 ? `across ${timeSaved.series} ${timeSaved.series === 1 ? 'show' : 'shows'}` : 'no skips yet'}
        />
        <StatTile
          label="Current streak"
          value={String(streak.current)}
          unit={streak.current === 1 ? 'day' : 'days'}
          icon={<Flame size={14} className="text-accent" />}
          hint={streak.longest > streak.current ? `Best: ${streak.longest}` : 'Keep going'}
        />
        <StatTile
          label="Diary entries"
          value={String(diaryYearCount)}
          unit={diaryYearCount === 1 ? `entry in ${CURRENT_YEAR}` : `entries in ${CURRENT_YEAR}`}
          icon={<CalendarStar size={14} className="text-accent" />}
        />
      </div>

      {/* Two-column: hours per genre + hours per studio */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-10">
        <Section title="Hours by genre" empty={hoursGenre.length === 0 ? 'No genre runtime data yet.' : null}>
          <div className="space-y-2">
            {hoursGenre.map((g, i) => (
              <Bar key={g.label} label={g.label} share={g.share} index={i} suffix={`${g.hours.toFixed(0)}h`} />
            ))}
          </div>
        </Section>
        <Section title="Top studios" empty={hoursStudio.length === 0 ? 'No studio info on your library.' : null}>
          <div className="space-y-2">
            {hoursStudio.map((s, i) => (
              <Bar key={s.label} label={s.label} share={s.share} index={i} suffix={`${s.hours.toFixed(0)}h`} />
            ))}
          </div>
        </Section>
      </div>

      {/* Completion ratios */}
      <Section title="Completion" className="mb-10">
        <div className="grid grid-cols-3 gap-3">
          <CompletionTile label="Finished" value={comp.completed} total={comp.total} accent />
          <CompletionTile label="In progress" value={comp.inProgress} total={comp.total} />
          <CompletionTile label="Untouched" value={comp.unstarted} total={comp.total} />
        </div>
        <p className="mt-3 text-[12px] text-text-3 tabular-nums">
          {(comp.completionRate * 100).toFixed(1)}% of tracked items reached the finish line.
        </p>
      </Section>

      {/* People */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-10">
        <Section title="Most-watched directors" empty={topDirectors.length === 0 ? 'No director credits on items.' : null}>
          <PersonList rows={topDirectors} onClick={n => navigate(`/search?q=${encodeURIComponent(n)}`)} />
        </Section>
        <Section title="Most-seen actors" empty={topActors.length === 0 ? 'No cast info on items.' : null}>
          <PersonList rows={topActors} onClick={n => navigate(`/search?q=${encodeURIComponent(n)}`)} />
        </Section>
      </div>

      {/* Side note: longest binge + breakdown */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-10">
        <Section title="Longest binge">
          {binge.count > 0 ? (
            <div>
              <p className="text-[28px] font-display font-bold text-text-1 tabular-nums leading-none">
                {binge.count} <span className="text-[14px] font-medium text-text-3">items in one day</span>
              </p>
              <p className="text-[12.5px] text-text-3 mt-2">
                On {binge.day ? new Date(binge.day + 'T00:00:00').toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' }) : 'unknown'}.
              </p>
            </div>
          ) : (
            <p className="text-[12.5px] text-text-3">No watched items yet.</p>
          )}
        </Section>
        <Section title="Genre share (by count)" empty={genreShare.length === 0 ? null : null}>
          <div className="space-y-2">
            {genreShare.map((g, i) => (
              <Bar key={g.genre} label={g.genre} share={g.share} index={i} suffix={`${g.count}`} />
            ))}
          </div>
        </Section>
      </div>

      {/* Time saved breakdown */}
      <Section title="Time saved" className="mb-10">
        {timeSaved.total > 0 ? (
          <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
            <BadgeTile label="Total" value={formatTimeSaved(timeSaved.total)} icon={<Award size={14} className="text-accent" />} />
            <BadgeTile label="Intros skipped" value={formatTimeSaved(timeSaved.intros)} />
            <BadgeTile label="Credits skipped" value={formatTimeSaved(timeSaved.credits)} />
          </div>
        ) : (
          <p className="text-[12.5px] text-text-3">No auto-skips recorded yet. Turn intro / credits skipping on in Playback settings.</p>
        )}
      </Section>
    </div>
  )
}

function StatTile({
  label,
  value,
  unit,
  hint,
  icon,
  accent,
}: {
  label: string
  value: string
  unit?: string
  hint?: string
  icon?: React.ReactNode
  accent?: boolean
}) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 6 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}
      className={`rounded-xl p-4 ring-1 ${
        accent ? 'bg-accent/10 ring-accent/30' : 'bg-elevated/40 ring-border'
      }`}
    >
      <div className="flex items-center gap-2 text-[10.5px] uppercase tracking-[0.16em] font-semibold text-text-3 mb-2">
        {icon}
        {label}
      </div>
      <div className="flex items-baseline gap-1.5">
        <span className="font-display text-[26px] font-bold text-text-1 tabular-nums leading-none">
          {value}
        </span>
        {unit && <span className="text-[12px] text-text-3 tracking-tight">{unit}</span>}
      </div>
      {hint && <p className="text-[11px] text-text-4 mt-1.5 tracking-tight">{hint}</p>}
    </motion.div>
  )
}

function Section({
  title,
  children,
  empty,
  className,
}: {
  title: string
  children: React.ReactNode
  empty?: string | null
  className?: string
}) {
  return (
    <section className={`rounded-xl bg-elevated/30 border border-border p-5 ${className || ''}`}>
      <h2 className="text-[13px] font-semibold text-text-1 mb-3 tracking-tight">{title}</h2>
      {empty ? <p className="text-[12.5px] text-text-3">{empty}</p> : children}
    </section>
  )
}

function Bar({
  label,
  share,
  index,
  suffix,
}: {
  label: string
  share: number
  index: number
  suffix?: string
}) {
  const pct = Math.max(2, Math.round(share * 100))
  return (
    <motion.div
      initial={{ opacity: 0, x: -6 }}
      animate={{ opacity: 1, x: 0 }}
      transition={{ duration: 0.3, delay: Math.min(index * 0.04, 0.4) }}
      className="flex items-center gap-3 text-[12px]"
    >
      <span className="w-32 shrink-0 text-text-2 font-medium tracking-tight truncate">
        {label}
      </span>
      <div className="flex-1 h-2.5 rounded-full bg-elevated/60 overflow-hidden">
        <motion.div
          initial={{ width: 0 }}
          animate={{ width: `${pct}%` }}
          transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
          className="h-full bg-accent"
        />
      </div>
      <span className="w-16 shrink-0 text-right text-text-3 tabular-nums">
        {suffix ?? `${pct}%`}
      </span>
    </motion.div>
  )
}

function CompletionTile({
  label,
  value,
  total,
  accent,
}: {
  label: string
  value: number
  total: number
  accent?: boolean
}) {
  const pct = total > 0 ? Math.round((value / total) * 100) : 0
  return (
    <div className={`rounded-lg p-4 ring-1 ${accent ? 'bg-accent/8 ring-accent/25' : 'bg-elevated/40 ring-border'}`}>
      <p className="text-[10.5px] uppercase tracking-[0.16em] font-semibold text-text-3 mb-1.5">{label}</p>
      <p className="font-display text-[22px] font-bold text-text-1 tabular-nums leading-none">
        {value.toLocaleString()}
      </p>
      <p className="text-[11px] text-text-4 mt-1 tabular-nums">{pct}%</p>
    </div>
  )
}

function PersonList({
  rows,
  onClick,
}: {
  rows: { name: string; count: number }[]
  onClick: (name: string) => void
}) {
  return (
    <ol className="space-y-1.5">
      {rows.map((p, i) => (
        <li key={p.name}>
          <button
            onClick={() => onClick(p.name)}
            className="w-full flex items-center gap-3 px-2 py-1.5 rounded-md hover:bg-white/4 transition-colors text-left focus-ring"
          >
            <span className="w-6 h-6 grid place-items-center rounded-full bg-accent/15 text-accent text-[10.5px] font-bold tabular-nums shrink-0">
              {i + 1}
            </span>
            <span className="flex-1 text-[12.5px] text-text-1 font-medium truncate tracking-tight">
              {p.name}
            </span>
            <span className="text-[11px] text-text-3 tabular-nums">
              {p.count} {p.count === 1 ? 'item' : 'items'}
            </span>
          </button>
        </li>
      ))}
    </ol>
  )
}

function BadgeTile({
  label,
  value,
  icon,
}: {
  label: string
  value: string
  icon?: React.ReactNode
}) {
  return (
    <div className="rounded-lg p-3.5 ring-1 ring-border bg-elevated/40">
      <p className="text-[10.5px] uppercase tracking-[0.16em] font-semibold text-text-3 mb-1.5 flex items-center gap-1.5">
        {icon}
        {label}
      </p>
      <p className="font-display text-[20px] font-bold text-text-1 tabular-nums leading-none">{value}</p>
    </div>
  )
}
