/**
 * @license MIT
 * author: Cube Dev Team
 * @cube-dev/ui-kit v0.0.0-canary-e980ce7
 * Released under the MIT license.
 */

import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState, } from 'react';
import { extractStyles, filterBaseProps, INNER_STYLES, mergeStyles, OUTER_STYLES, tasty, } from '../../../tasty/index.js';
import { isDevEnv } from '../../../tasty/utils/is-dev-env.js';
import { useCombinedRefs } from '../../../utils/react/index.js';
import { Alert } from '../Alert/index.js';
import { LayoutProvider, useLayoutActionsContext, useLayoutRefsContext, useLayoutStateContext, } from './LayoutContext.js';
const LayoutElement = tasty({
    as: 'div',
    qa: 'Layout',
    styles: {
        position: 'relative',
        display: 'block',
        overflow: {
            '': 'visible',
            'do-not-overflow': 'hidden',
        },
        flexGrow: 1,
        placeSelf: 'stretch',
        height: {
            '': 'auto',
            'auto-height': 'fixed 100%',
            collapsed: '6x',
        },
        '$content-padding': '1x',
        // Auto-border size for sub-components (set when layout is vertical)
        '$layout-border-size': {
            '': '0',
            vertical: '1bw',
        },
        Inner: {
            // .base-class[data-hover] > [data-element="Inner"] { ...}
            // Direct child selector required for nested layouts
            $: '>',
            container: 'layout / inline-size',
            position: 'absolute',
            inset: '$inset-top $inset-right $inset-bottom $inset-left',
            display: 'flex',
            flow: 'column',
            placeContent: 'stretch',
            placeItems: 'stretch',
            // Disable transition during panel resize for snappy feedback
            // Also disable transition when not ready to prevent initial animation
            // Only animate when has-transition is enabled (and not dragging/not-ready)
            transition: {
                '': 'none',
                'has-transition': 'inset $transition ease-out',
                'dragging | not-ready': 'none',
            },
        },
    },
});
function LayoutInner(props) {
    const layoutActions = useLayoutActionsContext();
    const layoutState = useLayoutStateContext();
    const layoutRefs = useLayoutRefsContext();
    const localRef = useRef(null);
    const [isAutoHeight, setIsAutoHeight] = useState(false);
    const [isCollapsed, setIsCollapsed] = useState(false);
    const { isGrid, columns, rows, template, contentPadding, hasTransition = false, styles, children, style, forwardedRef, innerRef: innerRefProp, innerProps, _forceShowDevWarning, doNotOverflow, ...otherProps } = props;
    const combinedInnerRef = useCombinedRefs(innerRefProp);
    // Extract outer wrapper styles and inner content styles
    const outerStyles = extractStyles(otherProps, OUTER_STYLES);
    const innerStyles = extractStyles(otherProps, INNER_STYLES);
    // Calculate if the layout flow is vertical (for auto-border feature)
    // Default flow is 'column' (vertical), only horizontal when explicitly set to 'row'
    const isVertical = useMemo(() => {
        const flowFromProp = innerStyles?.flow;
        const flowFromStyles = styles?.Inner?.flow;
        const flowValue = flowFromProp ?? flowFromStyles;
        return typeof flowValue !== 'string' || !flowValue.startsWith('row');
    }, [innerStyles?.flow, styles?.Inner]);
    // Merge styles using the same pattern as LayoutPane
    const finalStyles = useMemo(() => {
        // Handle grid mode and grid properties
        const gridStyles = {};
        if (isGrid) {
            gridStyles.display = 'grid';
        }
        if (columns) {
            gridStyles.gridColumns = columns;
        }
        if (rows) {
            gridStyles.gridRows = rows;
        }
        if (template) {
            gridStyles.gridTemplate = template;
        }
        return mergeStyles(outerStyles, contentPadding != null ? { '$content-padding': contentPadding } : null, styles, { Inner: mergeStyles(innerStyles, gridStyles, styles?.Inner) });
    }, [
        outerStyles,
        innerStyles,
        contentPadding,
        styles,
        isGrid,
        columns,
        rows,
        template,
    ]);
    // Calculate inset values from panel sizes
    const panelSizes = layoutState?.panelSizes ?? {
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
    };
    const isDragging = layoutState?.isDragging ?? false;
    const isReady = layoutState?.isReady ?? true;
    const markReady = layoutActions?.markReady;
    const dismissOverlayPanels = layoutActions?.dismissOverlayPanels;
    const hasOverlayPanels = layoutState?.hasOverlayPanels ?? false;
    // Mark layout as ready after first paint
    // Using useEffect + requestAnimationFrame ensures:
    // 1. Panels register in useLayoutEffect → correct insets before first paint
    // 2. First paint with not-ready=true (transition disabled)
    // 3. After paint completes → enables transitions for subsequent changes
    useEffect(() => {
        const frameId = requestAnimationFrame(() => {
            markReady?.();
        });
        return () => cancelAnimationFrame(frameId);
    }, [markReady]);
    // Auto-height detection: if layout collapses to 0 height after initialization,
    // automatically set height to 100% to prevent invisible layout
    useEffect(() => {
        if (isReady && localRef.current && localRef.current.offsetHeight === 0) {
            setIsAutoHeight(true);
        }
    }, [isReady]);
    // Second check: if still 0 height after auto-height was applied,
    // show collapsed state with warning
    useEffect(() => {
        if (isAutoHeight && localRef.current) {
            // Use requestAnimationFrame to check after styles have been applied
            const frameId = requestAnimationFrame(() => {
                if (localRef.current && localRef.current.offsetHeight === 0) {
                    setIsCollapsed(true);
                }
            });
            return () => cancelAnimationFrame(frameId);
        }
    }, [isAutoHeight]);
    const insetStyle = useMemo(() => {
        const baseStyle = {
            '--inset-top': `${panelSizes.top}px`,
            '--inset-right': `${panelSizes.right}px`,
            '--inset-bottom': `${panelSizes.bottom}px`,
            '--inset-left': `${panelSizes.left}px`,
        };
        if (style) {
            return { ...baseStyle, ...style };
        }
        return baseStyle;
    }, [panelSizes, style]);
    const mods = useMemo(() => ({
        dragging: isDragging,
        'not-ready': !isReady,
        'has-transition': hasTransition,
        'auto-height': isAutoHeight && !isCollapsed,
        collapsed: isCollapsed,
        vertical: isVertical,
        'do-not-overflow': doNotOverflow,
    }), [
        isDragging,
        isReady,
        hasTransition,
        isAutoHeight,
        isCollapsed,
        isVertical,
        doNotOverflow,
    ]);
    // Combine local ref with forwarded ref
    const setRefs = (element) => {
        localRef.current = element;
        if (typeof forwardedRef === 'function') {
            forwardedRef(element);
        }
        else if (forwardedRef) {
            forwardedRef.current = element;
        }
    };
    // Show dev warning when collapsed and in dev mode (or forced for stories)
    const showDevWarning = isCollapsed && (_forceShowDevWarning || isDevEnv());
    // Handle focus entering the Inner element - dismiss overlay panels
    const handleInnerFocus = useCallback((e) => {
        // Only dismiss if there are overlay panels
        if (!hasOverlayPanels)
            return;
        // Check if focus is coming from outside the Inner element
        const inner = e.currentTarget;
        const relatedTarget = e.relatedTarget;
        // If relatedTarget is null or not inside the Inner element,
        // focus is entering from outside - dismiss overlay panels
        if (!relatedTarget || !inner.contains(relatedTarget)) {
            dismissOverlayPanels?.();
        }
    }, [hasOverlayPanels, dismissOverlayPanels]);
    // Handle Escape key anywhere in the Layout - dismiss overlay panels
    const handleKeyDown = useCallback((e) => {
        if (hasOverlayPanels && e.key === 'Escape') {
            e.preventDefault();
            e.stopPropagation();
            dismissOverlayPanels?.();
        }
    }, [hasOverlayPanels, dismissOverlayPanels]);
    return (_jsx(LayoutElement, { ref: setRefs, ...filterBaseProps(otherProps, { eventProps: true }), mods: mods, styles: finalStyles, style: insetStyle, onKeyDown: hasOverlayPanels ? handleKeyDown : undefined, children: showDevWarning ? (_jsxs(Alert, { theme: "danger", children: [_jsx("b", { children: "UIKit:" }), " ", _jsx("b", { children: "<Layout/>" }), " has collapsed to ", _jsx("b", { children: "0" }), " height. Ensure the parent container has a defined height or use the", ' ', _jsx("b", { children: "height" }), " prop on ", _jsx("b", { children: "<Layout/>" }), "."] })) : (_jsxs(_Fragment, { children: [_jsx("div", { ref: combinedInnerRef, "data-element": "Inner", onFocus: handleInnerFocus, ...innerProps, children: children }), _jsx("div", { ref: layoutRefs?.setPanelContainer, "data-element": "PanelContainer" })] })) }));
}
/**
 * Layout component provides a vertical flex layout with overflow-safe content.
 * Uses a two-element architecture (wrapper + content) to ensure content never overflows.
 */
function Layout(props, ref) {
    const { hasTransition } = props;
    return (_jsx(LayoutProvider, { hasTransition: hasTransition, children: _jsx(LayoutInner, { ...props, forwardedRef: ref }) }));
}
const _Layout = forwardRef(Layout);
_Layout.displayName = 'Layout';
export { _Layout as Layout };

        