import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import React__default, { useState, useRef, useCallback, useEffect } from 'react';
import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
import { cn } from '../../../utils/cn.js';

/* ------------------------------------------------------------------ */
/*  Content transition variants                                         */
/* ------------------------------------------------------------------ */
const contentVariants = {
    enter: { opacity: 0, y: 12 },
    center: {
        opacity: 1,
        y: 0,
        transition: { duration: 0.35, ease: [0.25, 0.1, 0.25, 1] },
    },
    exit: {
        opacity: 0,
        y: -12,
        transition: { duration: 0.25, ease: [0.25, 0.1, 0.25, 1] },
    },
};
const reducedMotionVariants = {
    enter: { opacity: 1, y: 0 },
    center: { opacity: 1, y: 0 },
    exit: { opacity: 1, y: 0 },
};
/* ------------------------------------------------------------------ */
/*  Component                                                           */
/* ------------------------------------------------------------------ */
/**
 * StickyScroll
 *
 * Creates an Apple-style sticky scroll experience where one column stays
 * pinned while the other scrolls.  As each scrolling section enters the
 * viewport, the sticky content transitions to match.
 *
 * @example
 * ```tsx
 * <StickyScroll
 *   sections={[
 *     {
 *       id: 'design',
 *       title: 'Design System',
 *       description: 'Build consistent interfaces with a shared design language.',
 *       content: <img src="/design.png" alt="Design system" />,
 *     },
 *     {
 *       id: 'develop',
 *       title: 'Developer Experience',
 *       description: 'TypeScript-first components with full IntelliSense.',
 *       content: <img src="/develop.png" alt="Developer experience" />,
 *     },
 *   ]}
 * />
 * ```
 */
const StickyScroll = React__default.forwardRef(({ sections, contentPosition = 'left', showProgress = true, className, ...props }, ref) => {
    const shouldReduceMotion = useReducedMotion();
    const [activeIndex, setActiveIndex] = useState(0);
    const sectionRefs = useRef([]);
    const containerRef = useRef(null);
    // Set up Intersection Observer to track which section is in view.
    const observerCallback = useCallback((entries) => {
        for (const entry of entries) {
            if (entry.isIntersecting) {
                const index = sectionRefs.current.indexOf(entry.target);
                if (index !== -1) {
                    setActiveIndex(index);
                }
            }
        }
    }, []);
    useEffect(() => {
        const observer = new IntersectionObserver(observerCallback, {
            // Trigger when a section crosses the vertical center of the viewport.
            rootMargin: '-35% 0px -35% 0px',
            threshold: 0,
        });
        const currentRefs = sectionRefs.current;
        for (const sectionRef of currentRefs) {
            if (sectionRef)
                observer.observe(sectionRef);
        }
        return () => {
            for (const sectionRef of currentRefs) {
                if (sectionRef)
                    observer.unobserve(sectionRef);
            }
        };
    }, [observerCallback, sections.length]);
    const activeSection = sections[activeIndex];
    const variants = shouldReduceMotion
        ? reducedMotionVariants
        : contentVariants;
    /* -------------------------------------------------------------- */
    /*  Sub-renders                                                     */
    /* -------------------------------------------------------------- */
    const stickyContent = (jsxs("div", { className: "sticky top-[20vh] flex h-[60vh] items-center justify-center", children: [showProgress && (jsx("div", { className: cn('absolute top-1/2 -translate-y-1/2 flex flex-col gap-2', contentPosition === 'left' ? 'right-0 mr-4' : 'left-0 ml-4'), children: sections.map((section, index) => (jsx("button", { type: "button", "aria-label": `Go to ${section.title}`, onClick: () => {
                        var _a;
                        (_a = sectionRefs.current[index]) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
                            behavior: shouldReduceMotion ? 'auto' : 'smooth',
                            block: 'center',
                        });
                    }, className: cn('h-2 w-2 rounded-full transition-all duration-300', index === activeIndex
                        ? 'scale-125 bg-[var(--color-primary)]'
                        : 'bg-[var(--color-border)] hover:bg-[var(--color-text-muted)]') }, section.id))) })), jsx(AnimatePresence, { mode: "wait", children: jsx(motion.div, { variants: variants, initial: "enter", animate: "center", exit: "exit", className: "flex h-full w-full items-center justify-center", children: activeSection.content }, activeSection.id) })] }));
    const scrollingSections = (jsx("div", { className: "flex flex-col", children: sections.map((section, index) => (jsxs("div", { ref: (el) => {
                sectionRefs.current[index] = el;
            }, className: "flex min-h-[60vh] flex-col justify-center py-16 lg:py-24", children: [jsx("h3", { className: cn('text-2xl font-semibold transition-colors duration-300 lg:text-3xl', index === activeIndex
                        ? 'text-[var(--color-text-primary)]'
                        : 'text-[var(--color-text-muted)]'), children: section.title }), jsx("p", { className: cn('mt-4 max-w-lg text-lg leading-relaxed transition-colors duration-300 lg:text-xl', index === activeIndex
                        ? 'text-[var(--color-text-secondary)]'
                        : 'text-[var(--color-text-placeholder)]'), children: section.description })] }, section.id))) }));
    /* -------------------------------------------------------------- */
    /*  Layout                                                          */
    /* -------------------------------------------------------------- */
    const isContentLeft = contentPosition === 'left';
    return (jsx("div", { ref: (node) => {
            containerRef.current = node;
            if (typeof ref === 'function')
                ref(node);
            else if (ref)
                ref.current = node;
        }, className: cn('relative grid grid-cols-1 gap-8 lg:grid-cols-2 lg:gap-16', className), ...props, children: isContentLeft ? (jsxs(Fragment, { children: [jsx("div", { className: "hidden lg:block", children: stickyContent }), scrollingSections] })) : (jsxs(Fragment, { children: [scrollingSections, jsx("div", { className: "hidden lg:block", children: stickyContent })] })) }));
});
StickyScroll.displayName = 'StickyScroll';

export { StickyScroll };
