"use client";

import { animate, useInView, useMotionValue, useTransform } from "motion/react";
import { motion } from "motion/react";
import { type CSSProperties, useEffect, useRef } from "react";

const pairToIndex = (p: string): number => (p.charCodeAt(0) - 65) * 26 + (p.charCodeAt(1) - 65);

const indexToPair = (i: number): string => {
  const f = Math.floor(i / 26);
  const s = i % 26;
  return String.fromCharCode(65 + f) + String.fromCharCode(65 + s);
};

type LetterCounterProps = {
  from?: string;
  to?: string;
  duration?: number;
  delay?: number;
  className?: string;
  style?: CSSProperties;
};

/**
 * Letter "spin" between two two-letter codes (default AA → NN).
 * Use as an animated placeholder while a real value loads or to imply a pending figure.
 */
export function LetterCounter({
  from = "AA",
  to = "NN",
  duration = 1.0,
  delay = 0.2,
  className,
  style,
}: LetterCounterProps) {
  const ref = useRef<HTMLSpanElement>(null);
  const inView = useInView(ref, { once: true, amount: 0.4 });
  const value = useMotionValue(pairToIndex(from));
  const display = useTransform(value, (latest) => indexToPair(Math.round(latest)));

  useEffect(() => {
    if (!inView) return;
    const controls = animate(value, pairToIndex(to), {
      duration,
      delay,
      ease: "linear",
    });
    return controls.stop;
  }, [inView, to, duration, delay, value]);

  return (
    <motion.span ref={ref} className={className} style={style}>
      {display}
    </motion.span>
  );
}
