import { useEffect, useRef, useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { Check } from '../../lib/icons'
import {
  audioFormatLabel,
  subtitleLabel,
} from '../../lib/jellyfin-meta'
import { languageLabel } from '../../lib/format'

interface Track {
  Index?: number
  Codec?: string | null
  Profile?: string | null
  Language?: string | null
  Title?: string | null
  Channels?: number | null
  ChannelLayout?: string | null
  IsDefault?: boolean | null
  IsForced?: boolean | null
  IsHearingImpaired?: boolean | null
  IsExternal?: boolean | null
  AudioSpatialFormat?: string | null
  Type?: string
}

interface Props {
  trigger: React.ReactNode
  title: string
  tracks: Track[]
  selectedIndex: number | null
  onSelect: (index: number | null) => void
  variant: 'audio' | 'subtitle'
}

export default function TrackMenu({
  trigger,
  title,
  tracks,
  selectedIndex,
  onSelect,
  variant,
}: Props) {
  const [open, setOpen] = useState(false)
  const ref = useRef<HTMLDivElement>(null)

  useEffect(() => {
    function onDoc(e: MouseEvent) {
      if (!ref.current) return
      if (!ref.current.contains(e.target as Node)) setOpen(false)
    }
    if (open) {
      window.addEventListener('mousedown', onDoc)
      return () => window.removeEventListener('mousedown', onDoc)
    }
  }, [open])

  return (
    <div ref={ref} className="relative">
      <button
        onClick={() => setOpen(o => !o)}
        className="w-9 h-9 rounded-full grid place-items-center text-white/85 hover:text-white hover:bg-white/10 transition-colors focus-ring"
        aria-haspopup="listbox"
        aria-expanded={open}
        aria-label={title}
      >
        {trigger}
      </button>
      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ opacity: 0, y: -4, scale: 0.96 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: -4, scale: 0.96 }}
            transition={{ duration: 0.15, ease: [0.16, 1, 0.3, 1] }}
            role="listbox"
            className="absolute right-0 top-full mt-2 w-72 max-h-[min(60vh,420px)] overflow-y-auto content-scroll bg-black/85 backdrop-blur-xl border border-white/12 rounded-lg shadow-2xl"
          >
            <div className="sticky top-0 px-3 py-2.5 bg-black/90 border-b border-white/8 z-10">
              <p className="text-[10px] uppercase tracking-[0.14em] font-semibold text-white/60">
                {title}
              </p>
            </div>
            <div className="p-1">
              {variant === 'subtitle' && (
                <TrackOption
                  selected={selectedIndex === null}
                  onClick={() => {
                    onSelect(null)
                    setOpen(false)
                  }}
                  primary="Off"
                />
              )}
              {tracks.length === 0 && (
                <p className="px-3 py-3 text-[12px] text-white/55">No tracks available</p>
              )}
              {tracks.map(t => {
                const idx = t.Index ?? -1
                const selected = selectedIndex === idx
                const primary =
                  variant === 'audio'
                    ? audioFormatLabel(t) || t.Title || 'Unknown'
                    : subtitleLabel(t)
                const secondary =
                  variant === 'audio'
                    ? [languageLabel(t.Language), t.IsDefault && 'Default']
                        .filter(Boolean)
                        .join(' · ')
                    : [t.Codec?.toUpperCase(), t.IsExternal && 'External']
                        .filter(Boolean)
                        .join(' · ')
                return (
                  <TrackOption
                    key={idx}
                    selected={selected}
                    onClick={() => {
                      onSelect(idx)
                      setOpen(false)
                    }}
                    primary={primary}
                    secondary={secondary}
                  />
                )
              })}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  )
}

function TrackOption({
  selected,
  onClick,
  primary,
  secondary,
}: {
  selected: boolean
  onClick: () => void
  primary: string
  secondary?: string
}) {
  return (
    <button
      onClick={onClick}
      role="option"
      aria-selected={selected}
      className={`w-full flex items-center gap-2 px-2.5 py-2 rounded-md text-left transition-colors duration-100 focus-ring ${
        selected ? 'bg-accent/15' : 'hover:bg-white/8'
      }`}
    >
      <span
        className={`w-4 h-4 grid place-items-center shrink-0 ${
          selected ? 'text-accent' : 'text-transparent'
        }`}
      >
        <Check size={13} strokeWidth={2.5} />
      </span>
      <span className="flex-1 min-w-0">
        <span
          className={`block text-[12.5px] font-medium truncate ${
            selected ? 'text-accent' : 'text-white'
          }`}
        >
          {primary}
        </span>
        {secondary && <span className="block text-[10.5px] text-white/55 truncate">{secondary}</span>}
      </span>
    </button>
  )
}
