import { __rest } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment, useCallback, useContext, useEffect, useRef, useState } from 'react';
import styles from '@patternfly/react-styles/css/components/Drawer/drawer.mjs';
import { css } from '@patternfly/react-styles';
import { DrawerColorVariant, DrawerContext } from './Drawer';
import { formatBreakpointMods, getLanguageDirection } from '../../helpers/util';
import { useSSRSafeId } from '../../helpers';
import { FocusTrap } from '../../helpers/FocusTrap/FocusTrap';
import cssPanelMdFlexBasis from '@patternfly/react-tokens/dist/esm/c_drawer__panel_md_FlexBasis';
import cssPanelMdFlexBasisMin from '@patternfly/react-tokens/dist/esm/c_drawer__panel_md_FlexBasis_min';
import cssPanelMdFlexBasisMax from '@patternfly/react-tokens/dist/esm/c_drawer__panel_md_FlexBasis_max';
let isResizing = null;
let newSize = 0;
export const DrawerPanelContent = (_a) => {
    var { className, id, children, hasNoBorder = false, isResizable = false, hasNoGlass = false, isGlass = false, isPlain = false, isNoPlainOnGlass = false, onResize, minSize, defaultSize, maxSize, increment = 5, resizeAriaLabel = 'Resize', widths, colorVariant = DrawerColorVariant.default, focusTrap, style } = _a, props = __rest(_a, ["className", "id", "children", "hasNoBorder", "isResizable", "hasNoGlass", "isGlass", "isPlain", "isNoPlainOnGlass", "onResize", "minSize", "defaultSize", "maxSize", "increment", "resizeAriaLabel", "widths", "colorVariant", "focusTrap", "style"]);
    const panelId = useSSRSafeId('pf-drawer-panel-');
    const panel = useRef(undefined);
    const splitterRef = useRef(undefined);
    const [separatorValue, setSeparatorValue] = useState(0);
    const { position, isExpanded, isStatic, onExpand, drawerRef, drawerContentRef, isInline } = useContext(DrawerContext);
    const hidden = isStatic ? false : !isExpanded;
    const [isExpandedInternal, setIsExpandedInternal] = useState(!hidden);
    const [isFocusTrapActive, setIsFocusTrapActive] = useState(false);
    const [shouldCollapseSpace, setShouldCollapseSpace] = useState(hidden);
    const previouslyFocusedElement = useRef(null);
    const resizeState = useRef({
        initialPointerPos: 0,
        initialPanelSize: 0,
        currWidth: 0
    });
    if (isStatic && (focusTrap === null || focusTrap === void 0 ? void 0 : focusTrap.enabled)) {
        // eslint-disable-next-line no-console
        console.warn(`DrawerPanelContent: The focusTrap.enabled prop cannot be true if the Drawer's isStatic prop is true. This will cause a permanent focus trap.`);
    }
    useEffect(() => {
        if (!isStatic && isExpanded) {
            setIsExpandedInternal(isExpanded);
            setShouldCollapseSpace(false);
        }
    }, [isStatic, isExpanded]);
    const calcValueNow = () => {
        let splitterPos;
        let drawerSize;
        const isRTL = getLanguageDirection(panel.current) === 'rtl';
        if (isInline && (position === 'end' || position === 'right')) {
            if (isRTL) {
                splitterPos = panel.current.getBoundingClientRect().left - splitterRef.current.getBoundingClientRect().right;
                drawerSize = drawerRef.current.getBoundingClientRect().left - drawerRef.current.getBoundingClientRect().right;
            }
            else {
                splitterPos = panel.current.getBoundingClientRect().right - splitterRef.current.getBoundingClientRect().left;
                drawerSize = drawerRef.current.getBoundingClientRect().right - drawerRef.current.getBoundingClientRect().left;
            }
        }
        else if (isInline && (position === 'start' || position === 'left')) {
            if (isRTL) {
                splitterPos = splitterRef.current.getBoundingClientRect().left - panel.current.getBoundingClientRect().right;
                drawerSize = drawerRef.current.getBoundingClientRect().left - drawerRef.current.getBoundingClientRect().right;
            }
            else {
                splitterPos = splitterRef.current.getBoundingClientRect().right - panel.current.getBoundingClientRect().left;
                drawerSize = drawerRef.current.getBoundingClientRect().right - drawerRef.current.getBoundingClientRect().left;
            }
        }
        else if (position === 'end' || position === 'right') {
            if (isRTL) {
                splitterPos =
                    drawerContentRef.current.getBoundingClientRect().left - splitterRef.current.getBoundingClientRect().right;
                drawerSize =
                    drawerContentRef.current.getBoundingClientRect().left -
                        drawerContentRef.current.getBoundingClientRect().right;
            }
            else {
                splitterPos =
                    drawerContentRef.current.getBoundingClientRect().right - splitterRef.current.getBoundingClientRect().left;
                drawerSize =
                    drawerContentRef.current.getBoundingClientRect().right -
                        drawerContentRef.current.getBoundingClientRect().left;
            }
        }
        else if (position === 'start' || position === 'left') {
            if (isRTL) {
                splitterPos =
                    splitterRef.current.getBoundingClientRect().left - drawerContentRef.current.getBoundingClientRect().right;
                drawerSize =
                    drawerContentRef.current.getBoundingClientRect().left -
                        drawerContentRef.current.getBoundingClientRect().right;
            }
            else {
                splitterPos =
                    splitterRef.current.getBoundingClientRect().right - drawerContentRef.current.getBoundingClientRect().left;
                drawerSize =
                    drawerContentRef.current.getBoundingClientRect().right -
                        drawerContentRef.current.getBoundingClientRect().left;
            }
        }
        else if (position === 'bottom') {
            splitterPos =
                drawerContentRef.current.getBoundingClientRect().bottom - splitterRef.current.getBoundingClientRect().top;
            drawerSize =
                drawerContentRef.current.getBoundingClientRect().bottom - drawerContentRef.current.getBoundingClientRect().top;
        }
        const newSplitterPos = (splitterPos / drawerSize) * 100;
        return Math.round((newSplitterPos + Number.EPSILON) * 100) / 100;
    };
    const setInitialResizeState = (controlPosition) => {
        const panelRect = panel.current.getBoundingClientRect();
        const initialPanelSize = position === 'bottom' ? panelRect.height : panelRect.width;
        resizeState.current = {
            initialPointerPos: controlPosition,
            initialPanelSize,
            currWidth: initialPanelSize
        };
    };
    const handleTouchStart = (e) => {
        e.stopPropagation();
        setInitialResizeState(position === 'bottom' ? e.touches[0].clientY : e.touches[0].clientX);
        document.addEventListener('touchmove', callbackTouchMove, { passive: false });
        document.addEventListener('touchend', callbackTouchEnd);
        isResizing = true;
    };
    const handleMousedown = (e) => {
        e.stopPropagation();
        e.preventDefault();
        setInitialResizeState(position === 'bottom' ? e.clientY : e.clientX);
        document.addEventListener('mousemove', callbackMouseMove);
        document.addEventListener('mouseup', callbackMouseUp);
        drawerRef.current.classList.add(css(styles.modifiers.resizing));
        isResizing = true;
    };
    const handleMouseMove = (e) => {
        const mousePos = position === 'bottom' ? e.clientY : e.clientX;
        handleControlMove(e, mousePos);
    };
    const handleTouchMove = (e) => {
        e.preventDefault();
        e.stopImmediatePropagation();
        const touchPos = position === 'bottom' ? e.touches[0].clientY : e.touches[0].clientX;
        handleControlMove(e, touchPos);
    };
    const handleControlMove = (e, controlPosition) => {
        const isRTL = getLanguageDirection(panel.current) === 'rtl';
        e.stopPropagation();
        if (!isResizing) {
            return;
        }
        const { initialPointerPos, initialPanelSize } = resizeState.current;
        const delta = controlPosition - initialPointerPos;
        let newSize = 0;
        if (position === 'end' || position === 'right') {
            newSize = isRTL ? initialPanelSize + delta : initialPanelSize - delta;
        }
        else if (position === 'start' || position === 'left') {
            newSize = isRTL ? initialPanelSize - delta : initialPanelSize + delta;
        }
        else {
            newSize = initialPanelSize - delta;
        }
        if (position === 'bottom') {
            panel.current.style.overflowAnchor = 'none';
        }
        panel.current.style.setProperty(cssPanelMdFlexBasis.name, newSize + 'px');
        resizeState.current.currWidth = newSize;
        setSeparatorValue(calcValueNow());
    };
    const handleMouseup = (e) => {
        if (!isResizing) {
            return;
        }
        drawerRef.current.classList.remove(css(styles.modifiers.resizing));
        isResizing = false;
        onResize && onResize(e, resizeState.current.currWidth, id);
        document.removeEventListener('mousemove', callbackMouseMove);
        document.removeEventListener('mouseup', callbackMouseUp);
    };
    const handleTouchEnd = (e) => {
        e.stopPropagation();
        if (!isResizing) {
            return;
        }
        isResizing = false;
        onResize && onResize(e, resizeState.current.currWidth, id);
        document.removeEventListener('touchmove', callbackTouchMove);
        document.removeEventListener('touchend', callbackTouchEnd);
    };
    const callbackMouseMove = useCallback(handleMouseMove, []);
    const callbackTouchEnd = useCallback(handleTouchEnd, []);
    const callbackTouchMove = useCallback(handleTouchMove, []);
    const callbackMouseUp = useCallback(handleMouseup, []);
    const handleKeys = (e) => {
        const isRTL = getLanguageDirection(panel.current) === 'rtl';
        const key = e.key;
        if (key !== 'Escape' &&
            key !== 'Enter' &&
            key !== 'ArrowUp' &&
            key !== 'ArrowDown' &&
            key !== 'ArrowLeft' &&
            key !== 'ArrowRight') {
            if (isResizing) {
                e.preventDefault();
            }
            return;
        }
        e.preventDefault();
        if (key === 'Escape' || key === 'Enter') {
            onResize && onResize(e, resizeState.current.currWidth, id);
        }
        const panelRect = panel.current.getBoundingClientRect();
        newSize = position === 'bottom' ? panelRect.height : panelRect.width;
        let delta = 0;
        if (key === 'ArrowRight') {
            if (isRTL) {
                delta = position === 'left' || position === 'start' ? -increment : increment;
            }
            else {
                delta = position === 'left' || position === 'start' ? increment : -increment;
            }
        }
        else if (key === 'ArrowLeft') {
            if (isRTL) {
                delta = position === 'left' || position === 'start' ? increment : -increment;
            }
            else {
                delta = position === 'left' || position === 'start' ? -increment : increment;
            }
        }
        else if (key === 'ArrowUp') {
            delta = increment;
        }
        else if (key === 'ArrowDown') {
            delta = -increment;
        }
        newSize = newSize + delta;
        if (position === 'bottom') {
            panel.current.style.overflowAnchor = 'none';
        }
        panel.current.style.setProperty(cssPanelMdFlexBasis.name, newSize + 'px');
        resizeState.current.currWidth = newSize;
        setSeparatorValue(calcValueNow());
    };
    const boundaryCssVars = {};
    if (defaultSize) {
        boundaryCssVars[cssPanelMdFlexBasis.name] = defaultSize;
    }
    if (minSize) {
        boundaryCssVars[cssPanelMdFlexBasisMin.name] = minSize;
    }
    if (maxSize) {
        boundaryCssVars[cssPanelMdFlexBasisMax.name] = maxSize;
    }
    const isValidFocusTrap = (focusTrap === null || focusTrap === void 0 ? void 0 : focusTrap.enabled) && !isStatic;
    const Component = isValidFocusTrap ? FocusTrap : 'div';
    const focusTrapProps = {
        tabIndex: -1,
        'aria-modal': true,
        role: 'dialog',
        active: isFocusTrapActive,
        'aria-labelledby': (focusTrap === null || focusTrap === void 0 ? void 0 : focusTrap['aria-labelledby']) || id || panelId,
        focusTrapOptions: {
            fallbackFocus: () => panel.current,
            onActivate: () => {
                if (previouslyFocusedElement.current !== document.activeElement) {
                    previouslyFocusedElement.current = document.activeElement;
                }
            },
            onDeactivate: () => {
                previouslyFocusedElement.current &&
                    previouslyFocusedElement.current.focus &&
                    previouslyFocusedElement.current.focus();
            },
            clickOutsideDeactivates: true,
            returnFocusOnDeactivate: false,
            // FocusTrap's initialFocus can accept false as a value to prevent initial focus.
            // We want to prevent this in case false is ever passed in.
            initialFocus: (focusTrap === null || focusTrap === void 0 ? void 0 : focusTrap.elementToFocusOnExpand) || undefined,
            escapeDeactivates: false
        }
    };
    return (_jsx(Component, Object.assign({}, (isValidFocusTrap && focusTrapProps), { id: id || panelId, className: css(styles.drawerPanel, isResizable && styles.modifiers.resizable, hasNoGlass && 'pf-m-no-glass', isGlass && styles.modifiers.glass, isPlain && styles.modifiers.plain, isNoPlainOnGlass && styles.modifiers.noPlainOnGlass, hasNoBorder && styles.modifiers.noBorder, formatBreakpointMods(widths, styles), colorVariant === DrawerColorVariant.noBackground && styles.modifiers.noBackground, colorVariant === DrawerColorVariant.secondary && styles.modifiers.secondary, className), onTransitionEnd: (ev) => {
            if (ev.target === panel.current) {
                if (!hidden && ev.nativeEvent.propertyName === 'transform') {
                    onExpand(ev);
                }
                setIsExpandedInternal(!hidden);
                // We also need to collapse the space when the panel is hidden to prevent automation from scrolling to it
                if (hidden && ev.nativeEvent.propertyName === 'transform') {
                    setShouldCollapseSpace(true);
                }
                if (isValidFocusTrap && ev.nativeEvent.propertyName === 'transform') {
                    setIsFocusTrapActive((prevIsFocusTrapActive) => !prevIsFocusTrapActive);
                }
            }
        }, hidden: hidden, style: Object.assign(Object.assign({}, ((defaultSize || minSize || maxSize) && boundaryCssVars)), style) }, (shouldCollapseSpace && { inert: '' }), props, { ref: panel, children: isExpandedInternal && (_jsxs(Fragment, { children: [isResizable && (_jsxs(Fragment, { children: [_jsx("div", { className: css(styles.drawerSplitter, position !== 'bottom' && styles.modifiers.vertical), role: "separator", tabIndex: 0, "aria-orientation": position === 'bottom' ? 'horizontal' : 'vertical', "aria-label": resizeAriaLabel, "aria-valuenow": separatorValue, "aria-valuemin": 0, "aria-valuemax": 100, "aria-controls": id || panelId, onMouseDown: handleMousedown, onKeyDown: handleKeys, onTouchStart: handleTouchStart, ref: splitterRef, children: _jsx("div", { className: css(styles.drawerSplitterHandle), "aria-hidden": true }) }), _jsx("div", { className: css(styles.drawerPanelMain), children: children })] })), !isResizable && children] })) })));
};
DrawerPanelContent.displayName = 'DrawerPanelContent';
//# sourceMappingURL=DrawerPanelContent.js.map