"use client";

import { useEffect, useRef, useState } from "react";
import { animate, useInView, useMotionValue } from "framer-motion";

interface Props {
  to: number;
  from?: number;
  duration?: number;
  format?: (n: number) => string;
  className?: string;
  ariaLabel?: string;
}

export function Counter({
  to,
  from = 0,
  duration = 1.4,
  format,
  className,
  ariaLabel,
}: Props) {
  const ref = useRef<HTMLSpanElement>(null);
  const inView = useInView(ref, { once: true, margin: "-40px" });
  const value = useMotionValue(from);
  const [display, setDisplay] = useState(format ? format(from) : String(from));

  useEffect(() => {
    if (!inView) return;
    const controls = animate(value, to, {
      duration,
      ease: [0.16, 1, 0.3, 1],
      onUpdate: (latest) => {
        setDisplay(format ? format(latest) : String(Math.round(latest)));
      },
    });
    return () => controls.stop();
  }, [inView, to, duration, value, format]);

  return (
    <span
      ref={ref}
      className={className}
      aria-label={ariaLabel ?? (format ? format(to) : String(to))}
    >
      {display}
    </span>
  );
}
