import { useRef, useLayoutEffect, useEffect } from 'react';
import { animate } from 'motion/react';

const WRAPPER_SELECTOR = "[data-flik-drawer-wrapper]";
/**
 * useScaleBackground
 *
 * Applies an iOS-style scale-down + rounded-corners effect to a wrapper
 * element marked with `data-flik-drawer-wrapper` when an overlay opens.
 *
 * Uses Framer Motion's `animate()` to tween a progress value (0→1) and
 * applies interpolated styles via `onUpdate` for perfect synchronisation.
 *
 * Usage:
 * 1. Wrap your app content with `<div data-flik-drawer-wrapper>...</div>`
 * 2. Call this hook from any overlay component (Drawer, Modal, etc.)
 */
function useScaleBackground({ isOpen, scale = 0.94, borderRadius = 24, position = "bottom", }) {
    const originalBodyBg = useRef("");
    const originalHtmlBg = useRef("");
    const wrapperRef = useRef(null);
    const controlsRef = useRef(null);
    // Track current animation progress so rapid toggling picks up where it left off
    const progressRef = useRef(0);
    useLayoutEffect(() => {
        // Skip if no scaling needed
        if (scale >= 1)
            return;
        // Respect prefers-reduced-motion
        if (typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
            return;
        }
        const wrapper = document.querySelector(WRAPPER_SELECTOR);
        if (!wrapper) {
            if (process.env.NODE_ENV !== "production") {
                console.warn("[Drawer] No element found with `data-flik-drawer-wrapper` attribute. " +
                    "The scale background effect requires a wrapper element. " +
                    "Wrap your app content: <div data-flik-drawer-wrapper>...</div>");
            }
            return;
        }
        wrapperRef.current = wrapper;
        // Cancel any in-flight animation before starting a new one
        if (controlsRef.current) {
            controlsRef.current.stop();
            controlsRef.current = null;
        }
        // Calculate translate offset based on drawer position
        const TRANSLATE_AMT = 14;
        let targetX = 0;
        let targetY = 0;
        switch (position) {
            case "bottom":
                targetY = -TRANSLATE_AMT;
                break;
            case "top":
                targetY = TRANSLATE_AMT;
                break;
            case "left":
                targetX = TRANSLATE_AMT;
                break;
            case "right":
                targetX = -TRANSLATE_AMT;
                break;
        }
        // Helper to apply styles at a given progress value (0 = closed, 1 = open)
        const applyStyles = (t) => {
            const s = 1 + (scale - 1) * t;
            const r = borderRadius * t;
            const tx = targetX * t;
            const ty = targetY * t;
            wrapper.style.transform = `scale(${s}) translate3d(${tx}px, ${ty}px, 0)`;
            wrapper.style.borderRadius = `${r}px`;
        };
        if (isOpen) {
            // Store original backgrounds once
            originalBodyBg.current = document.body.style.background || "";
            originalHtmlBg.current = document.documentElement.style.background || "";
            // Read the theme-aware backdrop color from CSS variable
            const scaleBg = getComputedStyle(document.documentElement)
                .getPropertyValue("--color-scale-background")
                .trim() || "black";
            // Force backdrop colour
            document.body.style.setProperty("background", scaleBg, "important");
            document.documentElement.style.setProperty("background", scaleBg, "important");
            // Anchor transform origin to viewport center relative to wrapper
            const vh = window.innerHeight;
            const rect = wrapper.getBoundingClientRect();
            const originY = vh / 2 - rect.top;
            wrapper.style.transformOrigin = `center ${originY}px`;
            wrapper.style.overflow = "hidden";
            wrapper.style.willChange = "transform, border-radius";
            // Animate progress: current → 1
            const startFrom = progressRef.current;
            controlsRef.current = animate(startFrom, 1, {
                duration: 0.4 * Math.abs(1 - startFrom),
                ease: [0.42, 0, 0.58, 1],
                onUpdate: (t) => {
                    progressRef.current = t;
                    applyStyles(t);
                },
            });
        }
        else {
            // Animate progress: current → 0
            const startFrom = progressRef.current;
            controlsRef.current = animate(startFrom, 0, {
                duration: 0.38 * startFrom,
                ease: [0.42, 0, 0.58, 1],
                onUpdate: (t) => {
                    progressRef.current = t;
                    applyStyles(t);
                },
                onComplete: () => {
                    // Restore original backgrounds
                    if (originalBodyBg.current) {
                        document.body.style.background = originalBodyBg.current;
                    }
                    else {
                        document.body.style.removeProperty("background");
                    }
                    if (originalHtmlBg.current) {
                        document.documentElement.style.background = originalHtmlBg.current;
                    }
                    else {
                        document.documentElement.style.removeProperty("background");
                    }
                    // Clean up all inline animation styles
                    wrapper.style.transform = "";
                    wrapper.style.transformOrigin = "";
                    wrapper.style.borderRadius = "";
                    wrapper.style.overflow = "";
                    wrapper.style.willChange = "";
                },
            });
        }
    }, [isOpen, scale, borderRadius, position]);
    // Full cleanup on unmount
    useEffect(() => {
        return () => {
            if (controlsRef.current) {
                controlsRef.current.stop();
            }
            const wrapper = wrapperRef.current;
            if (wrapper) {
                wrapper.style.transform = "";
                wrapper.style.transformOrigin = "";
                wrapper.style.borderRadius = "";
                wrapper.style.overflow = "";
                wrapper.style.willChange = "";
            }
            if (originalBodyBg.current) {
                document.body.style.background = originalBodyBg.current;
            }
            else {
                document.body.style.removeProperty("background");
            }
            if (originalHtmlBg.current) {
                document.documentElement.style.background = originalHtmlBg.current;
            }
            else {
                document.documentElement.style.removeProperty("background");
            }
        };
    }, []);
}

export { useScaleBackground };
