import { jsxs, jsx } from 'react/jsx-runtime';
import React__default, { useId, useState, useRef, useMemo, useEffect, useCallback } from 'react';
import { cn } from '../../../utils/cn.js';

/**
 * Hook to detect dark mode preference
 */
const useDarkMode = () => {
    const [isDark, setIsDark] = useState(false);
    useEffect(() => {
        if (typeof window === "undefined")
            return;
        const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
        setIsDark(mediaQuery.matches);
        const handler = (e) => setIsDark(e.matches);
        mediaQuery.addEventListener("change", handler);
        return () => mediaQuery.removeEventListener("change", handler);
    }, []);
    return isDark;
};
/**
 * GlassSurface Component
 * Creates a realistic chromatic aberration glass effect using SVG filters.
 * Works as a wrapper for any content.
 */
const GlassSurface = React__default.forwardRef(({ children, width, height, borderRadius = 20, borderWidth = 0.07, brightness: brightnessProp, opacity: opacityProp, blur: blurProp, displace: displaceProp, backgroundOpacity: backgroundOpacityProp, backgroundColor, saturation: saturationProp, distortionScale: distortionScaleProp, redOffset = 0, greenOffset = 10, blueOffset = 20, xChannel = "R", yChannel = "G", mixBlendMode: mixBlendModeProp, colorScheme = "auto", backdropBrightness = 1, frosted = false, className = "", style = {}, }, forwardedRef) => {
    const uniqueId = useId().replace(/:/g, "-");
    const filterId = `glass-filter-${uniqueId}`;
    const redGradId = `red-grad-${uniqueId}`;
    const blueGradId = `blue-grad-${uniqueId}`;
    const noiseFilterId = `noise-filter-${uniqueId}`;
    const [svgSupported, setSvgSupported] = useState(false);
    const containerRef = useRef(null);
    const feImageRef = useRef(null);
    const redChannelRef = useRef(null);
    const greenChannelRef = useRef(null);
    const blueChannelRef = useRef(null);
    const gaussianBlurRef = useRef(null);
    const isDarkMode = useDarkMode();
    const resolvedDark = colorScheme === "auto" ? isDarkMode : colorScheme === "dark";
    // Theme-aware defaults: user-provided props always win
    // Note: brightness/opacity control the displacement map center fill, NOT visual brightness.
    // brightness=50 + opacity=1 = neutral center (no displacement), only edges refract.
    // On light backgrounds, high displacement pulls in black out-of-bounds pixels → gray artifacts.
    const brightness = brightnessProp !== null && brightnessProp !== void 0 ? brightnessProp : 50;
    const opacity = opacityProp !== null && opacityProp !== void 0 ? opacityProp : (resolvedDark ? 0.93 : 1);
    const blur = blurProp !== null && blurProp !== void 0 ? blurProp : 11;
    const displace = displaceProp !== null && displaceProp !== void 0 ? displaceProp : 0.7;
    const backgroundOpacity = backgroundOpacityProp !== null && backgroundOpacityProp !== void 0 ? backgroundOpacityProp : (resolvedDark ? 0.1 : 0);
    const saturation = saturationProp !== null && saturationProp !== void 0 ? saturationProp : (resolvedDark ? 1.8 : 1.4);
    const distortionScale = distortionScaleProp !== null && distortionScaleProp !== void 0 ? distortionScaleProp : (resolvedDark ? -180 : -40);
    const mixBlendMode = mixBlendModeProp !== null && mixBlendModeProp !== void 0 ? mixBlendModeProp : (resolvedDark ? "difference" : "multiply");
    /**
     * Generates the SVG displacement map as a Data URI
     */
    const generateDisplacementMap = () => {
        var _a;
        const rect = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
        const actualWidth = (rect === null || rect === void 0 ? void 0 : rect.width) || 0;
        const actualHeight = (rect === null || rect === void 0 ? void 0 : rect.height) || 0;
        // Don't generate if size is 0
        if (actualWidth === 0 || actualHeight === 0)
            return "";
        const edgeSize = Math.min(actualWidth, actualHeight) * (borderWidth * 0.5);
        const svgContent = `
      <svg viewBox="0 0 ${actualWidth} ${actualHeight}" xmlns="http://www.w3.org/2000/svg">
        <defs>
          <linearGradient id="${redGradId}" x1="100%" y1="0%" x2="0%" y2="0%">
            <stop offset="0%" stop-color="#000"/>
            <stop offset="100%" stop-color="red"/>
          </linearGradient>
          <linearGradient id="${blueGradId}" x1="0%" y1="0%" x2="0%" y2="100%">
            <stop offset="0%" stop-color="#000"/>
            <stop offset="100%" stop-color="blue"/>
          </linearGradient>
        </defs>
        <rect x="0" y="0" width="${actualWidth}" height="${actualHeight}" fill="black" />
        <rect x="0" y="0" width="${actualWidth}" height="${actualHeight}" rx="${borderRadius}" fill="url(#${redGradId})" />
        <rect x="0" y="0" width="${actualWidth}" height="${actualHeight}" rx="${borderRadius}" fill="url(#${blueGradId})" style="mix-blend-mode: ${mixBlendMode}" />
        <rect x="${edgeSize}" y="${edgeSize}" width="${actualWidth - edgeSize * 2}" height="${actualHeight - edgeSize * 2}" rx="${borderRadius}" fill="hsl(0 0% ${brightness}% / ${opacity})" style="filter:blur(${blur}px)" />
      </svg>
    `;
        return `data:image/svg+xml,${encodeURIComponent(svgContent)}`;
    };
    const updateDisplacementMap = () => {
        const dataUri = generateDisplacementMap();
        if (feImageRef.current && dataUri) {
            feImageRef.current.setAttribute("href", dataUri);
        }
    };
    // Detect SVG Filter support (backwards compatibility for Safari/Firefox)
    const supportsSVGFilters = () => {
        if (typeof window === "undefined" || typeof document === "undefined")
            return false;
        const isWebkit = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
        const isFirefox = /Firefox/.test(navigator.userAgent);
        if (isWebkit || isFirefox)
            return false;
        const div = document.createElement("div");
        div.style.backdropFilter = `url(#${filterId})`;
        return div.style.backdropFilter !== "";
    };
    const supportsBackdrop = useMemo(() => { var _a; return typeof CSS !== 'undefined' && ((_a = CSS.supports) === null || _a === void 0 ? void 0 : _a.call(CSS, 'backdrop-filter', 'blur(1px)')); }, []);
    useEffect(() => {
        setSvgSupported(supportsSVGFilters());
    }, []);
    // Update filter attributes when props change
    useEffect(() => {
        updateDisplacementMap();
        const scale = distortionScale;
        if (redChannelRef.current) {
            redChannelRef.current.setAttribute("scale", (scale + redOffset).toString());
            redChannelRef.current.setAttribute("xChannelSelector", xChannel);
            redChannelRef.current.setAttribute("yChannelSelector", yChannel);
        }
        if (greenChannelRef.current) {
            greenChannelRef.current.setAttribute("scale", (scale + greenOffset).toString());
            greenChannelRef.current.setAttribute("xChannelSelector", xChannel);
            greenChannelRef.current.setAttribute("yChannelSelector", yChannel);
        }
        if (blueChannelRef.current) {
            blueChannelRef.current.setAttribute("scale", (scale + blueOffset).toString());
            blueChannelRef.current.setAttribute("xChannelSelector", xChannel);
            blueChannelRef.current.setAttribute("yChannelSelector", yChannel);
        }
        if (gaussianBlurRef.current) {
            gaussianBlurRef.current.setAttribute("stdDeviation", displace.toString());
        }
    }, [
        borderRadius,
        borderWidth,
        brightness,
        opacity,
        blur,
        displace,
        distortionScale,
        redOffset,
        greenOffset,
        blueOffset,
        xChannel,
        yChannel,
        mixBlendMode,
    ]);
    // Ref to hold the latest updateDisplacementMap to avoid stale closures in ResizeObserver
    const updateRef = useRef(updateDisplacementMap);
    updateRef.current = updateDisplacementMap;
    // ResizeObserver to handle dimension changes
    useEffect(() => {
        if (!containerRef.current)
            return;
        const resizeObserver = new ResizeObserver(() => {
            // Use requestAnimationFrame for smoother updates
            requestAnimationFrame(() => updateRef.current());
        });
        resizeObserver.observe(containerRef.current);
        return () => {
            resizeObserver.disconnect();
        };
    }, []);
    // Check if user is providing custom shadow via className
    const hasCustomShadow = className === null || className === void 0 ? void 0 : className.includes("shadow");
    const containerStyles = useMemo(() => {
        const baseStyles = {
            ...style,
            width: typeof width === "number" ? `${width}px` : width,
            height: typeof height === "number" ? `${height}px` : height,
            borderRadius: `${borderRadius}px`,
        };
        // Default blur for frosted effect
        const frostedBlur = frosted ? "blur(12px)" : "";
        if (svgSupported) {
            // Determine background color: use prop if provided, otherwise auto-detect based on theme
            const bgColor = backgroundColor || (resolvedDark ? "hsl(0 0% 0%)" : "hsl(0 0% 100%)");
            // Convert color to rgba if needed to apply opacity
            const getBackgroundWithOpacity = () => {
                // If backgroundOpacity is 0, return transparent
                if (backgroundOpacity === 0)
                    return "transparent";
                // If color already has alpha channel (rgba, hsla), use as-is
                if (bgColor.includes("rgba") || bgColor.includes("hsla")) {
                    return bgColor;
                }
                // For named colors, hex, rgb, hsl - wrap in color-mix for opacity
                return `color-mix(in srgb, ${bgColor}, transparent ${(1 - backgroundOpacity) * 100}%)`;
            };
            return {
                ...baseStyles,
                background: getBackgroundWithOpacity(),
                backdropFilter: `url(#${filterId}) ${frostedBlur} brightness(${backdropBrightness}) saturate(${saturation})`,
                WebkitBackdropFilter: `url(#${filterId}) ${frostedBlur} brightness(${backdropBrightness}) saturate(${saturation})`,
                ...(!resolvedDark && { border: "1px solid rgba(0, 0, 0, 0.06)" }),
                ...(hasCustomShadow
                    ? {}
                    : {
                        boxShadow: resolvedDark
                            ? `0 0 2px 1px color-mix(in oklch, white, transparent 65%) inset,
               0 0 10px 4px color-mix(in oklch, white, transparent 85%) inset,
               0px 4px 16px rgba(17, 17, 26, 0.05),
               0px 8px 24px rgba(17, 17, 26, 0.05),
               0px 16px 56px rgba(17, 17, 26, 0.05)`
                            : `0 8px 24px -12px rgba(0, 0, 0, 0.08),
               0 4px 12px -4px rgba(0, 0, 0, 0.04)`,
                    }),
            };
        }
        else {
            // Fallback for Safari/Firefox or when SVG filters aren't supported
            const baseBlur = "12px";
            // Increase blur significantly for frosted mode in fallback
            const effectiveBlur = frosted ? "20px" : baseBlur;
            const fallbackSaturate = "1.8";
            const fallbackBrightness = resolvedDark ? "1.2" : "1.1";
            const filterStr = `blur(${effectiveBlur}) saturate(${fallbackSaturate}) brightness(${fallbackBrightness})`;
            if (resolvedDark) {
                return {
                    ...baseStyles,
                    background: supportsBackdrop
                        ? "rgba(255, 255, 255, 0.1)"
                        : "rgba(0, 0, 0, 0.4)",
                    backdropFilter: supportsBackdrop ? filterStr : undefined,
                    WebkitBackdropFilter: supportsBackdrop ? filterStr : undefined,
                    border: "1px solid rgba(255, 255, 255, 0.2)",
                    ...(hasCustomShadow
                        ? {}
                        : {
                            boxShadow: `inset 0 1px 0 0 rgba(255, 255, 255, 0.2), inset 0 -1px 0 0 rgba(255, 255, 255, 0.1)`,
                        }),
                };
            }
            else {
                return {
                    ...baseStyles,
                    background: supportsBackdrop
                        ? "rgba(255, 255, 255, 0.25)"
                        : "rgba(255, 255, 255, 0.4)",
                    backdropFilter: supportsBackdrop ? filterStr : undefined,
                    WebkitBackdropFilter: supportsBackdrop ? filterStr : undefined,
                    border: "1px solid rgba(255, 255, 255, 0.3)",
                    ...(hasCustomShadow
                        ? {}
                        : {
                            boxShadow: supportsBackdrop
                                ? `0 8px 32px 0 rgba(31, 38, 135, 0.2), 0 2px 16px 0 rgba(31, 38, 135, 0.1), inset 0 1px 0 0 rgba(255, 255, 255, 0.4), inset 0 -1px 0 0 rgba(255, 255, 255, 0.2)`
                                : `inset 0 1px 0 0 rgba(255, 255, 255, 0.5), inset 0 -1px 0 0 rgba(255, 255, 255, 0.3)`,
                        }),
                };
            }
        }
    }, [style, width, height, borderRadius, frosted, svgSupported, backgroundColor, resolvedDark, backgroundOpacity, filterId, backdropBrightness, saturation, hasCustomShadow, supportsBackdrop]);
    const focusVisibleClasses = resolvedDark
        ? "focus-visible:outline-2 focus-visible:outline-[#0A84FF] focus-visible:outline-offset-2"
        : "focus-visible:outline-2 focus-visible:outline-[#007AFF] focus-visible:outline-offset-2";
    const mergedRef = useCallback((node) => {
        containerRef.current = node;
        if (typeof forwardedRef === "function")
            forwardedRef(node);
        else if (forwardedRef)
            forwardedRef.current = node;
    }, [forwardedRef]);
    return (jsxs("div", { ref: mergedRef, className: cn("relative transition-opacity duration-[260ms] ease-out", focusVisibleClasses, className), style: containerStyles, children: [jsx("svg", { className: "w-full h-full pointer-events-none absolute inset-0 opacity-0 -z-10", xmlns: "http://www.w3.org/2000/svg", children: jsxs("defs", { children: [jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", x: "0%", y: "0%", width: "100%", height: "100%", children: [jsx("feImage", { ref: feImageRef, x: "0", y: "0", width: "100%", height: "100%", preserveAspectRatio: "none", result: "map" }), jsx("feDisplacementMap", { ref: redChannelRef, in: "SourceGraphic", in2: "map", result: "dispRed" }), jsx("feColorMatrix", { in: "dispRed", type: "matrix", values: "1 0 0 0 0\n                      0 0 0 0 0\n                      0 0 0 0 0\n                      0 0 0 1 0", result: "red" }), jsx("feDisplacementMap", { ref: greenChannelRef, in: "SourceGraphic", in2: "map", result: "dispGreen" }), jsx("feColorMatrix", { in: "dispGreen", type: "matrix", values: "0 0 0 0 0\n                      0 1 0 0 0\n                      0 0 0 0 0\n                      0 0 0 1 0", result: "green" }), jsx("feDisplacementMap", { ref: blueChannelRef, in: "SourceGraphic", in2: "map", result: "dispBlue" }), jsx("feColorMatrix", { in: "dispBlue", type: "matrix", values: "0 0 0 0 0\n                      0 0 0 0 0\n                      0 0 1 0 0\n                      0 0 0 1 0", result: "blue" }), jsx("feBlend", { in: "red", in2: "green", mode: "screen", result: "rg" }), jsx("feBlend", { in: "rg", in2: "blue", mode: "screen", result: "output" }), jsx("feGaussianBlur", { ref: gaussianBlurRef, in: "output", stdDeviation: "0.7" })] }), jsx("filter", { id: noiseFilterId, x: "0%", y: "0%", width: "100%", height: "100%", children: jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65", numOctaves: "3", stitchTiles: "stitch" }) })] }) }), jsx("div", { className: "relative z-10 h-full rounded-[inherit]", children: children }), jsx("div", { className: "absolute inset-0 pointer-events-none rounded-[inherit] overflow-hidden z-20", children: frosted && (jsx("div", { className: "absolute inset-0 opacity-10 mix-blend-overlay", style: { filter: `url(#${noiseFilterId})` } })) })] }));
});
GlassSurface.displayName = "GlassSurface";

export { GlassSurface };
