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

type DeadlineTimerOptions = {
  initialSeconds: number
  active: boolean
  intervalMs?: number
  onExpire: () => void
}

type RoundCountdownOptions = {
  seconds: number
  active: boolean
  intervalMs?: number
  onComplete: () => void
}

export function useDeadlineTimer({
  initialSeconds,
  active,
  intervalMs = 100,
  onExpire,
}: DeadlineTimerOptions) {
  const [timeLeft, setTimeLeft] = useState(initialSeconds)
  const deadlineRef = useRef(0)
  const timerRef = useRef<number | null>(null)
  const onExpireRef = useRef(onExpire)

  useEffect(() => {
    onExpireRef.current = onExpire
  }, [onExpire])

  const clearTimer = useCallback(() => {
    if (timerRef.current === null) return
    window.clearInterval(timerRef.current)
    timerRef.current = null
  }, [])

  const tick = useCallback(() => {
    if (deadlineRef.current <= 0) return
    const remaining = Math.max(0, (deadlineRef.current - Date.now()) / 1000)
    setTimeLeft(remaining)
    if (remaining > 0) return
    deadlineRef.current = 0
    clearTimer()
    onExpireRef.current()
  }, [clearTimer])

  const start = useCallback((seconds = initialSeconds) => {
    clearTimer()
    deadlineRef.current = Date.now() + seconds * 1000
    setTimeLeft(seconds)
    timerRef.current = window.setInterval(tick, intervalMs)
  }, [clearTimer, initialSeconds, intervalMs, tick])

  const clear = useCallback(() => {
    deadlineRef.current = 0
    clearTimer()
  }, [clearTimer])

  const reset = useCallback((seconds = initialSeconds) => {
    clear()
    setTimeLeft(seconds)
  }, [clear, initialSeconds])

  useEffect(() => {
    if (!active) clearTimer()
  }, [active, clearTimer])

  useEffect(() => () => clearTimer(), [clearTimer])

  return {
    timeLeft,
    start,
    clear,
    reset,
  }
}

export function useRoundCountdown({
  seconds,
  active,
  intervalMs = 100,
  onComplete,
}: RoundCountdownOptions) {
  return useDeadlineTimer({
    initialSeconds: seconds,
    active,
    intervalMs,
    onExpire: onComplete,
  })
}
