import { useEffect, useRef, useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { Type } from '../../lib/icons'
import { usePreferencesStore } from '../../stores/preferences-store'
import { usePlayerRuntimeStore } from '../../stores/player-runtime-store'
import { subtitleClasses } from '../../lib/subtitle-style'
import type { AppSettings } from '../../api/types'

/**
 * Floating panel inside the player that exposes the same subtitle-styling
 * controls as the Settings page, so users can fine-tune captions without
 * leaving playback. Writes straight to the preferences store, so changes
 * apply live everywhere the styling hook is consumed.
 */
export default function SubtitleStyleMenu() {
  const [open, setOpen] = useState(false)
  const ref = useRef<HTMLDivElement>(null)
  const prefs = usePreferencesStore()

  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])

  const preview = subtitleClasses({
    subtitleFontSize: prefs.subtitleFontSize,
    subtitleFontFamily: prefs.subtitleFontFamily,
    subtitleBackground: prefs.subtitleBackground,
    subtitleEdge: prefs.subtitleEdge,
    subtitlePosition: prefs.subtitlePosition,
    subtitleColor: prefs.subtitleColor,
  })
  const previewCls = preview.className.replace(/\babsolute\b|\binset-x-0\b|\bbottom-32\b|\btop-24\b|\bpx-7\b/g, '')

  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 ${
          open ? 'bg-white/15 text-white' : ''
        }`}
        aria-haspopup="dialog"
        aria-expanded={open}
        aria-label="Subtitle appearance"
      >
        <Type size={17} />
      </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="dialog"
            className="absolute right-0 top-full mt-2 w-[340px] max-h-[min(80vh,560px)] 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">
                Subtitle appearance
              </p>
            </div>
            <div className="p-3 space-y-3">
              <Field label={`Size (${prefs.subtitleFontSize}px)`}>
                <input
                  type="range"
                  min={12}
                  max={72}
                  step={1}
                  value={prefs.subtitleFontSize}
                  onChange={e => prefs.setPreference('subtitleFontSize', Number(e.target.value))}
                  className="subtitle-size-slider w-full h-7 appearance-none bg-transparent cursor-pointer"
                />
                <div className="flex justify-between text-[9px] text-white/40 -mt-0.5 px-0.5">
                  <span>12px</span>
                  <span>72px</span>
                </div>
              </Field>
              <Field label="Background">
                <Seg
                  value={prefs.subtitleBackground}
                  onChange={v => prefs.setPreference('subtitleBackground', v as AppSettings['subtitleBackground'])}
                  options={[
                    { value: 'none', label: 'None' },
                    { value: 'subtle', label: 'Subtle' },
                    { value: 'solid', label: 'Solid' },
                  ]}
                />
              </Field>
              <Field label="Edge">
                <Seg
                  value={prefs.subtitleEdge}
                  onChange={v => prefs.setPreference('subtitleEdge', v as AppSettings['subtitleEdge'])}
                  options={[
                    { value: 'none', label: 'None' },
                    { value: 'shadow', label: 'Shadow' },
                    { value: 'outline', label: 'Outline' },
                  ]}
                />
              </Field>
              <Field label="Position">
                <Seg
                  value={prefs.subtitlePosition}
                  onChange={v => prefs.setPreference('subtitlePosition', v as AppSettings['subtitlePosition'])}
                  options={[
                    { value: 'bottom', label: 'Bottom' },
                    { value: 'top', label: 'Top' },
                  ]}
                />
              </Field>
              <Field label="Colour">
                <Seg
                  value={prefs.subtitleColor}
                  onChange={v => prefs.setPreference('subtitleColor', v as AppSettings['subtitleColor'])}
                  options={[
                    { value: 'white', label: 'White' },
                    { value: 'yellow', label: 'Yellow' },
                    { value: 'cyan', label: 'Cyan' },
                  ]}
                />
              </Field>
              <Field label="Font">
                <Seg
                  value={prefs.subtitleFontFamily}
                  onChange={v => prefs.setPreference('subtitleFontFamily', v as AppSettings['subtitleFontFamily'])}
                  options={[
                    { value: 'sans', label: 'Sans' },
                    { value: 'serif', label: 'Display' },
                    { value: 'mono', label: 'Mono' },
                  ]}
                />
              </Field>

              <SyncRow />

              <div className="pt-1">
                <p className="text-[10px] uppercase tracking-[0.14em] font-semibold text-white/45 mb-1.5">
                  Preview
                </p>
                <div className="relative h-20 rounded-md overflow-hidden bg-[radial-gradient(ellipse_at_30%_20%,rgba(245,182,66,0.15),transparent_55%),linear-gradient(180deg,#1a1610,#0c0a08)] grid place-items-center">
                  <div className={previewCls} style={preview.style}>
                    <span data-cue>Sample subtitle text</span>
                  </div>
                </div>
              </div>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  )
}

function SyncRow() {
  const offsetMs = usePlayerRuntimeStore(s => s.subtitleOffsetMs)
  const bump = usePlayerRuntimeStore(s => s.bumpSubtitleOffsetMs)
  const reset = usePlayerRuntimeStore(s => s.setSubtitleOffsetMs)
  const display = `${offsetMs >= 0 ? '+' : ''}${(offsetMs / 1000).toFixed(2)}s`
  return (
    <Field label="Sync (this session)">
      <div className="flex items-center gap-1.5">
        <button
          onClick={() => bump(-100)}
          className="h-7 px-2.5 rounded bg-white/8 hover:bg-white/14 text-[11.5px] font-medium text-white/85 hover:text-white transition-colors focus-ring"
          aria-label="Subtitles earlier 100ms"
        >
          −100ms
        </button>
        <button
          onClick={() => reset(0)}
          className="flex-1 h-7 px-2.5 rounded text-[11.5px] font-mono font-semibold tabular-nums bg-void/60 border border-border text-text-1 hover:bg-void transition-colors focus-ring"
          title="Click to reset"
        >
          {display}
        </button>
        <button
          onClick={() => bump(100)}
          className="h-7 px-2.5 rounded bg-white/8 hover:bg-white/14 text-[11.5px] font-medium text-white/85 hover:text-white transition-colors focus-ring"
          aria-label="Subtitles later 100ms"
        >
          +100ms
        </button>
      </div>
    </Field>
  )
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div>
      <p className="text-[10.5px] font-medium text-white/55 mb-1 tracking-wide uppercase">{label}</p>
      {children}
    </div>
  )
}

function Seg<T extends string>({
  value,
  options,
  onChange,
}: {
  value: T
  options: { value: T; label: string }[]
  onChange: (v: T) => void
}) {
  return (
    <div className="inline-flex w-full p-0.5 bg-white/8 border border-white/10 rounded-md">
      {options.map(o => {
        const active = o.value === value
        return (
          <button
            key={o.value}
            onClick={() => onChange(o.value)}
            className={`flex-1 h-7 px-2 rounded text-[11.5px] font-medium tracking-tight transition-colors ${
              active ? 'bg-white text-void' : 'text-white/75 hover:text-white hover:bg-white/8'
            }`}
          >
            {o.label}
          </button>
        )
      })}
    </div>
  )
}
