import { parseTimeString } from '@slidev/parser/utils'
import { useInterval } from '@vueuse/core'
import { computed, toRef } from 'vue'
import { configs } from '../env'
import { sharedState } from '../state/shared'

export function useTimer() {
  const mode = computed(() => configs.timer || 'stopwatch')
  const duration = computed(() => parseTimeString(configs.duration).seconds)
  const interval = useInterval(100, { controls: true })

  const state = toRef(sharedState, 'timer')
  const status = computed(() => state.value?.status)
  const passedMs = computed(() => {
    // eslint-disable-next-line ts/no-unused-expressions
    interval.counter.value
    if (state.value.status === 'stopped' || !state.value.startedAt)
      return 0
    if (state.value.status === 'paused')
      return state.value.pausedAt - state.value.startedAt
    return Date.now() - state.value.startedAt
  })
  const passed = computed(() => passedMs.value / 1000)
  const percentage = computed(() => passed.value / duration.value * 100)

  const timer = computed(() => {
    if (mode.value === 'stopwatch') {
      if (state.value.status === 'stopped' || !state.value.startedAt)
        return { h: '', m: '-', s: '--', ms: '-' }
    }

    const total = mode.value === 'countdown'
      ? duration.value * 1000 - passedMs.value
      : passedMs.value

    let h = Math.floor(total / 1000 / 60 / 60).toString()
    if (h === '0')
      h = ''
    let min = Math.floor(total / 1000 / 60 % 60).toString()
    if (h)
      min = min.padStart(2, '0')
    const sec = Math.floor(total / 1000 % 60).toString().padStart(2, '0')
    const ms = Math.floor(total % 1000 / 100).toString()

    return {
      h,
      m: min,
      s: sec,
      ms,
    }
  })

  function reset() {
    interval.pause()
    state.value = {
      status: 'stopped',
      slides: {},
      startedAt: 0,
      pausedAt: 0,
    }
  }

  function resume() {
    if (!state.value)
      return
    if (state.value?.status === 'stopped') {
      state.value.status = 'running'
      state.value.startedAt = Date.now()
    }
    else if (state.value.status === 'paused') {
      state.value.status = 'running'
      state.value.startedAt = Date.now() - (state.value.pausedAt - state.value.startedAt)
    }
    interval.resume()
  }

  function pause() {
    state.value.status = 'paused'
    state.value.pausedAt = Date.now()
    interval.pause()
  }

  function toggle() {
    if (state.value.status === 'running') {
      pause()
    }
    else {
      resume()
    }
  }

  return {
    state,
    status,
    timer,
    reset,
    toggle,
    resume,
    pause,
    passed,
    percentage,
    duration,
    mode,
  }
}
