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

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { PressResponder } from '@react-aria/interactions';
import { useMediaQuery } from '@react-spectrum/utils';
import { Fragment, useEffect, useRef } from 'react';
import { useOverlayPosition, useOverlayTrigger, } from 'react-aria';
import { useOverlayTriggerState } from 'react-stately';
import { useCombinedRefs } from '../../../utils/react/index.js';
import { Modal, Popover, Tray } from '../Modal/index.js';
import { DialogContext } from './context.js';
/**
 * DialogTrigger serves as a wrapper around a Dialog and its associated trigger, linking the Dialog's
 * open state with the trigger's press state. Additionally, it allows you to customize the type and
 * positioning of the Dialog.
 */
export function DialogTrigger(props) {
    let { children, type = 'modal', mobileType = type === 'popover' ? 'modal' : type, hideArrow, targetRef, onDismiss, isDismissable = true, isKeyboardDismissDisabled, styles, mobileViewport = 700, hideOnClose, shouldCloseOnInteractOutside, ...positionProps } = props;
    if (!Array.isArray(children) || children.length > 2) {
        throw new Error('DialogTrigger must have exactly 2 children');
    }
    // if a function is passed as the second child, it won't appear in toArray
    let [trigger, content] = children;
    // On small devices, show a modal or tray instead of a popover.
    let isMobile = useMediaQuery(`(max-width: ${mobileViewport}px)`);
    if (isMobile) {
        // handle cases where desktop popovers need a close button for the mobile modal view
        if (type !== 'modal' && mobileType === 'modal') {
            isDismissable = true;
        }
        type = mobileType;
    }
    let state = useOverlayTriggerState(props);
    if (typeof trigger === 'function') {
        trigger = trigger(state);
    }
    let wasOpen = useRef(false);
    let isExiting = useRef(false);
    let onExiting = () => (isExiting.current = true);
    let onExited = () => (isExiting.current = false);
    wasOpen.current = state.isOpen;
    useEffect(() => {
        return () => {
            if ((wasOpen.current || isExiting.current) &&
                type !== 'popover' &&
                type !== 'tray') {
                console.warn('CubeUIKit: A DialogTrigger unmounted while open. This is likely due to being placed within a trigger that unmounts or inside a conditional. Consider using a DialogContainer instead.');
            }
        };
    }, []);
    function onClose(action) {
        if (isDismissable) {
            onDismiss && onDismiss(action);
            state.close();
        }
    }
    if (type === 'popover') {
        return (_jsx(PopoverTrigger, { ...positionProps, hideOnClose: hideOnClose, state: state, styles: styles, targetRef: targetRef, trigger: trigger, content: content, isKeyboardDismissDisabled: isKeyboardDismissDisabled, hideArrow: hideArrow, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, onClose: onClose }));
    }
    let renderOverlay = () => {
        switch (type) {
            case 'panel':
            case 'fullscreen':
            case 'fullscreenTakeover':
            case 'modal':
                return (_jsx(Modal, { hideOnClose: hideOnClose, isOpen: state.isOpen, isDismissable: isDismissable, type: type, isKeyboardDismissDisabled: isKeyboardDismissDisabled, styles: styles, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, onClose: onClose, onExiting: onExiting, onExited: onExited, children: typeof content === 'function' ? content(state.close) : content }));
            case 'tray':
                return (_jsx(Tray, { hideOnClose: hideOnClose, isOpen: state.isOpen, isKeyboardDismissDisabled: isKeyboardDismissDisabled, styles: styles, onClose: onClose, children: typeof content === 'function' ? content(state.close) : content }));
        }
    };
    return (_jsx(DialogTriggerBase, { type: type, state: state, isDismissable: isDismissable, trigger: trigger, overlay: renderOverlay(), hideOnClose: hideOnClose, onClose: onClose }));
}
function PopoverTrigger(allProps) {
    let { state, styles, targetRef, trigger, content, hideArrow, onClose, isKeyboardDismissDisabled, hideOnClose, shouldCloseOnInteractOutside, keepOpenOnScroll, ...props } = allProps;
    let triggerRef = useRef(null);
    let overlayRef = useRef(null);
    let { overlayProps: popoverProps, placement, arrowProps, updatePosition, } = useOverlayPosition({
        targetRef: targetRef || triggerRef,
        overlayRef: overlayRef,
        placement: props.placement,
        containerPadding: props.containerPadding,
        offset: props.offset || 8,
        crossOffset: props.crossOffset,
        shouldFlip: props.shouldFlip,
        shouldUpdatePosition: props.shouldUpdatePosition,
        isOpen: state.isOpen,
    });
    let overlayTriggerState = state;
    if (keepOpenOnScroll) {
        overlayTriggerState = { ...state, close: updatePosition };
    }
    let { triggerProps, overlayProps } = useOverlayTrigger({ type: 'dialog' }, overlayTriggerState, triggerRef);
    let triggerPropsWithRef = {
        ...triggerProps,
        ref: targetRef ? undefined : triggerRef,
    };
    let overlay = (_jsx(Popover, { ref: overlayRef, styles: styles, hideOnClose: hideOnClose, isOpen: state.isOpen, style: popoverProps.style, placement: placement, arrowProps: arrowProps, isKeyboardDismissDisabled: isKeyboardDismissDisabled, hideArrow: hideArrow, updatePosition: updatePosition, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, onClose: onClose, children: typeof content === 'function' ? content(state.close) : content }));
    return (_jsx(DialogTriggerBase, { type: "popover", state: state, triggerProps: triggerPropsWithRef, dialogProps: overlayProps, trigger: trigger, overlay: overlay, onClose: onClose }));
}
function DialogTriggerBase(props) {
    const ref = useCombinedRefs(props.ref);
    const wasOpenRef = useRef(false);
    let { type, state, onClose, isDismissable, dialogProps = {}, triggerProps = {}, overlay, trigger, } = props;
    let context = {
        type,
        onClose,
        isDismissable,
        isOpen: state.isOpen,
        ...dialogProps,
    };
    // Restore focus manually when the dialog closes
    useEffect(() => {
        if (!state.isOpen && wasOpenRef.current) {
            wasOpenRef.current = false;
            ref.current?.focus();
        }
        else if (state.isOpen) {
            wasOpenRef.current = true;
        }
    }, [state.isOpen]);
    return (_jsxs(Fragment, { children: [_jsx(PressResponder, { ref: ref, ...triggerProps, isPressed: state.isOpen &&
                    type !== 'modal' &&
                    type !== 'fullscreen' &&
                    type !== 'fullscreenTakeover', onPress: state.toggle, children: trigger }), _jsx(DialogContext.Provider, { value: context, children: overlay })] }));
}

        