<template>
  <div class="page-show-time" :style="{ color: textColor, fontSize: textSize, fontWeight }">
    {{ formattedTime }}
  </div>
</template>

<script setup lang="ts">
  import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
  import { getDateObj } from '@/utils/time';

  interface Props {
    /** 显示格式，决定显示哪些时间部分 */
    format?: string;
    /** 文字颜色 */
    textColor?: string;
    /** 文字大小，单位像素 */
    textSize?: string;
    /** 字体粗细 */
    fontWeight?: string;
  }

  const props = withDefaults(defineProps<Props>(), {
    format: 'yyyy-MM-dd HH:mm:ss',
    textColor: '#333333',
    textSize: '16px',
    fontWeight: 'bold',
  });

  const timeData = ref({
    year: '0000',
    month: '00',
    day: '00',
    hour: '00',
    minute: '00',
    second: '00',
  });

  const formattedTime = ref('');

  let timer: NodeJS.Timeout | null = null;

  /**
   * 更新当前时间数据和格式化字符串
   */
  function updateTime() {
    const now = new Date();
    timeData.value = getDateObj(now);

    formattedTime.value = props.format
      .replace('yyyy', timeData.value.year)
      .replace('MM', timeData.value.month)
      .replace('dd', timeData.value.day)
      .replace('HH', timeData.value.hour)
      .replace('mm', timeData.value.minute)
      .replace('ss', timeData.value.second);
  }

  /**
   * 计算到下一秒的毫秒数
   */
  function getDelayToNextSecond(): number {
    const now = new Date();
    const delay = 1000 - now.getMilliseconds();
    return delay;
  }

  /**
   * 设置下一个更新周期
   */
  function scheduleNextUpdate() {
    const delay = getDelayToNextSecond();
    timer = setTimeout(() => {
      updateTime();
      scheduleNextUpdate(); // 递归调用以继续更新
    }, delay);
  }

  watch(
    () => props.format,
    () => {
      updateTime(); // 当格式改变时立即更新
    }
  );

  onMounted(() => {
    updateTime(); // 初始化时立即更新
    scheduleNextUpdate(); // 设置后续更新
  });

  onBeforeUnmount(() => {
    timer && clearTimeout(timer);
  });
</script>

<style lang="scss" scoped>
  .page-show-time {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: monospace;
    white-space: nowrap;
  }
</style>
