<template>
  <Transition name="route-loader">
    <div v-if="isLoading" class="route-loader" :style="{ width: `${progress}%` }"></div>
  </Transition>
</template>

<script setup lang="ts">
/**
 * 路由加载指示器组件
 * 在路由切换时显示顶部进度条，提升用户体验
 */
import { ref, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';

// 加载状态和进度
const isLoading = ref(false);
const progress = ref(0);
const timer = ref<NodeJS.Timeout | null>(null);
const progressTimer = ref<NodeJS.Timeout | null>(null);

// 获取路由器实例
const router = useRouter();

/**
 * 开始加载动画
 * 显示进度条并逐步增加进度
 */
function startLoading() {
  // 重置并显示加载条
  isLoading.value = true;
  progress.value = 0;
  
  // 清除之前可能存在的计时器
  if (progressTimer.value) clearInterval(progressTimer.value);
  
  // 创建随机增长的进度条，最多到90%
  progressTimer.value = setInterval(() => {
    // 根据当前进度计算下一步增长量，进度越高增长越慢
    const remaining = 100 - progress.value;
    const increment = remaining * 0.1 * Math.random();
    
    // 增加进度，但确保不超过90%
    progress.value = Math.min(progress.value + increment, 90);
  }, 300);
}

/**
 * 完成加载动画
 * 将进度迅速增加到100%，然后隐藏进度条
 */
function completeLoading() {
  // 清除进度增长定时器
  if (progressTimer.value) {
    clearInterval(progressTimer.value);
    progressTimer.value = null;
  }
  
  // 完成加载动画，设置100%
  progress.value = 100;
  
  // 设置延时以显示完成状态
  if (timer.value) clearTimeout(timer.value);
  timer.value = setTimeout(() => {
    isLoading.value = false;
    progress.value = 0;
  }, 300);
}

/**
 * 监听路由事件
 * 在路由切换开始和结束时触发相应的动画
 */
onMounted(() => {
  // 路由开始切换
  router.beforeEach(() => {
    startLoading();
    return true;
  });
  
  // 路由切换完成
  router.afterEach(() => {
    completeLoading();
  });
  
  // 路由切换出错
  router.onError(() => {
    completeLoading();
  });
});

/**
 * 组件卸载时清理计时器
 */
onUnmounted(() => {
  if (timer.value) clearTimeout(timer.value);
  if (progressTimer.value) clearInterval(progressTimer.value);
});
</script> 