import { resolvePosition } from '../util/position.js';
import { cleanupSparkle, ensureOverlay, generateSparkleCSS, isSparkleSupported, isWorkletReady } from './sparkle.js';
export const BTU_RIPPLE_EVENT = 'btu-effect-ripple';
const DEFAULT_HUE_PROPERTIES = {
    '--btu-theme-primary-hue': 264,
    '--btu-theme-error-hue': 27,
    '--btu-theme-success-hue': 157,
};
let defaults = {};
let restoreTimer;
let propertyRegistered = false;
function registerProperty() {
    if (propertyRegistered)
        return;
    try {
        CSS.registerProperty({
            name: '--ripple-r',
            syntax: '<length>',
            inherits: false,
            initialValue: '0px',
        });
    }
    catch {
        // Already registered (e.g. via @property in CSS) or unsupported
    }
    propertyRegistered = true;
}
const RESOLVED = { ready: Promise.resolve(), finished: Promise.resolve() };
export function btuRipple(options) {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches)
        return RESOLVED;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const doc = document;
    if (!doc.startViewTransition)
        return RESOLVED;
    registerProperty();
    const { duration = 1200, ringWidth = 40, feather = 75, hueShift = 0, contrast = 1.8, saturate = 1.5, hueProperties = DEFAULT_HUE_PROPERTIES, } = { ...defaults, ...options };
    const isDark = document.documentElement.classList.contains('dark') || window.matchMedia('(prefers-color-scheme: dark)').matches;
    const effectiveContrast = isDark ? Math.min(contrast, 1.3) : contrast;
    const effectiveBrightness = isDark ? 1.4 : 1;
    if (restoreTimer)
        clearTimeout(restoreTimer);
    const { x, y } = resolvePosition(options.position);
    const maxRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
    const halfBand = ringWidth / 2;
    const endRadius = maxRadius + feather + halfBand;
    const root = document.documentElement;
    const useSparkle = !!options.sparkle && isSparkleSupported() && isWorkletReady();
    const sparkleOpts = typeof options.sparkle === 'object' ? options.sparkle : {};
    const sparkleSize = sparkleOpts.size ?? 300;
    const sparkleDuration = sparkleOpts.duration ?? duration;
    if (useSparkle) {
        ensureOverlay();
    }
    root.style.setProperty('view-transition-name', 'root');
    const style = document.createElement('style');
    let css = `
    ::view-transition-old(root) {
      animation: none;
    }
    ::view-transition-new(root) {
      mix-blend-mode: normal;
      filter: contrast(${effectiveContrast}) saturate(${saturate}) brightness(${effectiveBrightness});
      animation: btu-ripple-ring ${duration}ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
      mask-image: radial-gradient(
        circle at ${x}px ${y}px,
        transparent 0,
        transparent calc(var(--ripple-r) - ${feather + halfBand}px),
        black calc(var(--ripple-r) - ${halfBand}px),
        black calc(var(--ripple-r) + ${halfBand}px),
        transparent calc(var(--ripple-r) + ${feather + halfBand}px)
      );
      -webkit-mask-image: radial-gradient(
        circle at ${x}px ${y}px,
        transparent 0,
        transparent calc(var(--ripple-r) - ${feather + halfBand}px),
        black calc(var(--ripple-r) - ${halfBand}px),
        black calc(var(--ripple-r) + ${halfBand}px),
        transparent calc(var(--ripple-r) + ${feather + halfBand}px)
      );
    }
    @keyframes btu-ripple-ring {
      from { --ripple-r: 0px; }
      to { --ripple-r: ${endRadius}px; }
    }
  `;
    if (useSparkle) {
        css += generateSparkleCSS(x, y, sparkleSize, sparkleDuration);
    }
    style.textContent = css;
    document.head.appendChild(style);
    const transition = doc.startViewTransition(() => {
        for (const [prop, base] of Object.entries(hueProperties)) {
            root.style.setProperty(prop, `${base + hueShift}`);
        }
    });
    const restoreHues = () => {
        for (const prop of Object.keys(hueProperties)) {
            root.style.removeProperty(prop);
        }
    };
    const cleanup = () => {
        if (restoreTimer)
            clearTimeout(restoreTimer);
        restoreHues();
        style.remove();
        root.style.removeProperty('view-transition-name');
        if (useSparkle)
            cleanupSparkle();
    };
    const ready = transition.ready
        .then(() => {
        restoreTimer = setTimeout(restoreHues, Math.max(0, duration - 100));
    })
        .catch(() => { });
    const finished = transition.finished.then(cleanup).catch(cleanup);
    return { ready, finished };
}
btuRipple.setDefaults = (newDefaults) => {
    defaults = { ...defaults, ...newDefaults };
};
btuRipple.listen = () => {
    const handler = (e) => {
        const detail = e.detail;
        if (detail?.position)
            btuRipple(detail);
    };
    document.addEventListener(BTU_RIPPLE_EVENT, handler);
    return () => document.removeEventListener(BTU_RIPPLE_EVENT, handler);
};
//# sourceMappingURL=ripple.js.map