'use client';

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

/**
 * 数字增长动画 Hook - 进入视口触发，离开视口重置
 * 使用 requestAnimationFrame 保证与浏览器刷新同步
 */
export function useCountUp(end: number, duration: number = 1500, startRangePercent: number = 0.75) {
  const [mounted, setMounted] = useState(false);
  const [count, setCount] = useState(end); // 初始值设为目标值，避免 hydration 错误
  const elementRef = useRef<HTMLDivElement>(null);
  const startValueRef = useRef<number>(end);
  const rafRef = useRef<number | null>(null);

  // 客户端挂载后设置随机起始值
  useEffect(() => {
    setMounted(true);
    startValueRef.current = Math.floor(end * (startRangePercent + Math.random() * 0.15));
    setCount(startValueRef.current);
  }, [end, startRangePercent]);

  useEffect(() => {
    if (!mounted) return;

    const cancelAnimation = () => {
      if (rafRef.current !== null) {
        cancelAnimationFrame(rafRef.current);
        rafRef.current = null;
      }
    };

    const startAnimation = () => {
      cancelAnimation();

      const start = startValueRef.current;
      const startTime = performance.now();

      const tick = (currentTime: number) => {
        const elapsed = currentTime - startTime;
        const progress = Math.min(elapsed / duration, 1);

        // easeOutCubic 缓动
        const easeOutCubic = 1 - Math.pow(1 - progress, 3);
        const currentCount = Math.floor(start + (end - start) * easeOutCubic);

        setCount(currentCount);

        if (progress < 1) {
          rafRef.current = requestAnimationFrame(tick);
        } else {
          setCount(end); // 确保最终值准确
          rafRef.current = null;
        }
      };

      rafRef.current = requestAnimationFrame(tick);
    };

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          startAnimation();
        } else {
          cancelAnimation();
          setCount(startValueRef.current);
        }
      },
      { threshold: 0.1 }
    );

    if (elementRef.current) {
      observer.observe(elementRef.current);
    }

    return () => {
      observer.disconnect();
      cancelAnimation();
    };
  }, [end, duration, mounted]);

  return { count, elementRef };
}
