/**
 * Scroll-reveal action — fades elements in when they enter the viewport.
 *
 * Usage: <div use:reveal>...</div>
 *        <div use:reveal={{ delay: 200, threshold: 0.2 }}>...</div>
 *
 * The element gets the `.reveal` CSS class on mount and `.revealed` when
 * it enters the viewport. Animation is defined in style.css.
 *
 * SSR-safe: no-ops when IntersectionObserver is unavailable.
 */

export interface RevealOptions {
    /** Delay in ms before the animation starts (default: 0) */
    delay?: number
    /** IntersectionObserver threshold 0–1 (default: 0.15) */
    threshold?: number
    /** Only animate once, then disconnect (default: true) */
    once?: boolean
}

export function reveal(node: HTMLElement, options: RevealOptions = {}) {
    if (node.closest("[data-admin-preview='true']")) {
        node.classList.add("reveal", "revealed")
        return
    }

    if (typeof IntersectionObserver === "undefined") return

    const { delay = 0, threshold = 0.15, once = true } = options

    node.classList.add("reveal")

    const observer = new IntersectionObserver(
        (entries) => {
            for (const entry of entries) {
                if (entry.isIntersecting) {
                    if (delay > 0) {
                        setTimeout(() => node.classList.add("revealed"), delay)
                    } else {
                        node.classList.add("revealed")
                    }
                    if (once) observer.unobserve(node)
                } else if (!once) {
                    node.classList.remove("revealed")
                }
            }
        },
        { threshold }
    )

    observer.observe(node)

    return {
        update(newOptions: RevealOptions) {
            // Options are static for simplicity — recreate if needed
        },
        destroy() {
            observer.unobserve(node)
            observer.disconnect()
        },
    }
}
