<template>
  <div class="circle_progress">
    <canvas 
      ref="canvasRef" 
      :width="canvasWidth" 
      :height="canvasHeight"
      :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
    ></canvas>
  </div>
</template>

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

/**
 * 圆形进度条组件
 * @description 使用 Canvas 绘制的圆形进度条，支持高分辨率屏幕适配
 */

// ==================== Props 定义 ====================
interface Props {
  /** 进度值 (0-100) */
  process?: number
  /** 线条宽度 */
  lineWidth?: number
  /** 背景圆颜色 */
  backgroundColor?: string
  /** 进度条颜色 */
  lineColor?: string
  /** Canvas 显示宽度（CSS像素） */
  canvasWidth?: number
  /** Canvas 显示高度（CSS像素） */
  canvasHeight?: number
  /** 圆形半径 */
  circleRadius?: number
}

const props = withDefaults(defineProps<Props>(), {
  process: 0,
  lineWidth: 3,
  backgroundColor: '#ffffff',
  lineColor: '#2E64FA',
  canvasWidth: 20,
  canvasHeight: 20,
  circleRadius: 5
})

// ==================== 响应式数据 ====================
/** Canvas DOM 引用 */
const canvasRef = ref<HTMLCanvasElement | null>(null)

/** 防抖定时器 */
let resizeTimer: ReturnType<typeof setTimeout> | null = null

// ==================== 核心方法 ====================

/**
 * 绘制圆形进度条
 * @description 包含背景圆和进度圆弧的绘制，支持高清屏适配
 */
const drawCircle = (): void => {
  const canvas = canvasRef.value
  if (!canvas) return

  // 获取设备像素比
  const dpr = window.devicePixelRatio || 1

  // 设置canvas的实际物理尺寸（像素）- 这会重置 Canvas 状态
  canvas.width = props.canvasWidth * dpr
  canvas.height = props.canvasHeight * dpr

  // 设置canvas的显示尺寸（CSS像素）
  canvas.style.width = props.canvasWidth + 'px'
  canvas.style.height = props.canvasHeight + 'px'

  const ctx = canvas.getContext('2d')
  if (!ctx) return

  // 缩放绘制上下文以匹配设备像素比
  ctx.scale(dpr, dpr)

  // 启用高质量渲染
  ctx.imageSmoothingEnabled = true
  ctx.imageSmoothingQuality = 'high'

  // 设置线条样式
  ctx.lineCap = 'round'
  ctx.lineJoin = 'round'
  ctx.lineWidth = props.lineWidth

  // 清除画布
  ctx.clearRect(0, 0, props.canvasWidth, props.canvasHeight)

  // 计算圆心坐标
  const centerX = props.canvasWidth / 2
  const centerY = props.canvasHeight / 2

  // 绘制背景圆（灰色）
  ctx.beginPath()
  ctx.arc(centerX, centerY, props.circleRadius, 0, 2 * Math.PI)
  ctx.strokeStyle = '#cccccc'
  ctx.stroke()

  // 绘制进度圆弧（仅当进度大于 0 时绘制）
  if (props.process > 0) {
    ctx.beginPath()
    
    // 起始角度：从顶部开始（-90度）
    const startAngle = -90 * Math.PI / 180
    
    // 结束角度：根据进度计算
    const endAngle = ((props.process / 100) * 360 - 90) * Math.PI / 180
    
    console.log('进度值:', props.process, '起始角度:', startAngle, '结束角度:', endAngle)
    
    // 绘制圆弧
    ctx.arc(centerX, centerY, props.circleRadius, startAngle, endAngle, false)
    ctx.strokeStyle = props.lineColor
    ctx.stroke()
  }
}

/**
 * 窗口大小变化处理函数
 * @description 使用防抖优化，避免频繁重绘
 */
const handleResize = (): void => {
  if (resizeTimer) {
    clearTimeout(resizeTimer)
  }
  
  resizeTimer = setTimeout(() => {
    drawCircle()
  }, 100)
}

// ==================== 生命周期钩子 ====================

/**
 * 组件挂载时执行
 */
onMounted(() => {
  drawCircle()
  window.addEventListener('resize', handleResize)
})

/**
 * 组件卸载前执行
 */
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  
  if (resizeTimer) {
    clearTimeout(resizeTimer)
    resizeTimer = null
  }
})

// ==================== 监听器 ====================

/**
 * 监听进度变化，自动重绘
 */
watch(
  () => props.process,
  () => {
    drawCircle()
  }
)

/**
 * 监听 Canvas 尺寸变化，自动重绘
 */
watch(
  () => [props.canvasWidth, props.canvasHeight, props.circleRadius],
  () => {
    drawCircle()
  }
)
</script>

<style lang="scss" scoped>
.circle_progress {
  display: flex;
  justify-content: center;
  align-items: center;
  
  canvas {
    display: block;
  }
}
</style>