<template>
  <canvas ref="canvasRef" class="fixed inset-0 w-full h-full z-0 pointer-events-none"></canvas>
</template>

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

const canvasRef = ref<HTMLCanvasElement | null>(null)

// --- 配置参数 ---
const config = {
  starCount: 150,      // 恢复到经典数量，避免过于密集
  meteorChance: 0.003, // 自然流星概率
}

// 类型定义
interface Star {
  x: number
  y: number
  radius: number
  alpha: number
  fadingOut: boolean
  speed: number // 闪烁速度
}

interface Meteor {
  x: number
  y: number
  length: number
  speed: number
  angle: number
  alpha: number
  width: number
}

interface Wave {
  x: number
  y: number
  radius: number
  alpha: number
  lineWidth: number
  hue: number
}

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

// 状态
let ctx: CanvasRenderingContext2D | null = null
let animationFrameId: number
let width = 0
let height = 0

// 对象池
const stars: Star[] = []
const meteors: Meteor[] = []
const waves: Wave[] = []
const particles: Particle[] = []

// 初始化星星 (经典随机分布)
const initStars = () => {
  stars.length = 0
  for (let i = 0; i < config.starCount; i++) {
    stars.push({
      x: Math.random() * width,
      y: Math.random() * height,
      radius: Math.random() * 1.5,
      alpha: Math.random(),
      fadingOut: Math.random() > 0.5,
      speed: Math.random() * 0.02 + 0.005
    })
  }
}

// 渲染循环
const render = () => {
  if (!ctx || !canvasRef.value) return

  // 1. 清空画布
  ctx.clearRect(0, 0, width, height)

  // 2. 绘制星星 (经典呼吸闪烁)
  ctx.fillStyle = '#FFF'
  stars.forEach(star => {
    if (star.fadingOut) {
      star.alpha -= star.speed
      if (star.alpha < 0) {
        star.alpha = 0
        star.fadingOut = false
      }
    } else {
      star.alpha += star.speed
      if (star.alpha > 1) {
        star.alpha = 1
        star.fadingOut = true
      }
    }

    ctx!.globalAlpha = star.alpha
    ctx!.beginPath()
    ctx!.arc(star.x, star.y, star.radius, 0, Math.PI * 2)
    ctx!.fill()
  })
  ctx.globalAlpha = 1

  // 3. 绘制流星
  updateAndDrawMeteors()

  // 4. 绘制波纹 (Shockwave - 随机颜色)
  updateAndDrawWaves()

  // 5. 绘制粒子 (Sparks - 物理效果)
  updateAndDrawParticles()

  animationFrameId = requestAnimationFrame(render)
}

// --- 辅助绘制函数 ---

const updateAndDrawMeteors = () => {
  if (Math.random() < config.meteorChance) createMeteor()

  for (let i = meteors.length - 1; i >= 0; i--) {
    const m = meteors[i]
    if (!ctx) break

    const endX = m.x - m.length * Math.cos(m.angle)
    const endY = m.y - m.length * Math.sin(m.angle)

    // 流星尾巴渐变
    const gradient = ctx.createLinearGradient(m.x, m.y, endX, endY)
    gradient.addColorStop(0, `rgba(255, 255, 255, ${m.alpha})`)
    gradient.addColorStop(1, 'rgba(255, 255, 255, 0)')

    ctx.beginPath()
    ctx.moveTo(m.x, m.y)
    ctx.lineTo(endX, endY)
    ctx.lineWidth = m.width
    ctx.strokeStyle = gradient
    ctx.stroke()

    m.x += m.speed * Math.cos(m.angle)
    m.y += m.speed * Math.sin(m.angle)

    if (m.x > width + 100 || m.y > height + 100) {
      meteors.splice(i, 1)
    }
  }
}

const updateAndDrawWaves = () => {
  for (let i = waves.length - 1; i >= 0; i--) {
    const w = waves[i]
    if (!ctx) break

    ctx.beginPath()
    ctx.arc(w.x, w.y, w.radius, 0, Math.PI * 2)
    // 使用 HSL 随机色
    ctx.strokeStyle = `hsla(${w.hue}, 70%, 60%, ${w.alpha})`
    ctx.lineWidth = w.lineWidth
    ctx.stroke()

    w.radius += 2
    w.alpha -= 0.02
    w.lineWidth *= 0.95

    if (w.alpha <= 0) waves.splice(i, 1)
  }
}

const updateAndDrawParticles = () => {
  for (let i = particles.length - 1; i >= 0; i--) {
    const p = particles[i]
    if (!ctx) break

    ctx.fillStyle = p.color
    ctx.beginPath()
    ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2)
    ctx.fill()

    p.x += p.vx
    p.y += p.vy
    p.vy += 0.05 // 重力
    p.vx *= 0.96
    p.vy *= 0.96

    p.life -= 0.02
    p.size *= 0.96

    if (p.life <= 0) particles.splice(i, 1)
  }
}

const createMeteor = () => {
  const startX = Math.random() * width
  const angle = Math.PI / 4 // 45度
  meteors.push({
    x: startX,
    y: 0,
    length: Math.random() * 80 + 20,
    speed: Math.random() * 10 + 5,
    angle: angle,
    alpha: 1,
    width: Math.random() * 1.5 + 0.5
  })
}

// 交互处理
const handleClick = (e: MouseEvent) => {
  const hue = Math.floor(Math.random() * 360)

  // 1. 波纹
  waves.push({
    x: e.clientX,
    y: e.clientY,
    radius: 0,
    alpha: 1,
    lineWidth: 3,
    hue: hue
  })

  // 2. 粒子
  const particleCount = 10
  for (let i = 0; i < particleCount; i++) {
    const angle = (Math.PI * 2 / particleCount) * i
    const speed = Math.random() * 3 + 1
    particles.push({
      x: e.clientX,
      y: e.clientY,
      vx: Math.cos(angle) * speed,
      vy: Math.sin(angle) * speed,
      life: 1.0,
      color: `hsla(${hue}, 80%, 70%, 1)`, // 粒子跟随波纹颜色
      size: Math.random() * 2 + 1
    })
  }

  // 3. 点击触发流星
  createMeteor()
}

const handleResize = () => {
  if (canvasRef.value) {
    width = window.innerWidth
    height = window.innerHeight
    canvasRef.value.width = width
    canvasRef.value.height = height
    initStars()
  }
}

onMounted(() => {
  if (canvasRef.value) {
    ctx = canvasRef.value.getContext('2d')
    handleResize()

    window.addEventListener('resize', handleResize)
    window.addEventListener('click', handleClick)

    render()
  }
})

onUnmounted(() => {
  cancelAnimationFrame(animationFrameId)
  window.removeEventListener('resize', handleResize)
  window.removeEventListener('click', handleClick)
})
</script>

<style scoped>
canvas {
  display: block;
}
</style>