import { jsx, jsxs } from 'react/jsx-runtime';
import React__default, { useRef } from 'react';
import { createPortal } from 'react-dom';
import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
import { cn } from '../../../utils/cn.js';
import { useOverlay } from '../../../hooks/useOverlay.js';
import { useFocusTrap } from '../../../hooks/useFocusTrap.js';
import { useIsClient } from '../../../hooks/useIsClient.js';
import { overlayTheme, overlayPositionVariants } from './Overlay.theme.js';

/**
 * Default overlay backdrop animation variants
 */
const defaultOverlayAnimations = {
    initial: { opacity: 0 },
    animate: {
        opacity: 1,
        transition: { duration: 0.2, ease: "easeOut" },
    },
    exit: {
        opacity: 0,
        transition: { duration: 0.15, ease: "easeIn" },
    },
};
/**
 * Default content animation variants (center position)
 */
const defaultContentAnimations = {
    initial: { opacity: 0, scale: 0.95, y: 20 },
    animate: {
        opacity: 1,
        scale: 1,
        y: 0,
        transition: {
            type: "spring",
            damping: 25,
            stiffness: 300,
            delay: 0.05,
        },
    },
    exit: {
        opacity: 0,
        scale: 0.95,
        y: 20,
        transition: { duration: 0.2, ease: "easeIn" },
    },
};
/**
 * Shared Overlay Component
 *
 * Provides consistent overlay behavior (backdrop, portal, animations, escape key, scroll lock)
 * across Modal, Drawer, CommandPalette, and other overlay-based components.
 *
 * Features:
 * - Portal rendering to document.body
 * - Configurable positioning (center, top, bottom, left, right, none)
 * - Customizable animations
 * - Body scroll lock when open
 * - Escape key to close
 * - Click outside to close
 * - Accessible by default
 *
 * @example
 * ```tsx
 * <Overlay
 *   isOpen={isOpen}
 *   onClose={onClose}
 *   position="center"
 * >
 *   <div className="bg-white rounded-lg p-6">
 *     Modal content
 *   </div>
 * </Overlay>
 * ```
 */
const Overlay = React__default.forwardRef(({ isOpen, onClose, closeOnOverlayClick = true, closeOnEsc = true, enableScrollLock = true, position = "center", overlayClassName, contentClassName, contentStyle, animations, animationDuration, portalTarget, role, ariaLabelledBy, ariaDescribedBy, ariaModal, enableFocusTrap = true, children, }, ref) => {
    const isClient = useIsClient();
    const shouldReduceMotion = useReducedMotion();
    // When reduced motion is preferred, skip all animation durations
    const instantTransition = shouldReduceMotion ? { duration: 0 } : undefined;
    // Ref for focus trap container
    const focusTrapRef = useRef(null);
    useFocusTrap(focusTrapRef, enableFocusTrap && isOpen);
    // Use overlay hook for behavior (escape key, scroll lock, click handling)
    const { handleOverlayClick } = useOverlay({
        isOpen,
        onClose,
        closeOnEsc,
        closeOnOverlayClick,
        enableScrollLock,
    });
    // Merge custom animations with defaults
    const overlayAnimations = (animations === null || animations === void 0 ? void 0 : animations.overlay) || defaultOverlayAnimations;
    const contentAnimations = (animations === null || animations === void 0 ? void 0 : animations.content) || defaultContentAnimations;
    // Apply custom animation durations if provided
    const finalOverlayAnimations = { ...overlayAnimations };
    const finalContentAnimations = { ...contentAnimations };
    if (animationDuration) {
        if (animationDuration.enter && finalOverlayAnimations.animate) {
            const animate = finalOverlayAnimations.animate;
            animate.transition = {
                ...animate.transition,
                duration: animationDuration.enter,
            };
        }
        if (animationDuration.exit && finalOverlayAnimations.exit) {
            const exit = finalOverlayAnimations.exit;
            exit.transition = {
                ...exit.transition,
                duration: animationDuration.exit,
            };
        }
    }
    // Determine portal target
    const target = portalTarget !== undefined
        ? portalTarget
        : isClient
            ? document.body
            : null;
    // Don't render if no portal target available (SSR or first render)
    if (!target) {
        return null;
    }
    // Detect dark mode from document
    const isDarkMode = isClient &&
        (document.documentElement.classList.contains("dark") ||
            document.body.classList.contains("dark") ||
            document.querySelector(".dark") !== null);
    const content = (jsx(AnimatePresence, { mode: "wait", children: isOpen && (jsxs(motion.div, { className: cn(isDarkMode && "dark", overlayTheme.backdrop, overlayPositionVariants[position], overlayClassName), onClick: handleOverlayClick, variants: finalOverlayAnimations, initial: "initial", animate: "animate", exit: "exit", transition: instantTransition, children: [jsx("div", { className: overlayTheme.pattern, style: {
                        backgroundImage: "url(/overlay-dots.svg)",
                        backgroundRepeat: "repeat",
                        backgroundSize: "540px 540px",
                    } }), jsx(motion.div, { ref: (node) => {
                        // Merge external ref and focus trap ref
                        focusTrapRef.current = node;
                        if (typeof ref === "function")
                            ref(node);
                        else if (ref)
                            ref.current = node;
                    }, className: cn(overlayTheme.content, contentClassName), style: contentStyle, variants: finalContentAnimations, initial: "initial", animate: "animate", exit: "exit", transition: instantTransition, onClick: (e) => e.stopPropagation(), ...(role ? { role } : {}), ...(ariaModal ? { "aria-modal": true } : {}), ...(ariaLabelledBy ? { "aria-labelledby": ariaLabelledBy } : {}), ...(ariaDescribedBy
                        ? { "aria-describedby": ariaDescribedBy }
                        : {}), children: children })] })) }));
    return createPortal(content, target);
});
Overlay.displayName = "Overlay";

export { Overlay };
