<template>
  <div
    class="circle-progress"
    :style="{
      width: '5vw',
      height: '5vw',
    }"
  >
    <!-- 背景圆环 -->
    <div class="circle-bg" :style="{ borderColor: bgColor }"></div>

    <!-- 进度圆环容器（用于实现圆角） -->
    <div class="circle-bar-wrapper">
      <!-- 进度圆环（核心） -->
      <div
        class="circle-bar"
        :style="{
          background: `conic-gradient(${color} ${animateProgress}%, transparent ${animateProgress}%)`,
          '--thickness': `${thickness}px`,
          '--half-thickness': `${thickness / 2}px`,
        }"
      ></div>
    </div>

    <!-- 中间文字 -->
    <div class="circle-content" v-if="showText">
      <div class="progress-number">{{ Math.round(animateProgress) }}%</div>
      <div class="progress-label">进度</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, onMounted, watch } from 'vue';

/**
 * 纯CSS环形进度条组件（APP/移动端专用）
 * 适配设计图样式，带数字加载动效
 */
interface ProgressProps {
  /** 进度 0~100 */
  progress?: number;
  /** 进度条颜色 */
  color?: string;
  /** 背景圆环颜色 */
  bgColor?: string;
  /** 圆环粗细（优化后默认更细） */
  thickness?: number;
  /** 是否显示中间文字 */
  showText?: boolean;
  /** 动画时长(秒) */
  duration?: number;
}

// 定义Props（thickness默认改为1px，更细）
const props = withDefaults(defineProps<ProgressProps>(), {
  progress: 0,
  color: '#409EFF', // 匹配设计图蓝色
  bgColor: '#E5E5E5', // 灰色背景（提高不透明度，保证显示清晰）
  thickness: 1, // 进度条更细，默认1px
  showText: true,
  duration: 1.5, // 动画时长
});

// 限制进度在0-100之间
const realProgress = computed(() => {
  const p = Number(props.progress);
  return isNaN(p) ? 0 : Math.max(0, Math.min(100, p));
});

// 动画进度值
const animateProgress = ref(0);

// 数字加载动画
const startProgressAnimation = () => {
  const target = realProgress.value;
  const duration = props.duration * 1000;
  const frameRate = 60;
  const totalFrames = duration / (1000 / frameRate);
  const increment = target / totalFrames;
  
  let currentFrame = 0;
  const timer = setInterval(() => {
    currentFrame++;
    animateProgress.value += increment;
    
    if (currentFrame >= totalFrames || animateProgress.value >= target) {
      animateProgress.value = target;
      clearInterval(timer);
    }
  }, 1000 / frameRate);
};

// 监听进度变化重新执行动画
watch(realProgress, () => {
  animateProgress.value = 0;
  startProgressAnimation();
}, { immediate: false });

// 组件挂载时执行动画
onMounted(() => {
  startProgressAnimation();
});
</script>

<style scoped>
.circle-progress {
  position: relative;
  flex-shrink: 0;
  aspect-ratio: 1/1;
  /* 增加立体阴影，提升层次感 */
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  border-radius: 50%;
  /* 背景色保证阴影显示完整 */
  background: #fff;
}

/* 背景圆环（完整显示灰色环） */
.circle-bg {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 3px  solid #E8E9EA;
  box-sizing: border-box;
  opacity: 1;
  z-index: 2;
  position: relative;
}

/* 进度圆环容器（核心：实现进度条圆角） */
.circle-bar-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  z-index: 3;
  /* 裁剪超出部分，保证圆角效果 */
  overflow: hidden;
}

/* 进度圆环（核心） */
.circle-bar {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  /* 环形核心：锥形渐变 + 遮罩 */
  -webkit-mask: radial-gradient(
    transparent calc(50% - 3px),
    black calc(50% - 3px)
  );
  mask: radial-gradient(
    transparent calc(50% - 3px),
    black calc(50% - 3px)
  );
  /* 进度条圆角关键：通过伪元素实现 */
  &::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    right: 3px;
    bottom: 3px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 13px rgba(255, 255, 255, 1);
  }
  /* 进度条末端圆角优化 */
  clip-path: circle(50% at center);
}

/* 中间文字容器 */
.circle-content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80%;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 3; /* 文字层级最高 */
}

/* 百分比数字样式 - 匹配设计图 */
.progress-number {
  font-size: 1.2vw; /* 适配5vw容器的字体大小 */
  font-weight: 600;
  color: #333;
  line-height: 1;
  margin-bottom: 0.2vw;
}

/* 进度标签样式 - 匹配设计图 */
.progress-label {
  font-size: 1.1vw; /* 适配5vw容器的字体大小 */
  color: #666;
  line-height: 1;
}
</style>