"use client";

import {
	type MotionValue,
	motion,
	useSpring,
	useTransform,
} from "framer-motion";
import { useEffect } from "react";

//DOC: https://www.cult-ui.com/docs/components/animated-number

interface AnimatedNumberProps {
	value: number;
	mass?: number;
	stiffness?: number;
	damping?: number;
	precision?: number;
	format?: (value: number) => string;
	onAnimationStart?: () => void;
	onAnimationComplete?: () => void;
}

export function AnimatedNumber({
	value,
	mass = 0.8,
	stiffness = 75,
	damping = 15,
	precision = 0,
	format,
	onAnimationStart,
	onAnimationComplete,
}: AnimatedNumberProps) {
	const spring = useSpring(value, {
		damping,
		mass,
		stiffness,
	});

	const display: MotionValue<string> = useTransform(spring, (current) =>
		format
			? format(parseFloat(current.toFixed(precision)))
			: parseFloat(current.toFixed(precision)).toLocaleString(),
	);

	useEffect(() => {
		spring.set(value);
		if (onAnimationStart) onAnimationStart();
		const unsubscribe = spring.on("change", () => {
			if (spring.get() === value && onAnimationComplete) onAnimationComplete();
		});
		return () => unsubscribe();
	}, [spring, value, onAnimationStart, onAnimationComplete]);

	return <motion.span>{display}</motion.span>;
}
