import { _ as __rest } from './tslib.es6-es.js';
import React__default, { useState, useMemo, createContext, useContext } from 'react';
import classnames from 'classnames';
import { a as arrow, u as useFloating, b as autoUpdate, o as offset, s as shift, l as limitShift, n as autoPlacement, f as flip, F as FloatingPortal } from './floating-ui.react-es.js';
import { useRefocusOnActivator } from '@jobber/hooks';
import { A as AtlantisPortalContent } from './AtlantisPortalContent-es.js';
import { B as ButtonDismiss } from './ButtonDismiss-es.js';

const POPOVER_OFFSET = 10;
const POPOVER_SHIFT_PADDING = 8;
const POPOVER_ARROW_PADDING = 6;
const usePopover = ({ preferredPlacement, attachTo, open, }) => {
    const [arrowElement, setArrowElement] = useState();
    const modifiers = useMemo(() => {
        const baseModifiers = [
            offset(POPOVER_OFFSET),
            shift({
                mainAxis: true,
                crossAxis: false,
                padding: POPOVER_SHIFT_PADDING,
                limiter: limitShift(),
            }),
        ];
        const placementMiddleware = preferredPlacement === "auto"
            ? autoPlacement({
                allowedPlacements: ["top", "bottom", "left", "right"],
            })
            : flip({
                fallbackPlacements: ["top", "bottom", "left", "right"],
            });
        return [
            ...baseModifiers,
            placementMiddleware,
            arrow({
                element: arrowElement || null,
                padding: POPOVER_ARROW_PADDING,
            }),
        ];
    }, [arrowElement, preferredPlacement]);
    const referenceElement = isHTMLElement(attachTo)
        ? attachTo
        : attachTo.current;
    const { refs, floatingStyles, middlewareData, placement } = useFloating({
        placement: preferredPlacement === "auto" ? undefined : preferredPlacement,
        strategy: "absolute",
        middleware: modifiers,
        elements: {
            reference: referenceElement || null,
        },
        // Only use this option when the floating element is conditionally rendered
        // (which we are), not hidden with css. https://floating-ui.com/docs/autoUpdate
        whileElementsMounted: autoUpdate,
    });
    useRefocusOnActivator(open);
    return {
        setFloatingElement: refs.setFloating,
        setArrowElement,
        floatingStyles: {
            float: floatingStyles,
            arrow: middlewareData.arrow,
        },
        placement,
    };
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isHTMLElement(el) {
    return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) && el instanceof Element;
}

var styles = {"popover":"rY8OtuArIi0-","header":"UI1AohefbSo-","dismissButton":"HyA0TM5soDM-","arrow":"uClo-5-xhAc-","spinning":"VA0ROLmpLPs-"};

const usePopoverStyles = () => {
    return {
        container: styles.popover,
        dismissButton: styles.dismissButton,
        arrow: styles.arrow,
    };
};

const PopoverContext = createContext({
    floatingStyles: { float: {} },
    setArrowElement: () => {
        // noop
    },
});
function usePopoverContext() {
    return useContext(PopoverContext);
}
function PopoverProvider({ children, preferredPlacement = "auto", attachTo, open, UNSAFE_className, UNSAFE_style, }) {
    const { setFloatingElement, setArrowElement, floatingStyles, placement } = usePopover({
        preferredPlacement,
        attachTo,
        open,
    });
    if (!open)
        return null;
    return (React__default.createElement(PopoverContext.Provider, { value: {
            setArrowElement,
            floatingStyles,
            placement,
        } },
        React__default.createElement(PopoverWrapper, { UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style, setFloatingElement: setFloatingElement, placement: placement }, children)));
}
function PopoverWrapper({ children, setFloatingElement, UNSAFE_className, UNSAFE_style, placement, }) {
    const popoverStyles = usePopoverStyles();
    const { floatingStyles } = usePopoverContext();
    const classes = classnames(popoverStyles.container, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container);
    const content = (React__default.createElement(AtlantisPortalContent, null,
        React__default.createElement("div", { role: "dialog", "data-elevation": "elevated", ref: setFloatingElement, style: Object.assign(Object.assign({}, floatingStyles.float), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container), className: classes, "data-popover-placement": placement, "data-testid": "ATL-Popover-Container" }, children)));
    return React__default.createElement(FloatingPortal, null, content);
}

function Popover({ onRequestClose, children, attachTo, open, preferredPlacement = "auto", UNSAFE_className, UNSAFE_style, }) {
    return (React__default.createElement(Popover.Provider, { attachTo: attachTo, open: open, preferredPlacement: preferredPlacement, UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style },
        React__default.createElement(Popover.DismissButton, { UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style, onClick: onRequestClose }),
        children,
        React__default.createElement(Popover.Arrow, { UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style })));
}
Popover.Provider = PopoverProvider;
Popover.Arrow = function PopoverArrow({ UNSAFE_className, UNSAFE_style, }) {
    var _a, _b;
    const { setArrowElement, floatingStyles, placement } = usePopoverContext();
    const popoverStyles = usePopoverStyles();
    const classes = classnames(popoverStyles.arrow, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.arrow);
    // the arrow will get positioned opposite to the placement side
    const staticSideMap = {
        top: "bottom",
        right: "left",
        bottom: "top",
        left: "right",
    };
    const staticSide = staticSideMap[placement];
    const arrowX = (_a = floatingStyles.arrow) === null || _a === void 0 ? void 0 : _a.x;
    const arrowY = (_b = floatingStyles.arrow) === null || _b === void 0 ? void 0 : _b.y;
    const arrowStyles = {
        position: "absolute",
        // only left or top will be defined at a time
        left: arrowX !== null && arrowX !== undefined ? `${arrowX}px` : "",
        top: arrowY !== null && arrowY !== undefined ? `${arrowY}px` : "",
        right: "",
        bottom: "",
        [staticSide]: "var(--popover--position--offset)",
        width: "var(--base-unit)",
        height: "var(--base-unit)",
    };
    return (React__default.createElement("div", { ref: setArrowElement, className: classes, style: Object.assign(Object.assign({}, arrowStyles), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.arrow), "data-testid": "ATL-Popover-Arrow" }));
};
Popover.DismissButton = function PopoverDismissButton(props) {
    var _a;
    const { UNSAFE_className, UNSAFE_style, children } = props, dismissButtonProps = __rest(props, ["UNSAFE_className", "UNSAFE_style", "children"]);
    const popoverStyles = usePopoverStyles();
    const classes = classnames(popoverStyles.dismissButton, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.dismissButtonContainer);
    return (React__default.createElement("div", { className: classes, style: (_a = UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.dismissButtonContainer) !== null && _a !== void 0 ? _a : {}, "data-testid": "ATL-Popover-Dismiss-Button-Container" }, children !== null && children !== void 0 ? children : (React__default.createElement(ButtonDismiss, Object.assign({ ariaLabel: "Close dialog" }, dismissButtonProps)))));
};

export { Popover as P, usePopoverStyles as a, usePopoverContext as u };
