export interface UseTypewriterOptions {
  speed?: number
  speedMultiplier?: number
}

export function useTypewriter(text: Ref<string> | string, options: UseTypewriterOptions = {}) {
  const { speed = 40, speedMultiplier = 5 } = options

  const textValue = computed(() => toValue(text))
  const displayedText = ref('')
  const isTyping = ref(false)
  const isAccelerated = ref(false)

  let timeoutId: ReturnType<typeof setTimeout> | null = null
  let currentIndex = 0

  const reducedMotion = useReducedMotion()

  function typeNextChar() {
    if (currentIndex < textValue.value.length) {
      displayedText.value = textValue.value.slice(0, currentIndex + 1)
      currentIndex++

      const currentSpeed = isAccelerated.value ? speed / speedMultiplier : speed
      timeoutId = setTimeout(typeNextChar, currentSpeed)
    } else {
      isTyping.value = false
    }
  }

  function start() {
    stop()

    if (reducedMotion.value) {
      displayedText.value = textValue.value
      isTyping.value = false
      return
    }

    displayedText.value = ''
    currentIndex = 0
    isTyping.value = true
    isAccelerated.value = false
    typeNextChar()
  }

  function accelerate() {
    isAccelerated.value = true
  }

  function skip() {
    if (timeoutId) clearTimeout(timeoutId)
    displayedText.value = textValue.value
    isTyping.value = false
  }

  function stop() {
    if (timeoutId) {
      clearTimeout(timeoutId)
      timeoutId = null
    }
  }

  function reset() {
    stop()
    displayedText.value = ''
    currentIndex = 0
    isTyping.value = false
    isAccelerated.value = false
  }

  onUnmounted(() => {
    stop()
  })

  return {
    displayedText: readonly(displayedText),
    isTyping: readonly(isTyping),
    accelerate,
    skip,
    reset,
    start,
  }
}
