import type { Choice } from '../types'

export interface ChoiceTimerState {
  total: number
  remaining: number
}

type TimerUpdateCallback = (state: ChoiceTimerState) => void
type TimeoutCallback = (choice: Choice) => void

export class ChoiceSystem {
  private timerId: ReturnType<typeof setInterval> | null = null
  private timeoutId: ReturnType<typeof setTimeout> | null = null
  private timeLimit = 0
  private elapsed = 0
  private tickMs = 100
  private onUpdate: TimerUpdateCallback | null = null
  private onTimeout: TimeoutCallback | null = null

  start(choices: Choice[], onUpdate: TimerUpdateCallback, onTimeout: TimeoutCallback) {
    this.clear()

    const timed = choices.filter((c) => c.timeLimit && c.timeLimit > 0)
    if (timed.length === 0) return

    const maxLimitSec = Math.max(...timed.map((c) => c.timeLimit!))
    const maxLimitMs = maxLimitSec * 1000

    this.timeLimit = maxLimitMs
    this.elapsed = 0
    this.onUpdate = onUpdate
    this.onTimeout = onTimeout

    this.onUpdate({ total: maxLimitSec, remaining: maxLimitSec })

    this.timerId = setInterval(() => {
      this.elapsed += this.tickMs
      const remainingSec = Math.max(0, maxLimitMs - this.elapsed) / 1000
      this.onUpdate?.({
        total: maxLimitSec,
        remaining: Math.ceil(remainingSec * 10) / 10,
      })
    }, this.tickMs)

    this.timeoutId = setTimeout(() => {
      this.clear()
      if (choices.length > 0) {
        this.onTimeout?.(choices[0])
      }
    }, maxLimitMs)
  }

  stop() {
    this.clear()
  }

  private clear() {
    if (this.timerId !== null) {
      clearInterval(this.timerId)
      this.timerId = null
    }
    if (this.timeoutId !== null) {
      clearTimeout(this.timeoutId)
      this.timeoutId = null
    }
  }

  destroy() {
    this.clear()
    this.onUpdate = null
    this.onTimeout = null
  }
}
