import React, { useState, useImperativeHandle, forwardRef, useMemo, useEffect, useRef, } from 'react';
import Popover from '../Popover';
import RawText from '../Text/RawText';
import { dataHooks, TIMEOUT } from './constants';
import { ZIndex } from '../common/ZIndex';
import { st, classes } from './Tooltip.st.css.js';
import { useEventCallback } from '../common/useEventCallback/useEventCallback';
const Tooltip = forwardRef(({ onShow = () => ({}), onHide = () => ({}), size = 'medium', className, placement = 'top', exitDelay = 0, enterDelay = 0, moveArrowTo, appendTo = 'window', flip = true, fixed = false, maxWidth = 204, fluid, moveBy, disabled, children, zIndex = ZIndex.tooltip, textAlign = 'start', content = '', inline, 'aria-describedby': ariaDescribedBy, 'aria-labelledby': ariaLabelledBy, interactive = true, ...rest }, ref) => {
    const [shown, setShown] = useState(false);
    const contentRef = useRef(null);
    const open = useEventCallback(() => {
        setShown(true);
        onShow?.();
    });
    const close = useEventCallback(() => {
        setShown(false);
        onHide?.();
    });
    useImperativeHandle(ref, () => ({
        open,
        close,
        getContentElement: () => contentRef.current,
    }));
    const isDisabled = disabled ?? false;
    const onFocus = useEventCallback((event, handlers) => {
        const focusableHOC = handlers && handlers.focus;
        const target = event.target;
        try {
            if (process.env.NODE_ENV !== 'test' &&
                target instanceof Element &&
                !target.matches(':focus-visible')) {
                handlers?.blur();
                return;
            }
        }
        catch (e) {
            // browser does not support `matches(':focus-visible')` fallback to original focus behavior
        }
        open();
        return focusableHOC ? handlers.focus() : null;
    });
    const onBlur = useEventCallback((_event, handlers) => {
        const focusableHOC = handlers && handlers.blur;
        close();
        return focusableHOC ? handlers.blur() : null;
    });
    const handleKeyDown = useEventCallback((event) => {
        if (event.key === 'Escape' && shown) {
            close();
        }
    });
    useEffect(() => {
        document.addEventListener('keydown', handleKeyDown);
        return () => {
            document.removeEventListener('keydown', handleKeyDown);
        };
    }, [handleKeyDown]);
    const triggerElement = useMemo(() => {
        if (typeof children === 'string' || !children) {
            return children;
        }
        if (React.isValidElement(children)) {
            const ariaProps = ariaLabelledBy
                ? { 'aria-labelledby': ariaLabelledBy }
                : { 'aria-describedby': ariaDescribedBy };
            return React.cloneElement(children, {
                ...(isDisabled ? {} : { onFocus, onBlur }),
                ...ariaProps,
            });
        }
        if (typeof children === 'function') {
            return children({
                onFocus,
                onBlur,
            });
        }
        return;
    }, [
        children,
        isDisabled,
        onFocus,
        onBlur,
        ariaDescribedBy,
        ariaLabelledBy,
    ]);
    const contentElement = useMemo(() => {
        const textSize = size === 'small' ? 'tiny' : 'small';
        return (React.createElement("div", { style: { textAlign } }, typeof content === 'string' ? (
        // @ts-ignore
        React.createElement(RawText, { dataHook: dataHooks.tooltipText, size: textSize, light: true, className: classes.text, renderChildren: ({ text }) => text, renderElement: ({ element }) => element }, content)) : (content)));
    }, [content, textAlign, size]);
    return (React.createElement(Popover, { role: "tooltip", showArrow: size !== 'small', className: st(classes.root, { size, inline }, className), placement: placement, shown: isDisabled ? false : shown, onMouseEnter: isDisabled ? undefined : open, onMouseLeave: close, onClickOutside: close, onEscPress: close, "data-size": size, hideDelay: exitDelay, showDelay: enterDelay, moveBy: moveBy, moveArrowTo: moveArrowTo, appendTo: appendTo, id: ariaLabelledBy || ariaDescribedBy, flip: flip, fixed: fixed, maxWidth: maxWidth, fluid: fluid, disableClickOutsideWhenClosed: true, zIndex: zIndex, interactive: interactive, ...rest, theme: "dark", timeout: TIMEOUT },
        React.createElement(Popover.Element, null, triggerElement),
        React.createElement(Popover.Content, null,
            React.createElement("div", { ref: contentRef, style: { maxWidth } }, contentElement))));
});
Tooltip.displayName = 'Tooltip';
export default Tooltip;
//# sourceMappingURL=Tooltip.js.map