"use client"

import { useState, useEffect, useRef } from "react"
import { useInView } from "react-intersection-observer"
import { cn } from "@/lib/utils"

interface CountUpAnimationProps {
  end: number
  start?: number
  duration?: number
  delay?: number
  prefix?: string
  suffix?: string
  decimals?: number
  className?: string
}

export function CountUpAnimation({
  end,
  start = 0,
  duration = 2000,
  delay = 0,
  prefix = "",
  suffix = "",
  decimals = 0,
  className,
}: CountUpAnimationProps) {
  const [count, setCount] = useState(start)
  const countRef = useRef<number>(start)
  const [ref, inView] = useInView({
    triggerOnce: true,
    threshold: 0.1,
  })

  useEffect(() => {
    let startTime: number | null = null
    let animationFrame: number | null = null

    // Only start animation when in view and after delay
    if (!inView) return

    const timeout = setTimeout(() => {
      const animate = (timestamp: number) => {
        if (!startTime) startTime = timestamp
        const progress = Math.min((timestamp - startTime) / duration, 1)

        // Use easeOutExpo for a nice deceleration effect
        const easeOutExpo = 1 - Math.pow(2, -10 * progress)
        const currentCount = start + (end - start) * easeOutExpo

        countRef.current = currentCount
        setCount(currentCount)

        if (progress < 1) {
          animationFrame = requestAnimationFrame(animate)
        } else {
          // Ensure we end exactly at the target number
          countRef.current = end
          setCount(end)
        }
      }

      animationFrame = requestAnimationFrame(animate)
    }, delay)

    return () => {
      if (timeout) clearTimeout(timeout)
      if (animationFrame) cancelAnimationFrame(animationFrame)
    }
  }, [inView, start, end, duration, delay])

  // Format the number with commas and decimals
  const formattedCount = () => {
    const value = Math.round(count * Math.pow(10, decimals)) / Math.pow(10, decimals)
    return (
      prefix +
      value.toLocaleString(undefined, {
        minimumFractionDigits: decimals,
        maximumFractionDigits: decimals,
      }) +
      suffix
    )
  }

  return (
    <span ref={ref} className={cn("tabular-nums", className)}>
      {formattedCount()}
    </span>
  )
}

