import { jsx, Fragment } from 'react/jsx-runtime';
import { forwardRef, useMemo } from 'react';
import { cn } from '../../../utils/cn.js';
import { progressiveBlurTheme } from './ProgressiveBlur.theme.js';

const DEFAULT_LAYERS = 8;
const DEFAULT_MAX_BLUR = 64;
const DEFAULT_SIZE = "30%";
/**
 * Generate exponentially distributed blur levels (powers of 2).
 * e.g. for 8 layers with max 64: [0.5, 1, 2, 4, 8, 16, 32, 64]
 */
function generateBlurLevels(layers, maxBlur) {
    return Array.from({ length: layers }, (_, i) => maxBlur * Math.pow(2, i - (layers - 1)));
}
const GRADIENT_DIRECTIONS = {
    top: "to top",
    bottom: "to bottom",
    left: "to left",
    right: "to right",
};
/**
 * Renders a single blur instance for one position.
 */
const BlurInstance = forwardRef(({ position, blurLevels, size, theme, className, style, ...rest }, ref) => {
    const isVertical = position === "top" || position === "bottom";
    const direction = GRADIENT_DIRECTIONS[position];
    const n = blurLevels.length;
    const containerStyle = {
        ...(isVertical ? { height: size } : { width: size }),
        ...style,
    };
    return (jsx("div", { ref: ref, className: cn(theme.baseStyle, theme.positions[position], className), style: containerStyle, ...rest, children: blurLevels.map((blur, i) => {
            // MagicUI mask formula: each layer has a 1-step fade-in, 1-step solid,
            // and 1-step fade-out. Adjacent layers overlap by 2 steps, creating
            // smooth transitions. Values beyond 100% are clamped by the browser.
            const step = 100 / n;
            const gradient = `linear-gradient(${direction}, transparent ${i * step}%, black ${(i + 1) * step}%, black ${(i + 2) * step}%, transparent ${(i + 3) * step}%)`;
            const layerStyle = {
                maskImage: gradient,
                WebkitMaskImage: gradient,
                backdropFilter: `blur(${blur}px)`,
                WebkitBackdropFilter: `blur(${blur}px)`,
                zIndex: i + 1,
            };
            return (jsx("div", { className: theme.layerStyle, style: layerStyle }, i));
        }) }));
});
BlurInstance.displayName = "BlurInstance";
const ProgressiveBlur = forwardRef(({ position = "bottom", blurLevels: blurLevelsProp, layers = DEFAULT_LAYERS, blurIntensity = DEFAULT_MAX_BLUR, size = DEFAULT_SIZE, className, theme: themeOverrides, ...rest }, ref) => {
    const theme = useMemo(() => {
        var _a, _b;
        return ({
            baseStyle: (_a = themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.baseStyle) !== null && _a !== void 0 ? _a : progressiveBlurTheme.baseStyle,
            positions: {
                ...progressiveBlurTheme.positions,
                ...themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.positions,
            },
            layerStyle: (_b = themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.layerStyle) !== null && _b !== void 0 ? _b : progressiveBlurTheme.layerStyle,
        });
    }, [themeOverrides]);
    const blurLevels = useMemo(() => blurLevelsProp !== null && blurLevelsProp !== void 0 ? blurLevelsProp : generateBlurLevels(layers, blurIntensity), [blurLevelsProp, layers, blurIntensity]);
    const positions = Array.isArray(position)
        ? position
        : [position];
    // Single position — render directly, forward ref and remaining props
    if (positions.length === 1) {
        return (jsx(BlurInstance, { ref: ref, position: positions[0], blurLevels: blurLevels, size: size, theme: theme, className: className, ...rest }));
    }
    // Multiple positions — render one BlurInstance per position
    return (jsx(Fragment, { children: positions.map((pos) => (jsx(BlurInstance, { position: pos, blurLevels: blurLevels, size: size, theme: theme, className: className, ...rest }, pos))) }));
});
ProgressiveBlur.displayName = "ProgressiveBlur";

export { ProgressiveBlur };
