import { useEffect, useRef, useState } from 'react';

/**
 * Custom hook that animates a number from its previous value to `target`
 * using an ease-out cubic curve over `duration` milliseconds.
 */
export const useCountUp = (target: number, duration = 900): number => {
    const [display, setDisplay] = useState(0);
    const prev = useRef(0);
    const raf = useRef<number | null>(null);

    useEffect(() => {
        const start = prev.current;
        const startTime = performance.now();

        const tick = (now: number) => {
            const elapsed = now - startTime;
            const progress = Math.min(elapsed / duration, 1);
            // ease-out cubic
            const eased = 1 - Math.pow(1 - progress, 3);
            setDisplay(Math.round(start + (target - start) * eased));
            if (progress < 1) {
                raf.current = requestAnimationFrame(tick);
            } else {
                prev.current = target;
            }
        };

        if (raf.current) cancelAnimationFrame(raf.current);
        raf.current = requestAnimationFrame(tick);

        return () => {
            if (raf.current) cancelAnimationFrame(raf.current);
        };
    }, [target, duration]);

    return display;
};

interface AnimatedAmountProps {
    /** Numeric value to animate to (e.g. grand total in rupees). */
    value: number;
    /** CSS colour string applied to the rendered number. */
    color?: string;
    /** Animation duration in milliseconds. Defaults to 900. */
    duration?: number;
    showCurrency?: boolean;
}

/**
 * Displays a currency amount in Indian locale format (₹) with a smooth
 * count-up animation whenever `value` changes.
 */
const AnimatedAmount = ({
    value,
    color = '#1677ff',
    duration = 900,
    showCurrency = true,
}: AnimatedAmountProps) => {
    const count = useCountUp(value, duration);

    return (
        <span style={{ color, fontWeight: 700, fontSize: 22 }}>
            {showCurrency ? '₹' : ''}
            {count.toLocaleString('en-IN')}
        </span>
    );
};

export default AnimatedAmount;
