<template>
  <div class="particle-container" ref="container">
    <canvas ref="canvas" class="particle-canvas"></canvas>
  </div>
</template>

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

// 定义组件名称
defineOptions({
  name: 'ParticleEffect'
})

const container = ref<HTMLElement>()
const canvas = ref<HTMLCanvasElement>()
let animationId: number
let particles: Particle[] = []

interface Particle {
  x: number
  y: number
  vx: number
  vy: number
  size: number
  opacity: number
  color: string
}

const colors = [
  'rgba(26, 26, 26, 0.12)',
  'rgba(26, 26, 26, 0.08)',
  'rgba(92, 92, 92, 0.1)',
  'rgba(138, 138, 138, 0.08)',
  'rgba(26, 26, 26, 0.06)'
]

const createParticle = (): Particle => {
  return {
    x: Math.random() * (canvas.value?.width || 0),
    y: Math.random() * (canvas.value?.height || 0),
    vx: (Math.random() - 0.5) * 2,
    vy: (Math.random() - 0.5) * 2,
    size: Math.random() * 3 + 1,
    opacity: Math.random() * 0.5 + 0.2,
    color: colors[Math.floor(Math.random() * colors.length)] ?? colors[0]!
  }
}

const initParticles = () => {
  particles = []
  for (let i = 0; i < 50; i++) {
    particles.push(createParticle())
  }
}

const updateParticles = () => {
  if (!canvas.value) return
  
  const ctx = canvas.value.getContext('2d')
  if (!ctx) return
  
  ctx.clearRect(0, 0, canvas.value.width, canvas.value.height)
  
  particles.forEach((particle, index) => {
    // 更新位置
    particle.x += particle.vx
    particle.y += particle.vy
    
    // 边界检测
    if (particle.x < 0 || particle.x > canvas.value!.width) {
      particle.vx *= -1
    }
    if (particle.y < 0 || particle.y > canvas.value!.height) {
      particle.vy *= -1
    }
    
    // 绘制粒子
    ctx.beginPath()
    ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2)
    ctx.fillStyle = particle.color.replace(/[\d.]+\)$/g, `${particle.opacity})`)
    ctx.fill()
    
    // 绘制连线
    particles.slice(index + 1).forEach(otherParticle => {
      const dx = particle.x - otherParticle.x
      const dy = particle.y - otherParticle.y
      const distance = Math.sqrt(dx * dx + dy * dy)
      
      if (distance < 100) {
        ctx.beginPath()
        ctx.moveTo(particle.x, particle.y)
        ctx.lineTo(otherParticle.x, otherParticle.y)
        ctx.strokeStyle = `rgba(102, 126, 234, ${0.1 * (1 - distance / 100)})`
        ctx.lineWidth = 1
        ctx.stroke()
      }
    })
  })
  
  animationId = requestAnimationFrame(updateParticles)
}

const resizeCanvas = () => {
  if (!canvas.value || !container.value) return
  
  const rect = container.value.getBoundingClientRect()
  canvas.value.width = rect.width
  canvas.value.height = rect.height
}

onMounted(() => {
  if (!canvas.value || !container.value) return
  
  resizeCanvas()
  initParticles()
  updateParticles()
  
  window.addEventListener('resize', resizeCanvas)
})

onUnmounted(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  window.removeEventListener('resize', resizeCanvas)
})
</script>

<style scoped>
.particle-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

.particle-canvas {
  width: 100%;
  height: 100%;
}
</style>
