<script lang="ts">
	import { onMount, onDestroy } from 'svelte';
	import * as THREE from 'three';

	let container: HTMLDivElement;
	let canvas: HTMLCanvasElement;
	
	// Scene variables
	let scene: THREE.Scene;
	let camera: THREE.PerspectiveCamera;
	let renderer: THREE.WebGLRenderer;
	let particles: THREE.Points;
	let geometry: THREE.BufferGeometry;
	let material: THREE.PointsMaterial;
	
	// Interaction variables
	let mouseX = 0;
	let mouseY = 0;
	let scrollY = 0;
	let targetX = 0;
	let targetY = 0;
	
	const windowHalfX = typeof window !== 'undefined' ? window.innerWidth / 2 : 0;
	const windowHalfY = typeof window !== 'undefined' ? window.innerHeight / 2 : 0;

	onMount(() => {
		init();
		animate();

		window.addEventListener('resize', onWindowResize);
		document.addEventListener('mousemove', onDocumentMouseMove);
		window.addEventListener('scroll', onDocumentScroll);

		return () => {
			window.removeEventListener('resize', onWindowResize);
			document.removeEventListener('mousemove', onDocumentMouseMove);
			window.removeEventListener('scroll', onDocumentScroll);
			
			// Cleanup Three.js resources
			if (renderer) renderer.dispose();
			if (geometry) geometry.dispose();
			if (material) material.dispose();
		};
	});

	function init() {
		// 1. Scene Setup
		scene = new THREE.Scene();
		// Transparent background to blend with CSS gradient
		scene.background = null; 

		// 2. Camera Setup
		camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
		camera.position.z = 1000;

		// 3. Particles Setup
		const particleCount = 2000; // Lots of particles
		geometry = new THREE.BufferGeometry();
		const positions = new Float32Array(particleCount * 3);
		const colors = new Float32Array(particleCount * 3);

		const color1 = new THREE.Color(0x4ade80); // Bright Green
		const color2 = new THREE.Color(0x22c55e); // Darker Green
		const color3 = new THREE.Color(0x0f172a); // Deep Blue/Slate

		for (let i = 0; i < particleCount; i++) {
			// Random positions spread out
			positions[i * 3] = (Math.random() * 2 - 1) * 3000;
			positions[i * 3 + 1] = (Math.random() * 2 - 1) * 3000;
			positions[i * 3 + 2] = (Math.random() * 2 - 1) * 3000;

			// Mixed colors for depth
			const mixedColor = Math.random() > 0.5 ? color1 : (Math.random() > 0.5 ? color2 : color3);
			colors[i * 3] = mixedColor.r;
			colors[i * 3 + 1] = mixedColor.g;
			colors[i * 3 + 2] = mixedColor.b;
		}

		geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
		geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));

		// 4. Material Setup
		// Creating a circular texture for particles using canvas
		const sprite = new THREE.TextureLoader().load('https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/disc.png');

		material = new THREE.PointsMaterial({
			size: 15,
			vertexColors: true,
			map: sprite,
			alphaTest: 0.5,
			transparent: true,
			opacity: 0.8,
			blending: THREE.AdditiveBlending
		});

		particles = new THREE.Points(geometry, material);
		scene.add(particles);

		// 5. Renderer Setup
		renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true });
		renderer.setPixelRatio(window.devicePixelRatio);
		renderer.setSize(window.innerWidth, window.innerHeight);
	}

	function onWindowResize() {
		const width = window.innerWidth;
		const height = window.innerHeight;

		camera.aspect = width / height;
		camera.updateProjectionMatrix();

		renderer.setSize(width, height);
	}

	function onDocumentMouseMove(event: MouseEvent) {
		mouseX = (event.clientX - windowHalfX) * 0.5; // Scale down movement
		mouseY = (event.clientY - windowHalfY) * 0.5;
	}

	function onDocumentScroll() {
		scrollY = window.scrollY;
	}

	function animate() {
		requestAnimationFrame(animate);
		render();
	}

	function render() {
		// Smooth mouse movement
		targetX = mouseX * 0.05;
		targetY = mouseY * 0.05;

		// Gentle rotation based on time + mouse
		particles.rotation.x += 0.0005;
		particles.rotation.y += 0.0005;

		// Interactive movement (Parallax)
		// Move camera based on scroll (fly through effect) and mouse
		camera.position.x += (mouseX - camera.position.x) * 0.02;
		camera.position.y += (-mouseY - camera.position.y) * 0.02;
		
		// Scroll effect: Move deeper into the field or rotate
		camera.position.z = 1000 - (scrollY * 0.5); 
		camera.lookAt(scene.position);

		// Wave effect on particles
		const positions = particles.geometry.attributes.position.array as Float32Array;
		const time = Date.now() * 0.0001;

		renderer.render(scene, camera);
	}
</script>

<div bind:this={container} class="three-container">
	<canvas bind:this={canvas}></canvas>
</div>

<style>
	.three-container {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100vh;
		z-index: 0; /* Behind everything */
		pointer-events: none; /* Let clicks pass through */
		opacity: 0.6; /* Subtle blend */
	}
	
	canvas {
		display: block;
	}
</style>
