<script lang="ts" setup>
import type { Options } from 'typeit'
import type { El } from 'typeit/dist/types'
import TypeIt from 'typeit'
import { onBeforeUnmount, onMounted, shallowRef, watch } from 'vue'

defineOptions({ name: 'TypeIt' })

const props = withDefaults(defineProps<Props>(), {
  speed: 100,
  loop: false,
  cursor: true,
  lifeLike: true,
  strings: () => [],
})

interface Props {
  /** 打字速度 */
  speed?: number
  /** 是否循环 */
  loop?: boolean
  /** 是否显示光标 */
  cursor?: boolean
  /** 打字内容 */
  strings?: string | string[]
  /** 像人一样打字 */
  lifeLike?: boolean
  /** 开始前的延迟 */
  startDelay?: number
  /** 下一段文字的延迟 */
  nextStringDelay?: number
  /** 循环延迟 */
  loopDelay?: number
  /** 兼容旧代码或用户自定义延迟参数 */
  typeDelay?: number
}

const textRef = shallowRef<El>()
const typeItInstance = shallowRef<TypeIt | null>(null)

function init() {
  if (!textRef.value)
    return

  if (typeItInstance.value) {
    typeItInstance.value.destroy()
  }

  // 清空内容，防止重叠
  textRef.value.textContent = ''

  const options: Options = {
    strings: props.strings,
    lifeLike: props.lifeLike,
    speed: props.speed,
    loop: props.loop,
    cursor: props.cursor,
    startDelay: props.startDelay,
    nextStringDelay: props.nextStringDelay ?? props.typeDelay,
    loopDelay: props.loopDelay,
  }

  typeItInstance.value = new TypeIt(textRef.value, options).go()
}

onMounted(() => {
  init()
})

onBeforeUnmount(() => {
  if (typeItInstance.value) {
    typeItInstance.value.destroy()
  }
})

watch(() => [props.strings, props.speed, props.loop], () => {
  init()
})
</script>

<template>
  <span ref="textRef" class="typeit-container" />
</template>

<style scoped></style>
