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

export interface CountDownResult {
  /** 剩余秒数 */
  seconds: number
  /** 剩余分钟 */
  minutes: number
  /** 剩余小时 */
  hours: number
  /** 剩余天数 */
  days: number
  /** 总剩余秒数 */
  totalSeconds: number
  /** 是否在运行 */
  isRunning: boolean
  /** 是否已结束 */
  isExpired: boolean
  /** 格式化后的字符串 */
  formatted: string
  /** 暂停 */
  pause: () => void
  /** 继续 */
  resume: () => void
  /** 重置 */
  reset: (newTargetDate?: number) => void
}

/**
 * 倒计时 Hook
 * @param targetDate 目标时间戳（毫秒），0 表示立即结束
 * @param options 配置选项
 */
export function useCountDown(
  targetDate: number,
  options: {
    /** 触发间隔（毫秒），默认 1000 */
    interval?: number
    /** 结束时的回调 */
    onComplete?: () => void
    /** 是否自动开始，默认 true */
    autoStart?: boolean
    /** 格式化函数，默认返回 HH:MM:SS 或 DD天HH:MM:SS */
    format?: (result: Pick<CountDownResult, 'days' | 'hours' | 'minutes' | 'seconds'>) => string
  } = {}
): CountDownResult {
  const { interval = 1000, onComplete, autoStart = true, format } = options

  const targetRef = useRef(targetDate)
  const onCompleteRef = useRef(onComplete)
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const [state, setState] = useState(() => calculateTimeLeft(targetDate))
  const [isRunning, setIsRunning] = useState(autoStart)

  // 更新回调引用
  useEffect(() => {
    onCompleteRef.current = onComplete
  }, [onComplete])

  // 更新目标时间
  useEffect(() => {
    targetRef.current = targetDate
    setState(calculateTimeLeft(targetDate))
  }, [targetDate])

  // 计算剩余时间
  function calculateTimeLeft(target: number) {
    const now = Date.now()
    const diff = Math.max(0, Math.floor((target - now) / 1000))
    return {
      totalSeconds: diff,
      days: Math.floor(diff / 86400),
      hours: Math.floor((diff % 86400) / 3600),
      minutes: Math.floor((diff % 3600) / 60),
      seconds: diff % 60,
    }
  }

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

  // 启动定时器
  const startInterval = useCallback(() => {
    if (intervalRef.current) clearInterval(intervalRef.current)
    intervalRef.current = setInterval(() => {
      const left = calculateTimeLeft(targetRef.current)
      setState(left)
      if (left.totalSeconds <= 0) {
        if (intervalRef.current) clearInterval(intervalRef.current)
        setIsRunning(false)
        onCompleteRef.current?.()
      }
    }, interval)
  }, [interval])

  // 控制定时器
  useEffect(() => {
    if (isRunning) {
      // 立即执行一次
      const left = calculateTimeLeft(targetRef.current)
      setState(left)
      if (left.totalSeconds <= 0) {
        setIsRunning(false)
        onCompleteRef.current?.()
      } else {
        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(() => {
    if (state.totalSeconds > 0) setIsRunning(true)
  }, [state.totalSeconds])
  const reset = useCallback((newTarget?: number) => {
    const target = newTarget ?? targetDate
    targetRef.current = target
    setState(calculateTimeLeft(target))
    setIsRunning(true)
  }, [targetDate])

  return {
    ...state,
    isRunning,
    isExpired: state.totalSeconds <= 0,
    formatted: (format ?? defaultFormat)(state),
    pause,
    resume,
    reset,
  }
}
