import { useEffect, useRef, type ReactNode } from 'react'

/**
 * A centered modal dialog over a dimmed backdrop. Closes on Escape or a backdrop
 * click, unless `busy` (a mutation is in flight) — then it stays put so the
 * action can finish and report. The caller owns open/closed state (render only
 * when open).
 */
export function Modal({
  title,
  onClose,
  busy = false,
  children,
}: {
  title: string
  onClose: () => void
  busy?: boolean
  children: ReactNode
}) {
  const cardRef = useRef<HTMLDivElement>(null)
  // Keep the latest onClose/busy in refs so the mount-only effect below never
  // re-runs (which would re-attach the listener and steal focus on every parent
  // re-render, e.g. during a background refetch).
  const onCloseRef = useRef(onClose)
  onCloseRef.current = onClose
  const busyRef = useRef(busy)
  busyRef.current = busy

  useEffect(() => {
    cardRef.current?.focus()
    function onKey(e: KeyboardEvent) {
      if (e.key === 'Escape' && !busyRef.current) onCloseRef.current()
    }
    document.addEventListener('keydown', onKey)
    return () => document.removeEventListener('keydown', onKey)
  }, [])

  return (
    <div
      className="fixed inset-0 z-50 flex items-end justify-center bg-black/40 p-4 sm:items-center"
      onMouseDown={(e) => {
        if (e.target === e.currentTarget && !busy) onClose()
      }}
    >
      <div
        ref={cardRef}
        role="dialog"
        aria-modal="true"
        aria-label={title}
        tabIndex={-1}
        className="w-full max-w-md rounded-xl border border-border bg-surface p-6 shadow-lg outline-none"
      >
        <h2 className="text-lg font-semibold tracking-tight text-fg">{title}</h2>
        <div className="mt-4">{children}</div>
      </div>
    </div>
  )
}
