import { useEffect, useRef, useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { MonitorPlay, Tv, Loader2 } from '../../lib/icons'
import { listCastTargets, sendToSession, type CastTarget } from '../../lib/cast'
import { toast } from '../../stores/toast-store'

interface Props {
  itemId: string
  mediaType?: string
}

/**
 * "Play on..." picker. Pops a small list of other Jellyfin sessions that
 * advertise SupportsRemoteControl, filtered by what they can play. Click
 * a target to fire `Sessions/{id}/Playing` and hand the item off.
 */
export default function CastMenu({ itemId, mediaType }: Props) {
  const [open, setOpen] = useState(false)
  const [loading, setLoading] = useState(false)
  const [targets, setTargets] = useState<CastTarget[]>([])
  const [sendingTo, setSendingTo] = useState<string | null>(null)
  const wrapRef = useRef<HTMLDivElement | null>(null)

  useEffect(() => {
    if (!open) return
    function onDocClick(e: MouseEvent) {
      if (!wrapRef.current) return
      if (e.target instanceof Node && !wrapRef.current.contains(e.target)) {
        setOpen(false)
      }
    }
    function onEsc(e: KeyboardEvent) {
      if (e.key === 'Escape') setOpen(false)
    }
    document.addEventListener('mousedown', onDocClick)
    document.addEventListener('keydown', onEsc)
    return () => {
      document.removeEventListener('mousedown', onDocClick)
      document.removeEventListener('keydown', onEsc)
    }
  }, [open])

  useEffect(() => {
    if (!open) return
    let cancelled = false
    setLoading(true)
    listCastTargets(mediaType)
      .then(t => {
        if (!cancelled) setTargets(t)
      })
      .catch(() => {
        if (!cancelled) setTargets([])
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })
    return () => {
      cancelled = true
    }
  }, [open, mediaType])

  async function castTo(target: CastTarget) {
    setSendingTo(target.sessionId)
    try {
      await sendToSession(target.sessionId, itemId)
      toast(`Sent to ${target.deviceName}`, 'success')
      setOpen(false)
    } catch {
      toast('Could not send to that device', 'error')
    } finally {
      setSendingTo(null)
    }
  }

  return (
    <div ref={wrapRef} className="relative">
      <button
        onClick={() => setOpen(o => !o)}
        aria-label="Play on another device"
        title="Play on another device"
        aria-expanded={open}
        className={`w-11 h-11 rounded-lg backdrop-blur grid place-items-center transition-all duration-200 hover:scale-105 active:scale-95 focus-ring ${
          open
            ? 'bg-accent/15 border border-accent/30'
            : 'bg-white/10 border border-white/15 hover:bg-white/15'
        }`}
      >
        <MonitorPlay size={16} className="text-white/80" />
      </button>

      <AnimatePresence>
        {open && (
          <motion.div
            initial={{ opacity: 0, y: 6, scale: 0.97 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: 6, scale: 0.97 }}
            transition={{ duration: 0.18, ease: [0.16, 1, 0.3, 1] }}
            className="absolute bottom-full mb-2 right-0 w-[280px] z-30 bg-[#0c0a08]/96 backdrop-blur-xl border border-white/14 rounded-xl shadow-[0_20px_50px_-15px_rgba(0,0,0,0.7)] overflow-hidden"
            role="menu"
          >
            <div className="px-3.5 pt-3 pb-2 border-b border-white/8">
              <p className="text-[10px] uppercase tracking-[0.16em] font-semibold text-white/55">
                Play on
              </p>
            </div>
            <div className="max-h-[280px] overflow-y-auto content-scroll py-1.5">
              {loading && (
                <div className="px-3.5 py-4 flex items-center gap-2 text-[12px] text-white/60">
                  <Loader2 size={13} className="animate-spin" />
                  Looking for devices...
                </div>
              )}
              {!loading && targets.length === 0 && (
                <p className="px-3.5 py-4 text-[12px] text-white/55 leading-snug">
                  No other devices are signed in to this server right now.
                </p>
              )}
              {!loading &&
                targets.map(t => {
                  const isSending = sendingTo === t.sessionId
                  return (
                    <button
                      key={t.sessionId}
                      onClick={() => castTo(t)}
                      disabled={!!sendingTo}
                      className="w-full flex items-center gap-3 px-3.5 py-2.5 text-left hover:bg-white/6 transition-colors disabled:opacity-50 focus-ring"
                    >
                      <span className="w-8 h-8 rounded-md bg-white/8 grid place-items-center shrink-0">
                        {isSending ? (
                          <Loader2 size={13} className="text-white/70 animate-spin" />
                        ) : (
                          <Tv size={14} className="text-white/70" />
                        )}
                      </span>
                      <span className="flex-1 min-w-0">
                        <span className="block text-[12.5px] font-medium text-white tracking-tight truncate">
                          {t.deviceName}
                        </span>
                        <span className="block text-[10.5px] text-white/50 truncate">
                          {[t.client, t.userName].filter(Boolean).join(' - ')}
                        </span>
                      </span>
                    </button>
                  )
                })}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  )
}
