import { useEffect, useRef } from 'react';

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

function getFocusableElements(container) {
  return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
    (el) => !el.disabled && el.getAttribute('aria-hidden') !== 'true'
  );
}

/**
 * Trap focus inside a container while `active` and restore focus on close.
 * Returns a ref to attach to the dialog panel (not the backdrop).
 *
 * Used by pre-Liquid-Glass call sites (e.g. ScannerPageView) where the
 * caller wants the hook to own the container ref. New code that needs
 * to share / forward the panel ref should use the default export
 * `useFocusTrapContainer` instead — see Modal.js for the pattern.
 */
export function useFocusTrap(active) {
  const containerRef = useRef(null);
  const previouslyFocusedRef = useRef(null);

  useEffect(() => {
    if (!active) return undefined;

    previouslyFocusedRef.current = document.activeElement;
    const container = containerRef.current;
    if (!container) return undefined;

    const focusFirst = () => {
      const nodes = getFocusableElements(container);
      nodes[0]?.focus();
    };

    focusFirst();

    const handleKeyDown = (event) => {
      if (event.key !== 'Tab') return;

      const nodes = getFocusableElements(container);
      if (nodes.length === 0) return;

      const first = nodes[0];
      const last = nodes[nodes.length - 1];

      if (event.shiftKey && document.activeElement === first) {
        event.preventDefault();
        last.focus();
      } else if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault();
        first.focus();
      }
    };

    document.addEventListener('keydown', handleKeyDown);

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
      const previous = previouslyFocusedRef.current;
      if (previous && typeof previous.focus === 'function') {
        previous.focus();
      }
    };
  }, [active]);

  return containerRef;
}

const NEW_FOCUSABLE = [
  'a[href]',
  'button:not([disabled])',
  'input:not([disabled]):not([type="hidden"])',
  'select:not([disabled])',
  'textarea:not([disabled])',
  '[tabindex]:not([tabindex="-1"])',
  '[contenteditable="true"]',
].join(',');

/**
 * Focus-trap variant for the `<Modal>` primitive in components/ui/.
 * Takes a caller-owned containerRef + optional initialFocusRef, so the
 * panel ref can be forwarded through GlassSurface / forwardRef chains
 * without colliding with the hook's internal ref ownership.
 */
export default function useFocusTrapContainer({
  active,
  containerRef,
  initialFocusRef,
  restoreFocus = true,
}) {
  const previousActiveElement = useRef(null);

  useEffect(() => {
    if (!active) return undefined;
    previousActiveElement.current = document.activeElement;

    const container = containerRef.current;
    if (!container) return undefined;

    const focusTarget =
      initialFocusRef?.current ??
      container.querySelector(NEW_FOCUSABLE) ??
      container;
    if (focusTarget && typeof focusTarget.focus === 'function') {
      if (focusTarget === container && !container.hasAttribute('tabindex')) {
        container.setAttribute('tabindex', '-1');
      }
      focusTarget.focus({ preventScroll: true });
    }

    const handleKeyDown = (e) => {
      if (e.key !== 'Tab') return;
      const focusable = Array.from(container.querySelectorAll(NEW_FOCUSABLE));
      if (focusable.length === 0) {
        e.preventDefault();
        return;
      }
      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault();
        last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault();
        first.focus();
      }
    };

    document.addEventListener('keydown', handleKeyDown);

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
      if (
        restoreFocus &&
        previousActiveElement.current &&
        typeof previousActiveElement.current.focus === 'function'
      ) {
        previousActiveElement.current.focus({ preventScroll: true });
      }
    };
  }, [active, containerRef, initialFocusRef, restoreFocus]);
}
