<template>
    <div class="ps-send" :class="{
        ['ps-send--'+size]: size? true: false,
        ['ps-send--border']: border
    }" @click="onClick" :disabled="isDisabled"
        :loading="isLoading" type="button" size="small">
        {{ text }}
    </div>
</template>

<script lang="ts" setup>
import { onBeforeUnmount, ref } from "vue"
const props = withDefaults(
    defineProps<{
        duration?: number
        initText?: string
        runText?: string
        loadingText?: string
        resetText?: string
        border?: boolean
        size?: "small" | "big"
    }>(),
    {
        runText: "{%s}s 后重新发送",
        initText: "获取验证码",
        loadingText: "正在发送",
        resetText: "重新获取",
        border: false,
        duration: 60,
    },
)
const emits = defineEmits<{
    (event: "update:modelValue", show: boolean): void
    (event: "send", start: () => void, done: (isDone?: boolean) => void): void
}>()

const text = ref(props.initText)
const isDisabled = ref(false)
const isLoading = ref(false)
let timeID: any

onBeforeUnmount(() => {
    stop()
})

function stop() {
    clearInterval(timeID)
    text.value = props.resetText
    isLoading.value = false
    isDisabled.value = false
    emits("update:modelValue", false)
}
//获取格式化
function getText(second: string | number): string {
    return props.runText.replace(/\{([^{]*?)%s(.*?)\}/g, String(second))
}
function run() {
    isLoading.value = false
    let number = props.duration
    text.value = getText(number)
    clearInterval(timeID)
    timeID = setInterval(() => {
        number--
        text.value = getText(number)
        if (number <= 0) {
            stop()
        }
    }, 1000)
}

function onClick() {
    if (isDisabled.value) return
    if (isLoading.value) return
    emits(
        "send",
        () => {
            isDisabled.value = true
            isLoading.value = true
            text.value = props.loadingText
        },
        (isDone: boolean = true) => {
            if (isDone) {
                run()
            } else {
                stop()
            }
        },
    )
}
</script>
