import { parseToHsl, lighten, readableColor as polishedReadableColor, darken, getContrast, hsl, modularScale, stripUnit, math } from 'polished';
import { tryCatch } from '../utils';
const wcagContrast = {
    // https://www.w3.org/TR/WCAG21/#contrast-minimum
    AA: 4.5,
    AALarge: 3,
    // https://www.w3.org/TR/WCAG21/#contrast-enhanced
    AAA: 7,
    AAALarge: 4.5,
    // https://www.w3.org/TR/WCAG21/#non-text-contrast
    AANonText: 3
};
export const readableColor = (color, { mode = 'light', level = 'AA' } = {}) => {
    const minContrast = typeof level === 'string' ? wcagContrast[level] : level;
    if (mode === 'light' && getContrast('#fff', color) >= minContrast) {
        return '#fff';
    }
    if (mode === 'dark' && getContrast('#000', color) >= minContrast) {
        return '#000';
    }
    return polishedReadableColor(color);
};
const getBackgroundForegroundColors = (color, delta) => {
    const backgroundLightness = tryCatch(() => parseToHsl(color).lightness, () => 1);
    let background = tryCatch(() => lighten(delta, color));
    let foreground = tryCatch(() => readableColor(lighten(delta, color)));
    if (backgroundLightness > 0.35) {
        background = tryCatch(() => darken(delta, color));
        foreground = tryCatch(() => readableColor(darken(delta, color)));
    }
    return { background, foreground };
};
export const getHoverColors = (color) => {
    return getBackgroundForegroundColors(color, 0.1);
};
export const getActiveColors = (color) => {
    return getBackgroundForegroundColors(color, 0.2);
};
export const readableHue = (color1, color2, { mode = 'both', level = 'AA' } = {}) => {
    const minContrast = typeof level === 'string' ? wcagContrast[level] : level;
    if (getContrast(color1, color2) >= minContrast)
        return color1;
    const { lightness, ...hueSaturation } = parseToHsl(color1);
    let shouldLighten = true;
    let shouldDarken = true;
    let lightEnough = '';
    let darkEnough = '';
    for (let i = 0; i <= 1; i += 0.01) {
        if (shouldLighten) {
            const lightented = hsl({
                ...hueSaturation,
                lightness: Math.min(lightness + i, 1)
            });
            if (getContrast(lightented, color2) >= minContrast) {
                if (mode !== 'dark')
                    return lightented;
                shouldLighten = false;
                lightEnough = lightented;
            }
            if (lightness + i >= 1)
                shouldLighten = false;
        }
        if (shouldDarken) {
            const darkened = hsl({
                ...hueSaturation,
                lightness: Math.max(lightness - i, 0)
            });
            if (getContrast(darkened, color2) >= minContrast) {
                if (mode !== 'light')
                    return darkened;
                shouldDarken = false;
                darkEnough = darkened;
            }
            if (lightness - i <= 0)
                shouldDarken = false;
        }
        if (!shouldLighten && !shouldDarken)
            break;
    }
    if (lightEnough)
        return lightEnough;
    if (darkEnough)
        return darkEnough;
    return readableColor(color2, { mode, level });
};
export const omitProps = (...props) => ({
    shouldForwardProp: (prop, defaultValidatorFn) => !props.includes(prop) && defaultValidatorFn(prop)
});
const stepsMap = {
    xxs: -2,
    xs: -1,
    s: 0,
    m: 1,
    l: 2,
    xl: 3,
    xxl: 4
};
export const calculateFontSize = (baseFontSize, baseFontScale) => {
    return Object.fromEntries(Object.entries(stepsMap).map(([size, steps]) => {
        const calculation = tryCatch(() => baseFontScale === 'linear'
            ? math(`${baseFontSize} + (${steps} * 0.0625rem)`)
            : modularScale(steps, baseFontSize, baseFontScale), () => baseFontSize);
        if (size === 'xs' && Number.parseFloat(`${stripUnit(calculation)}`) < 0.75) {
            return [size, `max(calc((${baseFontSize} + 12px) / 2), 12px)`];
        }
        return [size, `max(${calculation}, 12px)`];
    }));
};
//# sourceMappingURL=utils.js.map