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

export interface CountUpResult {
  /** 当前秒数 */
  seconds: number
  /** 当前分钟 */
  minutes: number
  /** 当前小时 */
  hours: number
  /** 总秒数 */
  totalSeconds: number
  /** 是否在运行 */
  isRunning: boolean
  /** 格式化后的字符串 */
  formatted: string
  /** 暂停 */
  pause: () => void
  /** 继续 */
  resume: () => void
  /** 重置 */
  reset: (newStartFrom?: number) => void
}

export interface CountUpOptions {
  /** 起始值（秒），默认 0 */
  startFrom?: number
  /** 触发间隔（毫秒），默认 1000 */
  interval?: number
  /** 最大值，超出后停止 */
  maxValue?: number
  /** 格式化函数 */
  format?: (result: Pick<CountUpResult, 'hours' | 'minutes' | 'seconds'>) => string
}

/**
 * 正向计时 Hook
 * @param options 配置选项
 */
export function useCountUp(options: CountUpOptions = {}): CountUpResult {
  const { startFrom = 0, interval = 1000, maxValue, format } = options

  const startRef = useRef(startFrom)
  const maxRef = useRef(maxValue)
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const [totalSeconds, setTotalSeconds] = useState(startFrom)
  const [isRunning, setIsRunning] = useState(false)

  // 计算时分秒
  const calcTime = useCallback((total: number) => ({
    totalSeconds: total,
    hours: Math.floor(total / 3600),
    minutes: Math.floor((total % 3600) / 60),
    seconds: total % 60,
  }), [])

  const [time, setTime] = useState(() => calcTime(startFrom))

  // 默认格式化
  const defaultFormat = useCallback((r: Pick<CountUpResult, 'hours' | 'minutes' | 'seconds'>) => {
    const pad = (n: number) => String(n).padStart(2, '0')
    return `${pad(r.hours)}:${pad(r.minutes)}:${pad(r.seconds)}`
  }, [])

  const startInterval = useCallback(() => {
    if (intervalRef.current) clearInterval(intervalRef.current)
    intervalRef.current = setInterval(() => {
      setTotalSeconds(prev => {
        const next = prev + Math.floor(interval / 1000)
        const max = maxRef.current
        if (max !== undefined && next >= max) {
          if (intervalRef.current) clearInterval(intervalRef.current)
          setIsRunning(false)
          return max
        }
        return next
      })
    }, interval)
  }, [interval])

  // 更新 refs
  useEffect(() => {
    startRef.current = startFrom
    setTotalSeconds(startFrom)
    setTime(calcTime(startFrom))
  }, [startFrom, calcTime])

  useEffect(() => {
    maxRef.current = maxValue
  }, [maxValue])

  // 同步 totalSeconds 到 time
  useEffect(() => {
    setTime(calcTime(totalSeconds))
  }, [totalSeconds, calcTime])

  // 控制定时器
  useEffect(() => {
    if (isRunning) {
      startInterval()
    } else {
      if (intervalRef.current) {
        clearInterval(intervalRef.current)
        intervalRef.current = null
      }
    }
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current)
    }
  }, [isRunning, startInterval])

  const pause = useCallback(() => setIsRunning(false), [])
  const resume = useCallback(() => setIsRunning(true), [])
  const reset = useCallback((newStart?: number) => {
    const start = newStart ?? startFrom
    startRef.current = start
    setTotalSeconds(start)
    setTime(calcTime(start))
    setIsRunning(true)
  }, [startFrom, calcTime])

  return {
    ...time,
    isRunning,
    formatted: (format ?? defaultFormat)(time),
    pause,
    resume,
    reset,
  }
}
