/**
 * 数字滚动动画工具函数
 * @param {Function} updateCallback - 更新数字的回调函数
 * @param {number} target - 目标数字
 * @param {number} duration - 动画持续时间（毫秒）
 * @param {Function} easingFunction - 缓动函数
 */
export function animateNumber(updateCallback, target, duration = 2000, easingFunction = easeOutQuart) {
  const start = 0
  const startTime = performance.now()
  
  const animate = (currentTime) => {
    const elapsed = currentTime - startTime
    const progress = Math.min(elapsed / duration, 1)
    
    const easedProgress = easingFunction(progress)
    const current = Math.floor(start + (target - start) * easedProgress)
    
    updateCallback(current)
    
    if (progress < 1) {
      requestAnimationFrame(animate)
    } else {
      updateCallback(target)
    }
  }
  
  requestAnimationFrame(animate)
}

/**
 * 缓动函数 - 四次方缓出
 * @param {number} t - 进度值 (0-1)
 * @returns {number} 缓动后的值
 */
export function easeOutQuart(t) {
  return 1 - Math.pow(1 - t, 4)
}

/**
 * 缓动函数 - 三次方缓出
 * @param {number} t - 进度值 (0-1)
 * @returns {number} 缓动后的值
 */
export function easeOutCubic(t) {
  return 1 - Math.pow(1 - t, 3)
}

/**
 * 缓动函数 - 二次方缓出
 * @param {number} t - 进度值 (0-1)
 * @returns {number} 缓动后的值
 */
export function easeOutQuad(t) {
  return 1 - (1 - t) * (1 - t)
}

/**
 * 创建 Intersection Observer 来触发数字动画
 * @param {string} selector - 要观察的元素选择器
 * @param {Function} callback - 当元素进入视口时的回调函数
 * @param {Object} options - Intersection Observer 选项
 */
export function createNumberAnimationObserver(selector, callback, options = {}) {
  const defaultOptions = {
    threshold: 0.5,
    rootMargin: '0px 0px -100px 0px'
  }
  
  const observerOptions = { ...defaultOptions, ...options }
  
  const element = document.querySelector(selector)
  if (!element) {
    console.warn(`Element with selector "${selector}" not found`)
    return null
  }

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          callback()
          observer.unobserve(entry.target) // 只触发一次
        }
      })
    },
    observerOptions
  )

  observer.observe(element)
  return observer
}