<template>
  <slot name="renderText" :time="countdown.current.value">
    <Text v-bind="$attrs" :text="formatText()" />
  </slot>
</template>

<script setup lang="ts">
import Text, { type TextProps } from '@/components/basic/Text.vue';
import { useCountDown } from './CountdownHook';
import { onBeforeUnmount, onMounted, watch } from 'vue';
import { FormatUtils } from '@imengyu/imengyu-utils';

export interface CountDownProps extends TextProps {
  /**
   * 倒计时时长，单位毫秒
   * @default 0
   */
  time?: number;
  /**
   * 时间格式
   * @default 'HH:mm:ss'
   */
  format?: string;
  /**
   * 是否自动开始倒计时
   * @default true
   */
  autoStart?: boolean;
  /**
   * 是否开启毫秒级渲染
   * @default false
   */
  millisecond?: boolean;
}

export interface CountDownInstance {
  start: () => void;
  stop: () => void;
  reset: (time?: number) => void;
}

const emit = defineEmits<{
  /**
   * 倒计时结束事件
   */
  (e: 'finish'): void;
}>();

const props = withDefaults(defineProps<CountDownProps>(), {
  time: 0,
  format: 'HH:mm:ss',
  autoStart: true,
  millisecond: false,
});


const countdown = useCountDown({
  time: props.time || 0,
  millisecond: props.millisecond || false,
  onFinish: () => emit('finish'),
});

watch(() => props.time, () => {
  countdown.reset(props.time);
});

onMounted(() => {
  if (props.autoStart !== false)
    countdown.start();
});
onBeforeUnmount(() => {
  countdown.stop();
});

defineExpose<CountDownInstance>({
  start() { countdown.start(); },
  stop() { countdown.stop(); },
  reset(time) { countdown.reset(time); },
});

function formatText() {
  let str = props.format ? props.format : "HH:mm:ss";
  str = str.replace(/DD/, FormatUtils.formatNumberWithZero(countdown.current.value.days, 2));
  str = str.replace(/HH/, FormatUtils.formatNumberWithZero(countdown.current.value.hours, 2));
  str = str.replace(/mm/, FormatUtils.formatNumberWithZero(countdown.current.value.minutes, 2));
  str = str.replace(/ss/, FormatUtils.formatNumberWithZero(countdown.current.value.seconds, 2));
  str = str.replace(/SSS/, FormatUtils.formatNumberWithZero(countdown.current.value.milliseconds, 3));
  str = str.replace(/SS/, FormatUtils.formatNumberWithZero(Math.floor(countdown.current.value.milliseconds / 10), 2));
  str = str.replace(/S/, Math.floor(countdown.current.value.milliseconds / 100).toString());
  return str;
}
</script>