import { jsx, jsxs } from 'react/jsx-runtime';
import React__default, { createContext, useId, useMemo, useRef, useEffect, useContext } from 'react';
import { cn } from '../../../utils/cn.js';
import { useScaleBackground } from '../../../hooks/useScaleBackground.js';
import { Overlay } from '../../effects/Overlay/Overlay.js';
import { drawerTheme, drawerSizeVariants, drawerPositionVariantsFullWidth, drawerPositionVariantsWithMargin } from './Drawer.theme.js';
import { drawerOverlayAnimations, getDrawerContentAnimations } from './Drawer.animations.js';
import { DrawerHeader } from './DrawerHeader.js';
import { DrawerTitle } from './DrawerTitle.js';
import { DrawerSubtitle } from './DrawerSubtitle.js';
import { DrawerBody } from './DrawerBody.js';
import { DrawerFooter } from './DrawerFooter.js';

/** Manages browser history so the back button closes the drawer instead of navigating. */
function useCloseOnBack(isOpen, onClose, enabled) {
    const closedByPopstate = useRef(false);
    useEffect(() => {
        if (!enabled || !isOpen)
            return;
        closedByPopstate.current = false;
        history.pushState({ flikDrawer: true }, "");
        const handlePopstate = () => {
            closedByPopstate.current = true;
            onClose();
        };
        window.addEventListener("popstate", handlePopstate);
        return () => {
            window.removeEventListener("popstate", handlePopstate);
            if (!closedByPopstate.current) {
                history.back();
            }
        };
    }, [isOpen, onClose, enabled]);
}
// Create context for Drawer components
const DrawerContext = createContext(undefined);
const useDrawerContext = () => {
    const ctx = useContext(DrawerContext);
    if (!ctx)
        throw new Error("Drawer compound components must be used within <Drawer>");
    return ctx;
};
const DrawerRoot = ({ isOpen, onClose, title, subtitle, icon, position = "right", size = "md", closeOnOverlayClick = true, closeOnEsc = true, showCloseButton = true, children, className, theme: themeOverrides, scale = 0.94, closeOnBack = false, ...props }) => {
    // Close drawer on browser back button
    useCloseOnBack(isOpen, onClose, closeOnBack);
    // iOS-style scale background effect
    useScaleBackground({ isOpen, scale, position });
    // Generate unique IDs for ARIA linkage
    const id = useId();
    const titleId = `${id}-title`;
    const subtitleId = `${id}-subtitle`;
    // Merge theme with overrides
    const theme = useMemo(() => ({
        ...drawerTheme,
        ...(themeOverrides || {}),
    }), [themeOverrides]);
    // Context value
    const contextValue = useMemo(() => ({
        isOpen,
        onClose,
        position,
        size,
        closeOnOverlayClick,
        closeOnEsc,
        showCloseButton,
        theme,
        titleId,
        subtitleId,
    }), [
        isOpen,
        onClose,
        position,
        size,
        closeOnOverlayClick,
        closeOnEsc,
        showCloseButton,
        theme,
        titleId,
        subtitleId,
    ]);
    // Detect if children contain a compound Drawer.Header
    const hasCompoundHeader = React__default.Children.toArray(children).some((child) => {
        var _a;
        return React__default.isValidElement(child) &&
            ((_a = child.type) === null || _a === void 0 ? void 0 : _a.displayName) === "Drawer.Header";
    });
    // Auto-generate header when using prop shorthand (backward compat)
    const shouldAutoRenderHeader = !hasCompoundHeader && (title || showCloseButton);
    // Detect whether size is a preset token or an arbitrary Tailwind class
    const SIZE_TOKENS = ["sm", "md", "lg", "full"];
    const isSizeToken = SIZE_TOKENS.includes(size);
    // Get size variant based on position (only for preset tokens)
    const isHorizontal = position === "left" || position === "right";
    const sizeVariant = isSizeToken
        ? isHorizontal
            ? drawerSizeVariants.horizontal[size]
            : drawerSizeVariants.vertical[size]
        : size; // treat arbitrary string as a raw Tailwind class
    // Use different positioning for full-width/height drawers
    const positionVariant = size === "full"
        ? drawerPositionVariantsFullWidth[position]
        : drawerPositionVariantsWithMargin[position];
    return (jsx(Overlay, { isOpen: isOpen, onClose: onClose, closeOnOverlayClick: closeOnOverlayClick, closeOnEsc: closeOnEsc, position: "none", role: "dialog", ariaModal: true, ariaLabelledBy: titleId, ariaDescribedBy: subtitleId, contentClassName: cn(theme.container, positionVariant, isSizeToken && size !== "full" && sizeVariant, !isSizeToken && sizeVariant, // raw Tailwind class
        className), animations: {
            overlay: drawerOverlayAnimations,
            content: getDrawerContentAnimations(position),
        }, ...props, children: jsx(DrawerContext.Provider, { value: contextValue, children: jsxs("div", { className: theme.inner, children: [shouldAutoRenderHeader && (jsxs(DrawerHeader, { icon: icon, children: [title &&
                                (typeof title === "string" ? (jsx(DrawerTitle, { children: title })) : (title)), subtitle &&
                                (typeof subtitle === "string" ? (jsx(DrawerSubtitle, { children: subtitle })) : (subtitle))] })), children] }) }) }));
};
DrawerRoot.displayName = "Drawer";
// Attach compound subcomponents
const Drawer = Object.assign(DrawerRoot, {
    Header: DrawerHeader,
    Title: DrawerTitle,
    Subtitle: DrawerSubtitle,
    Body: DrawerBody,
    Footer: DrawerFooter,
});

export { Drawer, useDrawerContext };
