<script setup>
import * as THREE from 'three'
import { onMounted, onUnmounted, ref } from 'vue'
import { useBreakpoints } from '@vueuse/core'

const canvasRef = ref(null)

// 响应式控制粒子数量
const breakpoints = useBreakpoints({
  mobile: 640,
  tablet: 1024
})

const isMobile = breakpoints.smaller('tablet')
const particleCount = isMobile.value ? 800 : 1500

// 优化粒子配置
const config = {
  particleSize: isMobile.value ? 2.0 : 2.5,
  systemRadius: isMobile.value ? 15 : 20,
  baseSpeed: 0.1,
  hoverRadius: isMobile.value ? 3 : 4,
  color: 0xb4e0f7,  // 主色调：浅蓝色
  colorVariation: [0xffb7d0, 0xa8d8ea, 0xf3e5f5], // 粒子颜色变化
  lineColor: 0xa8d8ea,
  lineDistance: isMobile.value ? 2.5 : 3.5,
  particleCount: isMobile.value ? 800 : 1500,
  particleOpacity: 0.6,
  lineOpacity: 0.15,
  glowSize: 3
}

let scene, camera, renderer, particles, lines, mouse = { x: 0, y: 0 }

const initThreeJS = () => {
  if (!canvasRef.value) return
  
  // 1. 初始化场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x000000)
  scene.fog = new THREE.FogExp2(0x000000, 0.001)

  // 2. 初始化相机
  camera = new THREE.PerspectiveCamera(
    75, 
    window.innerWidth / window.innerHeight, 
    0.1, 
    1000
  )
  camera.position.z = 25

  // 3. 初始化渲染器
  renderer = new THREE.WebGLRenderer({
    canvas: canvasRef.value,
    antialias: true,
    alpha: true,
    powerPreference: 'high-performance'
  })
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  renderer.setSize(window.innerWidth, window.innerHeight)

  // 4. 创建粒子系统
  createParticles()
  
  // 5. 启动动画循环
  animate()
}

const createParticles = () => {
  const geometry = new THREE.BufferGeometry()
  const positions = new Float32Array(config.particleCount * 3)
  const colors = new Float32Array(config.particleCount * 3)
  const sizes = new Float32Array(config.particleCount)
  
  for (let i = 0; i < config.particleCount; i++) {
    const i3 = i * 3
    
    // 使用螺旋分布而不是随机分布
    const radius = (Math.random() * 0.8 + 0.2) * config.systemRadius
    const theta = Math.random() * Math.PI * 2
    const phi = Math.acos(2 * Math.random() - 1)
    const spiral = Math.sin(theta * 3) * 2 // 添加螺旋效果
    
    positions[i3] = radius * Math.sin(phi) * Math.cos(theta) + spiral
    positions[i3 + 1] = radius * Math.sin(phi) * Math.sin(theta) + spiral
    positions[i3 + 2] = radius * Math.cos(phi)
    
    // 随机选择颜色
    const color = new THREE.Color(
      config.colorVariation[Math.floor(Math.random() * config.colorVariation.length)]
    )
    colors[i3] = color.r
    colors[i3 + 1] = color.g
    colors[i3 + 2] = color.b
    
    // 变化的粒子大小
    sizes[i] = config.particleSize * (0.5 + Math.random() * 0.8)
  }
  
  geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
  geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))
  geometry.setAttribute('size', new THREE.BufferAttribute(sizes, 1))
  
  // 使用自定义着色器材质
  const material = new THREE.ShaderMaterial({
    uniforms: {
      time: { value: 0 },
      pixelRatio: { value: window.devicePixelRatio }
    },
    vertexShader: `
      uniform float time;
      attribute float size;
      varying vec3 vColor;
      void main() {
        vColor = color;
        vec3 pos = position;
        // 添加波浪动效
        pos.y += sin(time * 0.5 + position.x * 0.5) * 0.5;
        pos.x += cos(time * 0.3 + position.y * 0.5) * 0.3;
        vec4 mvPosition = modelViewMatrix * vec4(pos, 1.0);
        gl_PointSize = size * (300.0 / -mvPosition.z);
        gl_Position = projectionMatrix * mvPosition;
      }
    `,
    fragmentShader: `
      varying vec3 vColor;
      void main() {
        // 创建柔和的光晕效果
        vec2 center = gl_PointCoord - vec2(0.5);
        float dist = length(center);
        float alpha = 1.0 - smoothstep(0.3, 0.5, dist);
        gl_FragColor = vec4(vColor, alpha * 0.8);
      }
    `,
    transparent: true,
    depthWrite: false,
    blending: THREE.AdditiveBlending,
    vertexColors: true
  })
  
  particles = new THREE.Points(geometry, material)
  scene.add(particles)
  
  // 优化连线效果
  createConnections(positions, colors)
}

