// <Dialog> — a generic modal overlay, native `<dialog>` element rather
// than a hand-rolled focus-trap + backdrop: `showModal()` gives focus
// trapping, Escape-to-close, and a real `::backdrop` for free, and
// `@hive/shared`'s own shadow-DOM `hive-dialog` custom element isn't an
// option here — swarm-ui's esbuild config can't consume those custom
// elements at all (a separate, already-tracked gap).
// No opinion on content beyond a close button; the caller's own markup
// supplies whatever heading/layout it needs (its first real caller,
// the create-agent form, already has an established two-panel layout
// from its former life as a standalone route — reusing that unchanged
// is simpler and lower-risk than re-deriving a modal-specific layout
// for content mara has already reviewed).
import { useEffect, useRef } from 'preact/hooks';
import type { ComponentChildren } from 'preact';
import './Dialog.css';

export function Dialog({
  open,
  onClose,
  label,
  children,
}: {
  open: boolean;
  onClose: () => void;
  // `aria-label` only, no visible title row — see file-top comment on
  // why content owns its own heading.
  label: string;
  children: ComponentChildren;
}) {
  const ref = useRef<HTMLDialogElement>(null);

  // Drives the native open/closed state from the `open` prop rather
  // than mounting/unmounting the element — `showModal()`/`close()` are
  // imperative, there's no declarative `<dialog open>` equivalent that
  // also gets you the backdrop + focus trap.
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (open && !el.open) el.showModal();
    else if (!open && el.open) el.close();
  }, [open]);

  // The dialog's own `close` event fires on Escape (and would fire on
  // a native <form method="dialog"> submit, unused here) — syncing it
  // back to the caller's state keeps `open` truthful even when nothing
  // in this component's own JS drove the close.
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    function handleClose() {
      onClose();
    }
    el.addEventListener('close', handleClose);
    return () => el.removeEventListener('close', handleClose);
  }, [onClose]);

  return (
    <dialog
      ref={ref}
      class="ui-dialog"
      aria-label={label}
      // A click lands on the `<dialog>` element itself (not any child)
      // exactly when it's outside the rendered content box — inside
      // the box, the click target is always some descendant. Standard
      // "click the backdrop to close" trick for native `<dialog>`.
      onClick={(e) => {
        if (e.target === ref.current) onClose();
      }}
    >
      <button type="button" class="ui-dialog-close" aria-label="close" onClick={onClose}>
        ✕
      </button>
      <div class="ui-dialog-body">{children}</div>
    </dialog>
  );
}
