<template>
  <div class="star-background">
    <div ref="starContainer" class="star-container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import * as THREE from 'three';
import particleSprite from '../../assets/images/particle-sprite.png';

const starContainer = ref(null);
let scene = null;
let camera = null;
let renderer = null;
let mesh = null;
let animationId = null;
let texture = null;
const fieldRadius = 20;
const fieldZLength = 40;

const initScene = async () => {
  if (!starContainer.value) return;
  
  // 创建场景和相机
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(
    75,
    starContainer.value.clientWidth / starContainer.value.clientHeight,
    0.1,
    1000
  );
  camera.position.z = 5;

  // 创建渲染器
  renderer = new THREE.WebGLRenderer({ 
    antialias: true, 
    alpha: true,
    preserveDrawingBuffer: true // 保留缓冲区以确保正确渲染
  });
  renderer.setSize(
    starContainer.value.clientWidth,
    starContainer.value.clientHeight
  );
  renderer.setPixelRatio(window.devicePixelRatio); // 处理高DPI屏幕
  starContainer.value.appendChild(renderer.domElement);

  // 创建星空几何体
  createStars();
};

const createStars = () => {
  if (!scene) return;
  
  const corner = [];
  const colorMix = [];
  const geoIndex = [];
  const posArr = [];
  const uvArr = [];

  const geo = new THREE.BufferGeometry();

  // 循环生成星星
  for (let i = 0; i < 1000; i++) {
    const [x, y, z] = [
      THREE.MathUtils.mapLinear(Math.random(), 0, 1, -fieldRadius, fieldRadius),
      THREE.MathUtils.mapLinear(Math.random(), 0, 1, -fieldRadius, fieldRadius),
      THREE.MathUtils.mapLinear(Math.random(), 0, 1, -fieldZLength / 2, fieldZLength / 2)
    ];

    const mix = Math.random();
    for (let j = 0; j < 4; j++) {
      posArr.push(x, y, z);
      corner.push(j);
      colorMix.push(mix);
    }

    uvArr.push(0, 1);
    uvArr.push(1, 1);
    uvArr.push(0, 0);
    uvArr.push(1, 0);

    const index = 4 * i;
    geoIndex.push(index, index + 1, index + 2);
    geoIndex.push(index + 1, index + 3, index + 2);
  }

  geo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(posArr), 3));
  geo.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvArr), 2));
  geo.setAttribute('corner', new THREE.BufferAttribute(new Float32Array(corner), 1));
  geo.setAttribute('colorMix', new THREE.BufferAttribute(new Float32Array(colorMix), 1));
  geo.setIndex(geoIndex);
  geo.needsUpdate = true;

  // 顶点着色器
  const vertexShader = `
    attribute float corner;   
    attribute float colorMix;
    uniform float u_time;
    varying vec2 vUv;
    varying vec3 vColor;
     
    uniform float zMin;
    uniform float zMax;
    uniform vec3 color1;
    uniform vec3 color2;
     
    void main() {
        vUv = uv;
        vec3 pos = position;
        pos.z += u_time;
        pos.z = mod(pos.z, zMax - zMin) + zMin; // 修复模运算
        
     
        vec4 worldPos = modelMatrix * vec4(pos, 1.0);
        vec4 viewPosition = viewMatrix * worldPos;

        float offset = 0.1;
     
        if (corner == 0.0) {
            viewPosition.xy += vec2(-offset, -offset);
        }
        if (corner == 1.0) {
            viewPosition.xy += vec2(offset, -offset);
        }
        if (corner == 2.0) {
            viewPosition.xy += vec2(-offset, offset);
        }
        if (corner == 3.0) {
            viewPosition.xy += vec2(offset, offset);
        }
      
        vColor = mix(color1, color2, colorMix);
     
        gl_Position = projectionMatrix * viewPosition;
    }
  `;

  // 片元着色器
  const fragmentShader = `
    varying vec2 vUv;
    varying vec3 vColor;
    uniform sampler2D u_texture;
    void main() {
        vec4 texel = texture2D(u_texture, vUv);
     
        float alpha = texel.r;
      
        vec3 color = mix(vColor, vec3(1.0), texel.r);
      
        gl_FragColor = vec4(color, alpha);
    }
  `;

  // 加载粒子纹理
  const loader = new THREE.TextureLoader();
  const particleTexture = loader.load(particleSprite);

  // 创建材质
  const material = new THREE.ShaderMaterial({
    vertexShader: vertexShader,
    fragmentShader: fragmentShader,
    uniforms: {
      u_texture: {
        value: particleTexture // 使用粒子纹理
      },
      color1: {
        value: new THREE.Color(0x3068FF)
      },
      color2: {
        value: new THREE.Color(0xF34F94)
      },
      zMin: {
        value: -fieldZLength / 2
      },
      zMax: {
        value: fieldZLength / 2 // 修复zMax值
      },
      u_time: {
        value: 0
      },
    },
    transparent: true,
    blending: THREE.AdditiveBlending // 添加混合模式
  });

  // 创建网格
  mesh = new THREE.Mesh(geo, material);
  scene.add(mesh);
};

const animate = () => {
  if (!scene || !camera || !renderer) return;
  
  animationId = requestAnimationFrame(animate);
  
  if (mesh) {
    mesh.material.uniforms.u_time.value += 0.02;
  }
  
  renderer.render(scene, camera);
};

const onResize = () => {
  if (!starContainer.value || !camera || !renderer) return;
  
  camera.aspect = starContainer.value.clientWidth / starContainer.value.clientHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(
    starContainer.value.clientWidth,
    starContainer.value.clientHeight
  );
};

const dispose = () => {
  if (animationId) {
    cancelAnimationFrame(animationId);
  }
  
  // 清理几何体
  if (mesh) {
    if (mesh.geometry) mesh.geometry.dispose();
    if (mesh.material) {
      if (Array.isArray(mesh.material)) {
        mesh.material.forEach(material => material.dispose());
      } else {
        mesh.material.dispose();
      }
    }
    scene.remove(mesh);
  }
  
  // 清理渲染器
  if (renderer) {
    renderer.dispose();
  }
  
  // 清理dom元素
  if (renderer && renderer.domElement && starContainer.value && starContainer.value.contains(renderer.domElement)) {
    starContainer.value.removeChild(renderer.domElement);
  }
};

onMounted(async () => {
  await nextTick(); // 确保DOM已渲染
  initScene();
  animate();
  window.addEventListener('resize', onResize);
});

onUnmounted(() => {
  dispose();
  window.removeEventListener('resize', onResize);
});
</script>

<style scoped>
.star-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.star-container {
  width: 100%;
  height: 100%;
  overflow: hidden; /* 防止出现滚动条 */
}
</style>