const createConnections = (positions, colors) => {
  const lineGeometry = new THREE.BufferGeometry()
  const linePositions = new Float32Array(config.particleCount * 3 * 2) // 每个粒子可能连接多个
  
  // 简化的连接逻辑 (实际项目可以使用更高效的算法)
  let lineIndex = 0
  for (let i = 0; i < config.particleCount; i++) {
    const i3 = i * 3
    const p1 = new THREE.Vector3(
      positions[i3],
      positions[i3 + 1],
      positions[i3 + 2]
    )
    
    // 只检查附近粒子
    for (let j = i + 1; j < Math.min(i + 20, config.particleCount); j++) {
      const j3 = j * 3
      const p2 = new THREE.Vector3(
        positions[j3],
        positions[j3 + 1],
        positions[j3 + 2]
      )
      
      if (p1.distanceTo(p2) < config.lineDistance) {
        linePositions[lineIndex++] = p1.x
        linePositions[lineIndex++] = p1.y
        linePositions[lineIndex++] = p1.z
        linePositions[lineIndex++] = p2.x
        linePositions[lineIndex++] = p2.y
        linePositions[lineIndex++] = p2.z
      }
    }
  }
  
  lineGeometry.setAttribute(
    'position', 
    new THREE.BufferAttribute(linePositions, 3)
  )
  
  const lineMaterial = new THREE.LineBasicMaterial({
    color: config.lineColor,
    transparent: true,
    opacity: config.lineOpacity,
    blending: THREE.AdditiveBlending
  })
  
  lines = new THREE.LineSegments(lineGeometry, lineMaterial)
  scene.add(lines)
}

const animate = () => {
  if (!document.hidden) {
    requestAnimationFrame(animate)
    
    const time = Date.now() * 0.00005
    particles.material.uniforms.time.value = time
    
    // 更新粒子位置
    updateParticles(time)
    
    // 确保渲染器存在且场景已初始化
    if (renderer && scene) {
      renderer.render(scene, camera)
    }
  }
}

const updateParticles = (time) => {
  if (!particles || !particles.geometry) return
  
  const positions = particles.geometry.attributes.position.array
  
  for (let i = 0; i < config.particleCount; i++) {
    const i3 = i * 3
    
    // 优化粒子运动
    positions[i3] += Math.sin(time + i * 0.05) * 0.01
    positions[i3 + 1] += Math.cos(time + i * 0.03) * 0.01
    positions[i3 + 2] += Math.sin(time * 0.3 + i * 0.04) * 0.01
    
    // 鼠标交互
    if (mouse.x !== null && mouse.y !== null) {
      const dx = positions[i3] - mouse.x * 20
      const dy = positions[i3 + 1] - mouse.y * 20
      const distance = Math.sqrt(dx * dx + dy * dy)
      
      if (distance < config.hoverRadius) {
        const force = (config.hoverRadius - distance) / config.hoverRadius * 0.8
        positions[i3] += dx * force * 0.02
        positions[i3 + 1] += dy * force * 0.02
      }
    }
  }
  
  particles.geometry.attributes.position.needsUpdate = true
}

const handleResize = () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
}

const handleMouseMove = (event) => {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
}

// 添加后处理效果
const addPostProcessing = () => {
  const composer = new THREE.EffectComposer(renderer)
  const renderPass = new THREE.RenderPass(scene, camera)
  composer.addPass(renderPass)
  
  const bloomPass = new THREE.UnrealBloomPass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    0.5,  // 强度
    0.4,  // 半径
    0.85  // 阈值
  )
  composer.addPass(bloomPass)
}

// 添加页面可见性处理
const handleVisibilityChange = () => {
  if (document.hidden) {
    if (renderer) {
      renderer.setAnimationLoop(null)
    }
  } else {
    if (renderer) {
      renderer.setAnimationLoop(animate)
    }
  }
}

onMounted(() => {
  initThreeJS()
  window.addEventListener('resize', handleResize)
  window.addEventListener('mousemove', handleMouseMove)
  window.addEventListener('visibilitychange', handleVisibilityChange)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  window.removeEventListener('mousemove', handleMouseMove)
  window.removeEventListener('visibilitychange', handleVisibilityChange)
  if (renderer) {
    renderer.dispose()
    renderer = null
  }
})
</script>

<template>
  <canvas 
    ref="canvasRef" 
    class="particle-canvas"
    aria-hidden="true"
  />
</template>

<style scoped>
.particle-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-index-particle);
  pointer-events: none;
  opacity: 0.7;
  mix-blend-mode: screen;
  transition: opacity 0.3s ease;
}

/* 优化移动端显示 */
@media (max-width: 768px) {
  .particle-canvas {
    opacity: 0.4;
  }
}

/* 暗黑模式适配 */
[data-theme="dark"] .particle-canvas {
  opacity: 0.5;
  mix-blend-mode: multiply;
}
</style>
