import { ref, computed } from 'vue'

const TICK_MS = 100

export function useReplayControls() {
  const isPaused = ref(true)
  const speed = ref(60)
  const scenarioStartMs = ref(0)
  const scenarioEndMs = ref(0)
  const currentMs = ref(0)
  let timer = null

  const scenarioDurationMinutes = computed(() => {
    const span = scenarioEndMs.value - scenarioStartMs.value
    return span > 0 ? span / 60_000 : 0
  })

  const currentOffsetMinutes = computed(() => {
    const span = currentMs.value - scenarioStartMs.value
    return span > 0 ? span / 60_000 : 0
  })

  const progress = computed(() => {
    const span = scenarioEndMs.value - scenarioStartMs.value
    if (span <= 0) return 0
    return Math.min(100, ((currentMs.value - scenarioStartMs.value) / span) * 100)
  })

  const formattedTime = computed(() => {
    const mins = currentOffsetMinutes.value
    const h = Math.floor(mins / 60)
    const m = Math.floor(mins % 60)
    return `${h}:${String(m).padStart(2, '0')}`
  })

  function setScenarioBounds(startMs, endMs) {
    if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs <= startMs) return
    scenarioStartMs.value = startMs
    scenarioEndMs.value = endMs
    if (currentMs.value < startMs || currentMs.value > endMs) {
      currentMs.value = endMs
    }
  }

  function syncToEnd() {
    if (scenarioEndMs.value > scenarioStartMs.value) {
      currentMs.value = scenarioEndMs.value
    }
  }

  function pause() {
    isPaused.value = true
    stopTick()
  }

  function resume() {
    if (scenarioEndMs.value <= scenarioStartMs.value) return
    if (currentMs.value >= scenarioEndMs.value) {
      currentMs.value = scenarioStartMs.value
    }
    isPaused.value = false
    startTick()
  }

  function setSpeed(s) {
    speed.value = s
    if (s === 0) {
      currentMs.value = scenarioEndMs.value
      pause()
    }
  }

  function jumpToOffset(minutes) {
    if (scenarioEndMs.value <= scenarioStartMs.value) return
    const target = scenarioStartMs.value + minutes * 60_000
    currentMs.value = Math.min(Math.max(target, scenarioStartMs.value), scenarioEndMs.value)
  }

  function jumpToTimestamp(iso) {
    if (!iso || scenarioEndMs.value <= scenarioStartMs.value) return
    const ms = new Date(iso).getTime()
    currentMs.value = Math.min(Math.max(ms, scenarioStartMs.value), scenarioEndMs.value)
  }

  function isAtOrBefore(iso) {
    if (!iso) return true
    return new Date(iso).getTime() <= currentMs.value
  }

  function tick() {
    if (isPaused.value || scenarioEndMs.value <= scenarioStartMs.value) return

    if (speed.value === 0) {
      currentMs.value = scenarioEndMs.value
      pause()
      return
    }

    currentMs.value = Math.min(currentMs.value + TICK_MS * speed.value, scenarioEndMs.value)
    if (currentMs.value >= scenarioEndMs.value) pause()
  }

  function startTick() {
    stopTick()
    timer = setInterval(tick, TICK_MS)
  }

  function stopTick() {
    if (timer) clearInterval(timer)
    timer = null
  }

  function stopPlayback() {
    stopTick()
  }

  return {
    isPaused,
    speed,
    scenarioStartMs,
    scenarioEndMs,
    currentMs,
    scenarioDurationMinutes,
    currentOffsetMinutes,
    progress,
    formattedTime,
    setScenarioBounds,
    syncToEnd,
    pause,
    resume,
    setSpeed,
    jumpToOffset,
    jumpToTimestamp,
    isAtOrBefore,
    stopPlayback,
  }
}
