import { jsx as _jsx } from "react/jsx-runtime";
import { forwardRef, useState, useEffect } from 'react';
import styled, { css } from 'styled-components';
import { useTheme } from '../../hooks';
import { defaultThemeProp } from '../../theme';
import { readableColor } from '../../styles';
const iconRegistry = new Map([]);
export const registerIcon = (...icons) => {
    icons.forEach(({ set: modSet, name, ...iconDef }) => {
        const set = modSet ?? 'budicon';
        if (!iconRegistry.has(set)) {
            iconRegistry.set(set, new Map([[name, iconDef]]));
        }
        else if (!iconRegistry.get(set).has(name)) {
            iconRegistry.get(set).set(name, iconDef);
        }
    });
};
export const forceRegisterIcon = (...icons) => {
    icons.forEach(({ set: modSet, name, ...iconDef }) => {
        const set = modSet ?? 'budicon';
        if (!iconRegistry.has(set)) {
            iconRegistry.set(set, new Map([[name, iconDef]]));
        }
        else {
            iconRegistry.get(set).set(name, iconDef);
        }
    });
};
export const StyledIcon = styled.svg(({ theme, size = 's' }) => {
    const { components: { icon: { size: { s, m, l } } } } = theme;
    return css `
    display: inline-block;
    fill: currentColor;
    vertical-align: middle;
    flex-shrink: 0;
    /* stylelint-disable unit-allowed-list */
    min-width: 14px;
    min-height: 14px;
    /* stylelint-enable unit-allowed-list */

    ${size === 's' &&
        css `
      width: ${s};
      height: ${s};
    `}

    ${size === 'm' &&
        css `
      width: ${m};
      height: ${m};
    `}

    ${size === 'l' &&
        css `
      width: ${l};
      height: ${l};
    `}

    ${size === 'font-size' &&
        css `
      width: 1em;
      height: 1em;
    `}
  `;
});
StyledIcon.defaultProps = defaultThemeProp;
export const StyledIconShape = styled.div(({ theme, background, foreground, size = 'm', shape = 'square' }) => {
    const readableFg = readableColor(background);
    const { base: { 'border-radius': baseRadius }, components: { icon: { size: { s, m, l }, 'border-radius-multiplier': borderRadiusMultiplier } } } = theme;
    return css `
    color: ${foreground ?? readableFg};
    background-color: ${background};
    display: flex;
    justify-content: center;
    align-items: center;

    ${size === 's' &&
        css `
      width: ${s};
      height: ${s};
    `}

    ${size === 'm' &&
        css `
      width: ${m};
      height: ${m};
    `}

    ${size === 'l' &&
        css `
      width: ${l};
      height: ${l};
    `}

    ${size === 'font-size' &&
        css `
      width: 1em;
      height: 1em;
    `}

    ${shape === 'square' &&
        css `
      border-radius: calc(${borderRadiusMultiplier} * ${baseRadius});
    `}

    ${shape === 'circle' &&
        css `
      border-radius: 50%;
    `}

    ${StyledIcon} {
      width: 50%;
      height: 50%;
      /* stylelint-disable unit-allowed-list */
      min-width: min(14px, 90%);
      min-height: min(14px, 90%);
      /* stylelint-enable unit-allowed-list */
    }
  `;
});
StyledIconShape.defaultProps = defaultThemeProp;
const emptyIconDefinition = Object.freeze({ Component: () => null });
const Icon = forwardRef(function Icon({ set: setProp, name, size, 'aria-label': ariaLabel, ...restProps }, ref) {
    const { base: { 'icon-set': setTheme } } = useTheme();
    const set = setProp ?? setTheme ?? 'budicon';
    const [iconDef, setIconDef] = useState(iconRegistry.get(set)?.get(name) ?? emptyIconDefinition);
    useEffect(() => {
        if (iconRegistry.get(set)?.has(name)) {
            setIconDef(iconRegistry.get(set).get(name));
            return;
        }
        const controller = new AbortController();
        (async () => {
            try {
                const encodedName = encodeURIComponent(name);
                let iconSet;
                let module;
                switch (set) {
                    case 'streamline':
                        iconSet = 'streamline-icons';
                        break;
                    case 'budicon':
                        iconSet = 'icons';
                        break;
                    default:
                        throw new Error('Unknown icon');
                }
                // The following expression is required for Storybook Vite Builder
                try {
                    module = await import(`./${iconSet}/${encodedName}.icon`);
                }
                catch {
                    module = await import(`./${iconSet}/${encodedName}.icon.tsx`);
                }
                if (module.name !== name || !module.Component)
                    throw new Error('Malformed icon definition');
                registerIcon(module);
            }
            catch {
                registerIcon({ set, name, ...emptyIconDefinition });
            }
            if (!controller.signal.aborted) {
                setIconDef(iconRegistry.get(set).get(name) ?? emptyIconDefinition);
            }
        })();
        return () => controller.abort();
    }, [name, set]);
    return typeof restProps.background === 'string' ? (_jsx(StyledIconShape, { ...restProps, background: restProps.background, foreground: restProps.foreground, shape: restProps.shape, size: size, ref: ref, children: _jsx(StyledIcon, { role: ariaLabel !== undefined ? 'img' : 'presentation', "aria-label": ariaLabel, viewBox: iconDef.viewBox, children: _jsx(iconDef.Component, {}) }) })) : (_jsx(StyledIcon, { ...restProps, role: ariaLabel !== undefined ? 'img' : 'presentation', "aria-label": ariaLabel, viewBox: iconDef.viewBox, size: size, ref: ref, children: _jsx(iconDef.Component, {}) }));
});
export default Icon;
//# sourceMappingURL=Icon.js.map