import './index.css';
import { jsx } from 'react/jsx-runtime';
import { forwardRef, useRef, useState, useEffect, useLayoutEffect } from 'react';
import classnames from 'classnames';
import { useDisabled } from '@hh.ru/magritte-common-use-disabled';
import { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';
import { ComponentWithBadge } from '@hh.ru/magritte-ui-badge';
import { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';
import { s as styles, I as IconDynamic } from './IconDynamic-BAC1U7QU.js';
import { LoaderGlyph } from './LoaderGlyph.js';
import { SkeletonSize16, SkeletonSize24, SkeletonSize32 } from './Skeleton.js';
import './variants/icon/LoaderOutlinedSize16.js';
import './variants/icon/LoaderOutlinedSize24.js';
import './variants/icon/LoaderOutlinedSize32.js';
import './variants/icon/LoaderOutlinedSize48.js';
import './variants/icon/LoaderOutlinedSize64.js';
import './variants/icon/LoaderOutlinedSize96.js';
import '@hh.ru/magritte-ui-skeleton';

const INCOMPLETE_SKELETON_BY_SIZE = {
    16: SkeletonSize16,
    24: SkeletonSize24,
    32: SkeletonSize32,
};
const ALLOWED_BADGE_SIZES = ['small', 'extra-small'];
const BADGE_HALF_SIZE = 3;
const hoc = function (IconGlyph, componentName) {
    const IconWrapperComponent = ({ initialColor: _initialColor, 'aria-label': ariaLabel, 'aria-hidden': ariaHidden, padding, borderRadius, borderStyle, backgroundStyle, hoverBackgroundStyle, pressedBackgroundStyle, shadow = 'level-0', increaseShadow, badge, onClick, disabled, hex, tabIndex, loading, ...props }, ref) => {
        let highlightedValue;
        let disabledValue;
        let pressedValue;
        let hexHighlightedValue;
        let hexDisabledValue;
        let hexPressedValue;
        let dataQa;
        const initialColor = !_initialColor && !hex ? 'primary' : _initialColor;
        let propsToPass = { ...props };
        const hasBackground = backgroundStyle || hoverBackgroundStyle || pressedBackgroundStyle;
        const isFocusable = !!onClick || (tabIndex ?? -1) >= 0;
        const withWrapper = !!padding ||
            !!borderRadius ||
            hasBackground ||
            !!borderStyle ||
            isFocusable ||
            shadow !== 'level-0' ||
            increaseShadow;
        const WrapperElement = isFocusable ? 'button' : 'span';
        const wrapperProps = { ref, tabIndex };
        const isComponentDisabled = useDisabled() || !!disabled;
        const iconGlyphRef = useRef();
        const iconGlyphRefCallback = useMultipleRefs(iconGlyphRef, withWrapper ? null : ref);
        const animationDurationRef = useRef(null);
        const prevLoadingValueRef = useRef(loading);
        const [renderedLoadingValue, setRenderedLoadingValue] = useState(loading);
        const [badgeOutline, setBadgeOutline] = useState();
        const [badgeHoveredOutline, setBadgeHoveredOutline] = useState();
        const [isHovered, setIsHovered] = useState(false);
        const fadeTimeoutRef = useRef(null);
        const { isMobile } = useBreakpoint();
        const isActive = isFocusable && !isComponentDisabled && !renderedLoadingValue;
        const withBadge = !!badge;
        useEffect(() => {
            const animationDurationElement = document.createElement('div');
            animationDurationElement.classList.add(styles.fade);
            document.body.appendChild(animationDurationElement);
            const style = window.getComputedStyle(animationDurationElement);
            const fadeAnimationDuration = parseInt(style.getPropertyValue('--fade-animation-duration'), 10);
            document.body.removeChild(animationDurationElement);
            animationDurationRef.current = { fade: fadeAnimationDuration };
        }, []);
        useEffect(() => {
            if (fadeTimeoutRef.current !== null) {
                iconGlyphRef.current?.classList.remove(styles.fadeOut);
                clearTimeout(fadeTimeoutRef.current);
                fadeTimeoutRef.current = null;
            }
            if (prevLoadingValueRef.current !== loading) {
                iconGlyphRef.current?.classList.add(styles.fadeOut);
                fadeTimeoutRef.current = setTimeout(() => {
                    fadeTimeoutRef.current = null;
                    setRenderedLoadingValue(loading);
                }, animationDurationRef.current?.fade);
            }
        }, [loading]);
        useEffect(() => {
            if (prevLoadingValueRef.current !== renderedLoadingValue) {
                void iconGlyphRef.current?.scrollTop; // trigger repaint
                iconGlyphRef.current?.classList.add(styles.fadeIn);
                prevLoadingValueRef.current = renderedLoadingValue;
            }
        }, [renderedLoadingValue]);
        useLayoutEffect(() => {
            if (withBadge && (shadow !== 'level-0' || increaseShadow)) {
                // получаем размер outline для badge из стилей
                // width - outline
                // height - outline для hover при increaseShadow
                const shadowElement = document.createElement('div');
                shadowElement.classList.add(styles[`shadow-${shadow}-element`]);
                shadowElement.classList.toggle(styles.increase, increaseShadow);
                document.body.appendChild(shadowElement);
                const style = window.getComputedStyle(shadowElement);
                const outline = parseInt(style.getPropertyValue(`width`), 10);
                const outlineHovered = parseInt(style.getPropertyValue(`height`), 10);
                if (Number.isInteger(outline)) {
                    setBadgeOutline(outline);
                }
                if (Number.isInteger(outlineHovered)) {
                    setBadgeHoveredOutline(outlineHovered);
                }
                document.body.removeChild(shadowElement);
            }
        }, [shadow, increaseShadow, withBadge]);
        if (WrapperElement === 'button') {
            wrapperProps.type = 'button';
            wrapperProps.disabled = isComponentDisabled;
            wrapperProps.onClick = onClick;
            if (renderedLoadingValue) {
                wrapperProps.tabIndex = -1;
            }
        }
        // если тень при ховере меняется, нужно другое значение для outline баджа
        if (!isMobile && increaseShadow && badge && isActive) {
            wrapperProps.onMouseEnter = () => setIsHovered(true);
            wrapperProps.onMouseLeave = () => setIsHovered(false);
        }
        if ('highlightedColor' in propsToPass) {
            const { highlightedColor, ...lastProps } = propsToPass;
            propsToPass = lastProps;
            highlightedValue = highlightedColor;
        }
        else if (initialColor && onClick) {
            highlightedValue = initialColor;
        }
        if ('disabledColor' in propsToPass) {
            const { disabledColor, ...lastProps } = propsToPass;
            propsToPass = lastProps;
            disabledValue = disabledColor;
        }
        else if (initialColor && onClick) {
            disabledValue = initialColor;
        }
        if ('pressedColor' in propsToPass) {
            const { pressedColor, ...lastProps } = propsToPass;
            propsToPass = lastProps;
            pressedValue = pressedColor;
        }
        else if (initialColor && onClick) {
            pressedValue = initialColor;
        }
        if (highlightedValue && !pressedValue) {
            pressedValue = highlightedValue;
        }
        if ('hexHighlighted' in propsToPass) {
            const { hexHighlighted, ...lastProps } = propsToPass;
            propsToPass = lastProps;
            hexHighlightedValue = hexHighlighted;
        }
        if ('hexDisabled' in propsToPass) {
            const { hexDisabled, ...lastProps } = propsToPass;
            propsToPass = lastProps;
            hexDisabledValue = hexDisabled;
        }
        if ('hexPressed' in propsToPass) {
            const { hexPressed, ...lastProps } = propsToPass;
            propsToPass = lastProps;
            hexPressedValue = hexPressed;
        }
        if (hexHighlightedValue && !hexPressedValue) {
            hexPressedValue = hexHighlightedValue;
        }
        if ('data-qa' in propsToPass) {
            const { 'data-qa': dataQaValue, ...lastProps } = propsToPass;
            propsToPass = lastProps;
            dataQa = dataQaValue;
        }
        const glyphProps = {
            ...propsToPass,
            'data-qa': withWrapper && dataQa ? `${dataQa}-svg` : dataQa,
            role: 'img',
            focusable: false,
            ref: iconGlyphRefCallback,
            tabIndex: withWrapper ? undefined : tabIndex,
            className: classnames(styles.icon, {
                [styles[`icon_initial-${initialColor}`]]: !!initialColor,
                [styles[`icon_disabled-${disabledValue}`]]: !!disabledValue,
                [styles.hexed]: hex || hexDisabledValue,
                [styles.fadeInStart]: prevLoadingValueRef.current !== renderedLoadingValue,
            }, !renderedLoadingValue && {
                [styles[`icon_highlighted-${highlightedValue}`]]: !!highlightedValue,
                [styles[`icon_pressed-${pressedValue}`]]: !!pressedValue,
                [styles.hexed]: hex || hexHighlightedValue || hexDisabledValue,
            }),
            style: {
                '--magritte-ui-icon-hex-color': hex,
                '--magritte-ui-icon-hex-disabled-color': hexDisabledValue,
                ...(!renderedLoadingValue && {
                    '--magritte-ui-icon-hex-highlighted-color': hexHighlightedValue,
                    '--magritte-ui-icon-hex-pressed-color': hexPressedValue,
                }),
            },
        };
        if (withWrapper) {
            wrapperProps['aria-label'] = ariaLabel;
            wrapperProps['aria-hidden'] = ariaHidden || undefined;
            glyphProps['aria-hidden'] = true;
        }
        else {
            glyphProps['aria-label'] = ariaLabel;
            glyphProps['aria-hidden'] = ariaLabel ? ariaHidden || undefined : true;
        }
        const size = parseInt(componentName.slice(-2), 10);
        const icon = renderedLoadingValue ? jsx(LoaderGlyph, { size: size, ...glyphProps }) : jsx(IconGlyph, { ...glyphProps });
        const wrappedIcon = badge && !hasBackground && shadow === 'level-0' && !increaseShadow && !isComponentDisabled ? (jsx(ComponentWithBadge, { allowedSizes: ALLOWED_BADGE_SIZES, badge: badge, offset: -5, children: icon })) : (icon);
        let wrapper = wrappedIcon;
        const defaultBackgroundStyleValue = onClick ? backgroundStyle : undefined;
        const hoverBackgroundStyleValue = hoverBackgroundStyle ?? defaultBackgroundStyleValue;
        const pressedBackgroundStyleValue = pressedBackgroundStyle ?? hoverBackgroundStyleValue;
        if (withWrapper) {
            const content = (jsx(WrapperElement, { ...wrapperProps, "data-qa": dataQa, className: classnames(styles.view, {
                    [styles[`shadow-${shadow}`]]: shadow,
                    [styles.increase]: increaseShadow && !isMobile,
                    [styles.loading]: renderedLoadingValue,
                }), style: { borderRadius: borderRadius === 'halfHeight' ? '9999px' : borderRadius }, children: jsx("span", { className: classnames(styles.view, backgroundStyle && styles[`background-style-${backgroundStyle}`], hoverBackgroundStyleValue && styles[`hover-background-style-${hoverBackgroundStyleValue}`], pressedBackgroundStyleValue &&
                        styles[`pressed-background-style-${pressedBackgroundStyleValue}`], borderStyle && styles[`border-style-${borderStyle}`]), style: { borderRadius: borderRadius === 'halfHeight' ? '9999px' : borderRadius, padding }, children: wrappedIcon }) }));
            wrapper = (jsx("span", { className: classnames(styles.wrapper, {
                    [styles.active]: !!isFocusable && !isComponentDisabled && !renderedLoadingValue,
                }), children: onClick ? jsx(IconDynamic, { children: content }) : content }));
        }
        if (badge && (hasBackground || shadow !== 'level-0' || increaseShadow) && !isComponentDisabled) {
            // считаем расстояние от правого верхнего угла до окружности с borderRadius
            const currentHalfSize = size / 2 + (padding || 0);
            let currentBorderRadius;
            if (borderRadius === 'halfHeight' || (borderRadius && borderRadius > currentHalfSize)) {
                currentBorderRadius = currentHalfSize;
            }
            else {
                currentBorderRadius = borderRadius || 0;
            }
            const offset = currentBorderRadius - currentBorderRadius / Math.sqrt(2) - BADGE_HALF_SIZE;
            return (jsx(ComponentWithBadge, { allowedSizes: ALLOWED_BADGE_SIZES, badge: badge, offset: offset, outline: isHovered ? badgeHoveredOutline : badgeOutline, children: wrapper }));
        }
        return wrapper;
    };
    const IconWrapper = forwardRef(IconWrapperComponent);
    IconWrapper.displayName = componentName;
    const size = parseInt(componentName.slice(-2), 10);
    const IncompleteSkeleton = INCOMPLETE_SKELETON_BY_SIZE[size];
    const Skeleton = ((props) => (jsx(IncompleteSkeleton, { Icon: IconWrapper, ...props })));
    const IconWithSkeleton = IconWrapper;
    IconWithSkeleton.isIcon = true;
    IconWithSkeleton.Skeleton = Skeleton;
    IconWithSkeleton._size = size;
    IconWithSkeleton.displayName = componentName;
    return IconWithSkeleton;
};

export { hoc as default };
//# sourceMappingURL=hoc.js.map
