/**
 * TabataFit Timer Hook
 * Extracted from player/[id].tsx — reusable timer logic
 */

import { useRef, useEffect, useCallback } from 'react'
import { usePlayerStore } from '../stores'
import i18n from '@/src/shared/i18n'
import type { Workout } from '../types'

export type TimerPhase = 'PREP' | 'WORK' | 'REST' | 'COMPLETE'

interface UseTimerReturn {
  phase: TimerPhase
  timeRemaining: number
  currentRound: number
  totalRounds: number
  currentExercise: string
  nextExercise: string | undefined
  progress: number
  isPaused: boolean
  isRunning: boolean
  isComplete: boolean
  calories: number
  start: () => void
  pause: () => void
  resume: () => void
  skip: () => void
  stop: () => void
}

export function useTimer(workout: Workout | null): UseTimerReturn {
  const store = usePlayerStore()
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)

  // Load workout into store on mount
  useEffect(() => {
    if (workout) {
      store.loadWorkout(workout)
    }
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current)
    }
  }, [workout?.id])

  const w = workout ?? {
    prepTime: 10,
    workTime: 20,
    restTime: 10,
    rounds: 8,
    exercises: [{ name: i18n.t('screens:player.phases.prep'), duration: 20 }],
  }

  // Calculate phase duration
  const phaseDuration =
    store.phase === 'PREP' ? w.prepTime :
    store.phase === 'WORK' ? w.workTime :
    store.phase === 'REST' ? w.restTime : 0

  const progress = phaseDuration > 0 ? 1 - store.timeRemaining / phaseDuration : 1

  // Exercise index based on current round
  const exerciseIndex = (store.currentRound - 1) % w.exercises.length
  const currentExercise = w.exercises[exerciseIndex]?.name ?? ''
  const nextExercise = w.exercises[(exerciseIndex + 1) % w.exercises.length]?.name

  // Timer tick — uses recursive setTimeout so the last second (showing "1")
  // only holds for 600ms before transitioning, instead of the full 1000ms.
  useEffect(() => {
    if (!store.isRunning || store.isPaused || store.phase === 'COMPLETE') {
      if (intervalRef.current) {
        clearTimeout(intervalRef.current)
        intervalRef.current = null
      }
      return
    }

    function scheduleTick() {
      const state = usePlayerStore.getState()
      const isLastSecond = state.timeRemaining <= 1.9
      const delay = isLastSecond ? 600 : 1000

      intervalRef.current = setTimeout(() => {
        const s = usePlayerStore.getState()
        if (!s.isRunning || s.isPaused || s.phase === 'COMPLETE') return

        if (s.timeRemaining <= 1.9) {
          // Phase transition
          if (s.phase === 'PREP') {
            store.setPhase('WORK')
            store.setTimeRemaining(w.workTime)
          } else if (s.phase === 'WORK') {
            const caloriesPerRound = workout ? Math.round(workout.calories / workout.rounds) : 5
            store.addCalories(caloriesPerRound)
            store.setPhase('REST')
            store.setTimeRemaining(w.restTime)
          } else if (s.phase === 'REST') {
            if (s.currentRound >= (workout?.rounds ?? 8)) {
              store.setPhase('COMPLETE')
              store.setTimeRemaining(0)
              store.setRunning(false)
            } else {
              store.setPhase('WORK')
              store.setTimeRemaining(w.workTime)
              store.setCurrentRound(s.currentRound + 1)
            }
          }
          // Don't reschedule — phase change triggers effect re-run
        } else {
          store.setTimeRemaining(s.timeRemaining - 1)
          scheduleTick()
        }
      }, delay)
    }

    scheduleTick()

    return () => {
      if (intervalRef.current) {
        clearTimeout(intervalRef.current)
        intervalRef.current = null
      }
    }
  }, [store.isRunning, store.isPaused, store.phase])

  const start = useCallback(() => {
    store.setRunning(true)
    store.setPaused(false)
  }, [])

  const pause = useCallback(() => {
    store.setPaused(true)
  }, [])

  const resume = useCallback(() => {
    store.setPaused(false)
  }, [])

  const skip = useCallback(() => {
    const s = usePlayerStore.getState()
    if (s.phase === 'PREP') {
      store.setPhase('WORK')
      store.setTimeRemaining(w.workTime)
    } else if (s.phase === 'WORK') {
      store.setPhase('REST')
      store.setTimeRemaining(w.restTime)
    } else if (s.phase === 'REST') {
      if (s.currentRound >= (workout?.rounds ?? 8)) {
        store.setPhase('COMPLETE')
        store.setTimeRemaining(0)
        store.setRunning(false)
      } else {
        store.setPhase('WORK')
        store.setTimeRemaining(w.workTime)
        store.setCurrentRound(s.currentRound + 1)
      }
    }
  }, [])

  const stop = useCallback(() => {
    store.reset()
  }, [])

  return {
    phase: store.phase as TimerPhase,
    timeRemaining: store.timeRemaining,
    currentRound: store.currentRound,
    totalRounds: workout?.rounds ?? 8,
    currentExercise,
    nextExercise: store.phase === 'REST' ? nextExercise : undefined,
    progress,
    isPaused: store.isPaused,
    isRunning: store.isRunning,
    isComplete: store.phase === 'COMPLETE',
    calories: store.calories,
    start,
    pause,
    resume,
    skip,
    stop,
  }
}
