import { useEffect, useRef } from 'react';

const FOCUSABLE =
  'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), ' +
  'textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';

/**
 * Trap keyboard focus within an overlay while `active` (docs/architecture/03 →
 * Shell). On activation it remembers the previously focused element and moves
 * focus into the container; `Tab`/`Shift+Tab` cycle within it; on deactivation
 * focus returns to the trigger. Shared by every overlay (the confirm dialog now,
 * the feature-modal shell later) so accessibility is implemented once.
 *
 * `initialSelector` optionally picks which child receives focus on open
 * (e.g. the Cancel button for a destructive confirm); it falls back to the
 * first focusable child.
 */
export function useFocusTrap<T extends HTMLElement = HTMLDivElement>(
  active: boolean,
  initialSelector?: string,
) {
  const ref = useRef<T>(null);
  const returnTo = useRef<Element | null>(null);

  useEffect(() => {
    const el = ref.current;
    if (!active || !el) return;

    returnTo.current = document.activeElement;
    const initial =
      (initialSelector ? el.querySelector<HTMLElement>(initialSelector) : null) ??
      el.querySelector<HTMLElement>(FOCUSABLE);
    initial?.focus();

    const onKey = (e: KeyboardEvent) => {
      if (e.key !== 'Tab') return;
      const f = el.querySelectorAll<HTMLElement>(FOCUSABLE);
      if (!f.length) return;
      const first = f[0];
      const last = f[f.length - 1];
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault();
        last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault();
        first.focus();
      }
    };

    el.addEventListener('keydown', onKey);
    return () => {
      el.removeEventListener('keydown', onKey);
      (returnTo.current as HTMLElement | null)?.focus();
    };
  }, [active, initialSelector]);

  return ref;
}
