import { useRef, useEffect } from 'react';

const FOCUSABLE_SELECTOR = [
    'a[href]',
    'button:not([disabled])',
    'input:not([disabled])',
    'select:not([disabled])',
    'textarea:not([disabled])',
    '[tabindex]:not([tabindex="-1"])',
    '[data-autofocus]',
].join(', ');
/**
 * Traps focus within the given container element when active.
 *
 * - Tab / Shift+Tab cycles through focusable elements inside the container.
 * - Initial focus is given to `[data-autofocus]` if present, otherwise the
 *   first focusable element.
 * - When deactivated, focus is returned to the previously focused element.
 */
function useFocusTrap(containerRef, isActive) {
    const previouslyFocusedRef = useRef(null);
    useEffect(() => {
        if (!isActive)
            return;
        // Store the element that had focus before the trap activated
        previouslyFocusedRef.current = document.activeElement;
        const container = containerRef.current;
        if (!container)
            return;
        // Set initial focus
        const setInitialFocus = () => {
            const autofocus = container.querySelector('[data-autofocus]');
            if (autofocus) {
                autofocus.focus();
                return;
            }
            const focusable = container.querySelectorAll(FOCUSABLE_SELECTOR);
            if (focusable.length > 0) {
                focusable[0].focus();
            }
        };
        // Small delay to let the DOM settle (e.g. after animations)
        const rafId = requestAnimationFrame(setInitialFocus);
        const handleKeyDown = (e) => {
            if (e.key !== 'Tab')
                return;
            const focusable = container.querySelectorAll(FOCUSABLE_SELECTOR);
            if (focusable.length === 0)
                return;
            const first = focusable[0];
            const last = focusable[focusable.length - 1];
            if (e.shiftKey) {
                // Shift+Tab: wrap to last element
                if (document.activeElement === first) {
                    e.preventDefault();
                    last.focus();
                }
            }
            else {
                // Tab: wrap to first element
                if (document.activeElement === last) {
                    e.preventDefault();
                    first.focus();
                }
            }
        };
        container.addEventListener('keydown', handleKeyDown);
        return () => {
            cancelAnimationFrame(rafId);
            container.removeEventListener('keydown', handleKeyDown);
            // Restore focus to the previously focused element
            if (previouslyFocusedRef.current && typeof previouslyFocusedRef.current.focus === 'function') {
                previouslyFocusedRef.current.focus();
            }
        };
    }, [isActive, containerRef]);
}

export { useFocusTrap };
