import { jsx } from 'react/jsx-runtime';
import React__default, { useMemo, Children, isValidElement, useState, useEffect, useRef, useCallback } from 'react';
import { useReducedMotion, motion, useMotionValue, useTransform } from 'motion/react';
import { cn } from '../../../utils/cn.js';
import { cardStackTheme } from './CardStack.theme.js';

function CardRotate({ children, onSendToBack, dragThreshold, disabled, shouldReduceMotion, }) {
    const x = useMotionValue(0);
    const y = useMotionValue(0);
    const rotateX = useTransform(y, [-100, 100], [60, -60]);
    const rotateY = useTransform(x, [-100, 100], [-60, 60]);
    function handleDragEnd(_event, info) {
        const sensitivity = dragThreshold * 300; // Convert to pixels
        if (Math.abs(info.offset.x) > sensitivity ||
            Math.abs(info.offset.y) > sensitivity) {
            onSendToBack();
        }
        else {
            x.set(0);
            y.set(0);
        }
    }
    if (disabled || shouldReduceMotion) {
        return (jsx(motion.div, { className: "absolute inset-0 cursor-pointer", style: { x: 0, y: 0 }, children: children }));
    }
    return (jsx(motion.div, { className: "absolute inset-0 cursor-grab", style: { x, y, rotateX, rotateY }, drag: true, dragConstraints: { top: 0, right: 0, bottom: 0, left: 0 }, dragElastic: 0.6, whileTap: { cursor: "grabbing" }, onDragEnd: handleDragEnd, children: children }));
}
const CARD_SPRING_TRANSITION = {
    type: "spring",
    stiffness: 260,
    damping: 20,
};
/**
 * CardStack - Interactive card stack component with drag/swipe gestures
 */
