import { documentIsAvailable, getScrollbarWidth, testElForOverflow } from '../../utils';
export const sameWidth = Object.freeze({
    name: 'sameWidth',
    enabled: true,
    phase: 'beforeWrite',
    fn({ state }) {
        state.styles.popper.width = `${state.rects.reference.width}px`;
    },
    requires: ['computeStyles']
});
const scrollbarSize = documentIsAvailable ? getScrollbarWidth() : 0;
export const fitToContent = Object.freeze({
    name: 'fitToContent',
    enabled: true,
    phase: 'beforeWrite',
    requires: ['computeStyles', 'offset'],
    fn({ state }) {
        state.styles.popper.width = 'fit-content';
        // Ideally, we would use `content-width.md` from the theme, but we can't access it outside of a React function component
        state.elements.popper.style.maxWidth = '60ch';
        state.elements.popper.style.minWidth = `${state.rects.reference.width}px`;
    }
});
export const placeAndContain = Object.freeze({
    name: 'placeAndContain',
    enabled: true,
    phase: 'beforeWrite',
    requires: ['computeStyles', 'offset'],
    fn: ({ state }) => {
        const [requestedPrimaryPlacement, requestedSecondaryPlacement] = state.placement.split('-');
        const padding = {
            top: 0,
            bottom: 0,
            right: 0,
            left: 0
        };
        const preventOverflowPad = state.orderedModifiers.find(({ name }) => name === 'preventOverflow')
            ?.options?.padding;
        if (typeof preventOverflowPad === 'number') {
            padding.top = preventOverflowPad;
            padding.bottom = preventOverflowPad;
            padding.right = preventOverflowPad;
            padding.left = preventOverflowPad;
        }
        else if (preventOverflowPad) {
            padding.top = preventOverflowPad.top ?? padding.top;
            padding.bottom = preventOverflowPad.bottom ?? padding.bottom;
            padding.right = preventOverflowPad.right ?? padding.right;
            padding.left = preventOverflowPad.left ?? padding.left;
        }
        const vw = document.documentElement.clientWidth;
        const vh = document.documentElement.clientHeight;
        const targetRect = state.rects.reference;
        const targetRectXStart = targetRect.x;
        const targetRectXEnd = targetRectXStart + targetRect.width;
        const targetRectYStart = targetRect.y;
        const targetRectYEnd = targetRectYStart + targetRect.height;
        const targetXMid = (targetRectXStart + targetRectXEnd) / 2;
        const targetYMid = (targetRectYStart + targetRectYEnd) / 2;
        const targetIsInLeftHalfOfViewport = targetXMid < vw / 2;
        const targetIsInTopHalfOfViewport = targetYMid < vh / 2;
        const offsetFromTargetX = state.modifiersData.offset?.[state.placement]?.x ?? 0;
        const offsetFromTargetY = state.modifiersData.offset?.[state.placement]?.y ?? 0;
        let popoverMaxWidth = null;
        let popoverMaxHeight = null;
        // The elements whose natural content size should be measured to determine resolved placement
        const scrollableEls = [...state.elements.popper.children].flatMap(popoverChildEl => {
            // Default to measuring direct popover children unless they have measureable items declared within
            const elsToMeasure = popoverChildEl.querySelectorAll('[data-popover-scroll-el]');
            return elsToMeasure.length > 0 ? [...elsToMeasure] : popoverChildEl;
        });
        const totalScrollableChildHeight = scrollableEls.reduce((sum, el) => {
            if (el === state.elements.arrow) {
                return sum;
            }
            if (testElForOverflow(el)[0]) {
                return sum + el.scrollHeight + scrollbarSize;
            }
            return sum + el.scrollHeight;
        }, 0);
        const naturalPopoverHeight = Math.max(state.elements.popper.scrollHeight, totalScrollableChildHeight);
        const naturalPopoverWidth = Math.max(state.elements.popper.scrollWidth, ...Array.from(state.elements.popper.children).map(el => {
            if (el === state.elements.arrow) {
                return -Infinity;
            }
            if (testElForOverflow(el)[1]) {
                return el.scrollWidth + scrollbarSize;
            }
            return el.scrollWidth;
        }));
        let resolvedPlacement = requestedPrimaryPlacement;
        if (requestedPrimaryPlacement === 'bottom') {
            popoverMaxHeight = vh - targetRectYEnd - offsetFromTargetY - padding.bottom;
            if (
            // If the popover will overflow the viewport bottom
            targetRectYEnd + offsetFromTargetY + naturalPopoverHeight + padding.bottom >
                vh) {
                // Choose the side with most allowance
                resolvedPlacement = targetIsInTopHalfOfViewport ? 'bottom' : 'top';
            }
        }
        else if (requestedPrimaryPlacement === 'top') {
            popoverMaxHeight = targetRectYStart + offsetFromTargetY - padding.top;
            if (
            // If the popover will overflow the viewport top
            targetRectYStart + offsetFromTargetY - naturalPopoverHeight + padding.top <
                0) {
                // Choose the side with most allowance
                resolvedPlacement = targetIsInTopHalfOfViewport ? 'bottom' : 'top';
            }
        }
        else if (requestedPrimaryPlacement === 'left') {
            popoverMaxWidth = targetRectXStart + offsetFromTargetX - padding.left;
            if (
            // If the popover will overflow the viewport left
            targetRectXStart + offsetFromTargetX - naturalPopoverWidth + padding.left <
                0) {
                // Choose the side with most allowance
                resolvedPlacement = targetIsInLeftHalfOfViewport ? 'right' : 'left';
            }
        }
        else if (requestedPrimaryPlacement === 'right') {
            popoverMaxWidth = vw - targetRectXEnd - offsetFromTargetX - padding.right;
            if (
            // If the popover will overflow the viewport right
            targetRectXEnd + offsetFromTargetX + naturalPopoverWidth + padding.right >
                vw) {
                // Choose the side with most allowance
                resolvedPlacement = targetIsInLeftHalfOfViewport ? 'right' : 'left';
            }
        }
        if (resolvedPlacement === 'left' || resolvedPlacement === 'right') {
            popoverMaxHeight = vh - padding.top - padding.bottom;
        }
        state.elements.popper.style.maxHeight = `${popoverMaxHeight}px`;
        state.elements.popper.style.maxWidth = popoverMaxWidth !== null ? `${popoverMaxWidth}px` : '';
        resolvedPlacement = `${resolvedPlacement}${(requestedSecondaryPlacement ? `-${requestedSecondaryPlacement}` : '')}`;
        if (state.placement !== resolvedPlacement) {
            state.placement = resolvedPlacement;
            state.reset = true;
        }
    }
});
//# sourceMappingURL=modifiers.js.map