/**
 * useIdleDetection — time-management.
 *
 * Detects user inactivity using Page Visibility API + mousemove/keydown/scroll
 * event listeners. Idle = no activity for `idleThresholdMs`.
 *
 * Accessibility: respects prefers-reduced-motion (no animated idle indicators).
 * Detection pauses when `enabled=false` (no timer running).
 */
import { useState, useEffect, useRef, useCallback } from 'react'

interface UseIdleDetectionOptions {
  idleThresholdMs: number
  enabled: boolean
}

interface IdleDetectionResult {
  isIdle: boolean
  idleSeconds: number
  /** Unix timestamp (ms) when idle state began; null if not idle. */
  idleStartedAt: number | null
  reset: () => void
}

const ACTIVITY_EVENTS = ['mousemove', 'keydown', 'scroll', 'touchstart', 'pointerdown'] as const

export function useIdleDetection({
  idleThresholdMs,
  enabled,
}: UseIdleDetectionOptions): IdleDetectionResult {
  const [isIdle, setIsIdle] = useState(false)
  const [idleSeconds, setIdleSeconds] = useState(0)
  const [idleStartedAt, setIdleStartedAt] = useState<number | null>(null)

  const lastActivityRef = useRef(Date.now())
  const idleStartRef = useRef<number | null>(null)
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const reset = useCallback(() => {
    lastActivityRef.current = Date.now()
    idleStartRef.current = null
    setIsIdle(false)
    setIdleSeconds(0)
    setIdleStartedAt(null)
  }, [])

  useEffect(() => {
    if (!enabled) {
      reset()
      return
    }

    let debounceTimer: ReturnType<typeof setTimeout> | null = null

    const handleActivity = () => {
      if (debounceTimer) clearTimeout(debounceTimer)
      debounceTimer = setTimeout(() => {
        lastActivityRef.current = Date.now()
        if (isIdle) {
          idleStartRef.current = null
          setIsIdle(false)
          setIdleSeconds(0)
        }
      }, 100)
    }

    const handleVisibilityChange = () => {
      if (!document.hidden) {
        handleActivity()
      }
    }

    // Register activity listeners
    for (const event of ACTIVITY_EVENTS) {
      window.addEventListener(event, handleActivity, { passive: true })
    }
    document.addEventListener('visibilitychange', handleVisibilityChange)

    // Polling interval: check for idle state every second
    timerRef.current = setInterval(() => {
      const now = Date.now()
      const timeSinceActivity = now - lastActivityRef.current

      if (timeSinceActivity >= idleThresholdMs) {
        if (!idleStartRef.current) {
          idleStartRef.current = lastActivityRef.current + idleThresholdMs
          setIdleStartedAt(idleStartRef.current)
        }
        const secs = Math.floor((now - idleStartRef.current) / 1000)
        setIsIdle(true)
        setIdleSeconds(Math.max(0, secs))
      }
    }, 1000)

    return () => {
      if (debounceTimer) clearTimeout(debounceTimer)
      if (timerRef.current) clearInterval(timerRef.current)
      for (const event of ACTIVITY_EVENTS) {
        window.removeEventListener(event, handleActivity)
      }
      document.removeEventListener('visibilitychange', handleVisibilityChange)
    }
  }, [enabled, idleThresholdMs, isIdle, reset])

  return { isIdle, idleSeconds, idleStartedAt, reset }
}
