import { jsx } from 'react/jsx-runtime';
import React__default, { useMemo } from 'react';
import { motion, useReducedMotion } from 'motion/react';
import { cn } from '../../../utils/cn.js';

const DIGIT_CONTAINER_STYLE = { height: "1em", width: "0.6em", lineHeight: "1em" };
const DIGIT_ITEM_STYLE = { height: "1em", lineHeight: "1em" };
const DIGITS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const DEFAULT_TRANSITION = { type: "spring", stiffness: 300, damping: 30, bounce: 0 };
const STATIC_CHAR_STYLE = { width: "0.6em" };
const ROOT_STYLE = { lineHeight: "1" };
/**
 * Individual digit component that handles the sliding animation
 */
const SlidingDigit = React__default.memo(({ value, transition, className, disableAnimations, }) => {
    return (jsx("div", { className: cn("relative inline-block overflow-hidden", className), style: DIGIT_CONTAINER_STYLE, "aria-hidden": "true", children: jsx(motion.div, { className: "absolute inset-0", animate: disableAnimations ? { y: 0 } : { y: `${-value * 100}%` }, transition: disableAnimations ? undefined : transition, children: DIGITS.map((num) => (jsx("div", { className: "flex items-center justify-center", style: DIGIT_ITEM_STYLE, children: num }, num))) }) }));
});
SlidingDigit.displayName = "SlidingDigit";
/**
 * Static character component for non-numeric symbols
 */
const StaticChar = React__default.memo(({ char, className }) => {
    return (jsx("div", { className: cn("inline-flex items-center justify-center", className), style: STATIC_CHAR_STYLE, "aria-hidden": "true", children: char }));
});
StaticChar.displayName = "StaticChar";
/**
 * SlidingNumber component with odometer-style digit animation
 *
 * Each digit animates independently, creating a satisfying slot-machine effect.
 * Perfect for counters, statistics, and animated numeric displays.
 *
 * @example
 * ```tsx
 * <SlidingNumber value={12345} />
 * <SlidingNumber value={99.95} decimalPlaces={2} />
 * <SlidingNumber value={42} padStart padWidth={4} /> // "0042"
 * ```
 */
const SlidingNumber = React__default.forwardRef(({ value, decimalPlaces = 0, padStart = false, padWidth, transition = DEFAULT_TRANSITION, className, digitClassName, ...props }, ref) => {
    const shouldReduceMotion = useReducedMotion();
    const shouldDisableAnimations = !!shouldReduceMotion;
    // Format the number with decimal places and padding
    const formattedNumber = useMemo(() => {
        // 1. Convert to fixed decimal string or rounded integer string
        let numStr = decimalPlaces > 0
            ? Number(value).toFixed(decimalPlaces)
            : String(Math.round(value));
        // 2. Handle Padding
        if (padStart && padWidth) {
            const isNegative = numStr.startsWith("-");
            let stringToPad = isNegative ? numStr.substring(1) : numStr;
            const [intPart, decPart] = stringToPad.split(".");
            const paddedInt = intPart.padStart(padWidth, "0");
            stringToPad = decPart ? `${paddedInt}.${decPart}` : paddedInt;
            return isNegative ? `-${stringToPad}` : stringToPad;
        }
        return numStr;
    }, [value, decimalPlaces, padStart, padWidth]);
    // Split formatted number into individual characters
    const characters = useMemo(() => {
        return formattedNumber.split("");
    }, [formattedNumber]);
    return (jsx("div", { ref: ref, className: cn("inline-flex items-center justify-center tabular-nums", className), style: ROOT_STYLE, "aria-label": formattedNumber, ...props, children: characters.map((char, index) => {
            const isNumber = /\d/.test(char);
            if (!isNumber) {
                return (jsx(StaticChar, { char: char, className: digitClassName }, `${char}-${index}`));
            }
            return (jsx(SlidingDigit, { value: parseInt(char, 10), className: digitClassName, transition: transition, disableAnimations: shouldDisableAnimations }, `digit-${index}`));
        }) }));
});
SlidingNumber.displayName = "SlidingNumber";

export { SlidingNumber };