const CardStackRoot = React__default.forwardRef(({ 
// Behavior props
draggable = true, dragThreshold = 0.3, loop = false, rotationRange = 5, autoPlay = false, autoPlayInterval = 3000, 
// Callbacks
onCardChange, onCardSwipe, 
// Appearance
perspective = "md", scaleStep = 0.06, 
// Accessibility
"aria-label": ariaLabel, disabled = false, 
// Theme & Styling
theme: themeOverrides, className, 
// Children
children, ...rest }, ref) => {
    // Extract cards from children
    const cardsArray = useMemo(() => {
        return Children.toArray(children).filter((child) => isValidElement(child));
    }, [children]);
    const totalCards = cardsArray.length;
    // Stack state: array of objects with id and content
    // Last item in array is on TOP visually
    const [stack, setStack] = useState(() => {
        return cardsArray.map((content, index) => ({
            id: index,
            content,
        }));
    });
    // Update stack when children change
    useEffect(() => {
        setStack(cardsArray.map((content, index) => ({
            id: index,
            content,
        })));
    }, [cardsArray]);
    // Pause state for autoplay
    const [isPaused, setIsPaused] = useState(false);
    // Check for reduced motion
    const shouldReduceMotion = useReducedMotion();
    // Track if component is mounted
    const isMounted = useRef(true);
    useEffect(() => {
        return () => {
            isMounted.current = false;
        };
    }, []);
    // Merge theme with overrides
    const theme = useMemo(() => {
        var _a, _b, _c, _d, _e, _f;
        const baseTheme = cardStackTheme;
        const overrides = themeOverrides || {};
        return {
            rootStyle: overrides.rootStyle || baseTheme.rootStyle,
            containerStyle: overrides.containerStyle || baseTheme.containerStyle,
            cardBaseStyle: overrides.cardBaseStyle || baseTheme.cardBaseStyle,
            cardDisabledStyle: overrides.cardDisabledStyle || baseTheme.cardDisabledStyle,
            perspective: {
                sm: ((_a = overrides.perspective) === null || _a === void 0 ? void 0 : _a.sm) || baseTheme.perspective.sm,
                md: ((_b = overrides.perspective) === null || _b === void 0 ? void 0 : _b.md) || baseTheme.perspective.md,
                lg: ((_c = overrides.perspective) === null || _c === void 0 ? void 0 : _c.lg) || baseTheme.perspective.lg,
            },
            states: {
                idle: ((_d = overrides.states) === null || _d === void 0 ? void 0 : _d.idle) || baseTheme.states.idle,
                dragging: ((_e = overrides.states) === null || _e === void 0 ? void 0 : _e.dragging) || baseTheme.states.dragging,
                exiting: ((_f = overrides.states) === null || _f === void 0 ? void 0 : _f.exiting) || baseTheme.states.exiting,
            },
        };
    }, [themeOverrides]);
    // Send card to back of stack (becomes bottom card)
    const sendToBack = useCallback((id) => {
        setStack((prev) => {
            const newStack = [...prev];
            const index = newStack.findIndex((card) => card.id === id);
            const [card] = newStack.splice(index, 1);
            newStack.unshift(card); // Add to beginning (bottom of visual stack)
            return newStack;
        });
        onCardChange === null || onCardChange === void 0 ? void 0 : onCardChange(id);
        onCardSwipe === null || onCardSwipe === void 0 ? void 0 : onCardSwipe(id, "left");
    }, [onCardChange, onCardSwipe]);
    // Autoplay logic
    useEffect(() => {
        if (!autoPlay || disabled || isPaused || stack.length <= 1)
            return;
        const timer = setInterval(() => {
            if (isMounted.current) {
                const topCardId = stack[stack.length - 1].id; // Last item is on top
                sendToBack(topCardId);
            }
        }, autoPlayInterval);
        return () => clearInterval(timer);
    }, [autoPlay, disabled, isPaused, stack, autoPlayInterval, sendToBack]);
    // Pause/resume handlers for autoplay
    const handleMouseEnter = useCallback(() => {
        if (autoPlay) {
            setIsPaused(true);
        }
    }, [autoPlay]);
    const handleMouseLeave = useCallback(() => {
        if (autoPlay) {
            setIsPaused(false);
        }
    }, [autoPlay]);
    // Keyboard navigation
    const handleKeyDown = useCallback((e) => {
        if (disabled || stack.length === 0)
            return;
        switch (e.key) {
            case "ArrowRight":
            case " ":
            case "Enter":
                e.preventDefault();
                const topCardId = stack[stack.length - 1].id;
                sendToBack(topCardId);
                break;
        }
    }, [disabled, stack, sendToBack]);
    // Generate stable random rotations per card
    const randomRotations = useRef(new Map());
    const getRandomRotation = useCallback((cardId) => {
        if (!randomRotations.current.has(cardId)) {
            randomRotations.current.set(cardId, rotationRange ? Math.random() * rotationRange * 2 - rotationRange : 0);
        }
        return randomRotations.current.get(cardId);
    }, [rotationRange]);
    // Memoize theme classes
    const themeClasses = useMemo(() => ({
        root: cn(theme.rootStyle, theme.perspective[perspective], disabled && "opacity-50 pointer-events-none", className),
        container: theme.containerStyle,
    }), [theme, perspective, disabled, className]);
    // Don't render if no cards
    if (totalCards === 0) {
        return null;
    }
    return (jsx("div", { ref: ref, role: "region", "aria-roledescription": "card stack", "aria-label": ariaLabel || "Interactive card stack", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, "data-disabled": disabled, className: themeClasses.root, style: {
            perspective: 600,
        }, ...rest, children: jsx("div", { className: themeClasses.container, children: stack.map((card, index) => {
                const randomRotate = getRandomRotation(card.id);
                // Top card is last in array (stack.length - 1)
                // index 0 = bottom card, index stack.length-1 = top card
                const visualIndex = stack.length - index - 1;
                const isTopCard = index === stack.length - 1;
                return (jsx(CardRotate, { onSendToBack: () => sendToBack(card.id), dragThreshold: dragThreshold, disabled: !draggable || !isTopCard || disabled, shouldReduceMotion: !!shouldReduceMotion, children: jsx(motion.div, { className: cn(theme.cardBaseStyle, disabled && theme.cardDisabledStyle), animate: {
                            rotateZ: visualIndex * 4 + randomRotate,
                            scale: 1 + index * scaleStep - stack.length * scaleStep,
                            transformOrigin: "90% 90%",
                        }, initial: false, transition: CARD_SPRING_TRANSITION, children: card.content }) }, card.id));
            }) }) }));
});
CardStackRoot.displayName = "CardStack";
const CardStack = CardStackRoot;

export { CardStack };
