'use client';

import { useRef, useMemo, useState, useEffect } from 'react';
import { Canvas, useFrame, useThree } from '@react-three/fiber';
import * as THREE from 'three';

const generateParticleData = (count: number) => {
    const positions = new Float32Array(count * 3);
    const particlesData = [];

    for (let i = 0; i < count; i++) {
        const time = Math.random() * 100;
        const factor = 20 + Math.random() * 100;
        const speed = 0.01 + Math.random() / 200;
        const x = (Math.random() - 0.5) * 2000;
        const y = (Math.random() - 0.5) * 2000;
        const z = (Math.random() - 0.5) * 2000;

        positions[i * 3] = x;
        positions[i * 3 + 1] = y;
        positions[i * 3 + 2] = z;

        particlesData.push({ time, factor, speed, x, y, z });
    }

    const geometry = new THREE.BufferGeometry();
    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));

    return { particlesData, geometry };
};

function Particles({ count = 3000 }: { count?: number }) {
    const mesh = useRef<THREE.Points>(null);
    const light = useRef<THREE.PointLight>(null);

    const { particlesData, geometry } = useMemo(() => generateParticleData(count), [count]);

    useFrame(() => {
        if (!mesh.current || !mesh.current.geometry) return;

        const positions = mesh.current.geometry.attributes.position as THREE.BufferAttribute;

        particlesData.forEach((particle, i) => {
            const t = (particle.time += particle.speed);

            positions.setXYZ(
                i,
                particle.x + Math.cos((t / 10) * particle.factor) + (Math.sin(t * 1) * particle.factor) / 10,
                particle.y + Math.sin((t / 10) * particle.factor) + (Math.cos(t * 2) * particle.factor) / 10,
                particle.z + Math.cos((t / 10) * particle.factor) + (Math.sin(t * 3) * particle.factor) / 10
            );
        });

        positions.needsUpdate = true;
        if (mesh.current) {
            mesh.current.rotation.x += 0.0005;
            mesh.current.rotation.y += 0.001;
        }
    });

    return (
        <>
            <pointLight ref={light} distance={1000} intensity={1.5} color="#ffffff" />
            <points ref={mesh} frustumCulled={false} geometry={geometry}>
                <pointsMaterial
                    transparent
                    color="#ffffff"
                    size={2}
                    sizeAttenuation={true}
                    depthWrite={false}
                    opacity={0.7}
                />
            </points>
        </>
    );
}

function MeshGeometry() {
    const meshRef = useRef<THREE.Mesh>(null);
    const meshRef2 = useRef<THREE.Mesh>(null);

    useFrame((state, delta) => {
        if (meshRef.current) {
            meshRef.current.rotation.x += delta * 0.1;
            meshRef.current.rotation.y += delta * 0.15;

            const time = state.clock.getElapsedTime();
            meshRef.current.position.y = Math.sin(time * 0.5) * 0.5;
        }

        if (meshRef2.current) {
            meshRef2.current.rotation.x -= delta * 0.08;
            meshRef2.current.rotation.y -= delta * 0.12;

            const time = state.clock.getElapsedTime();
            meshRef2.current.position.y = Math.cos(time * 0.5) * 0.5;
        }
    });

    return (
        <>
            <mesh ref={meshRef} position={[0, 0, 0]}>
                <icosahedronGeometry args={[2, 1]} />
                <meshStandardMaterial
                    color="#ffffff"
                    wireframe
                    opacity={0.15}
                    transparent
                    emissive="#ffffff"
                    emissiveIntensity={0.1}
                />
            </mesh>
            <mesh ref={meshRef2} position={[0, 0, -5]}>
                <octahedronGeometry args={[1.5, 0]} />
                <meshStandardMaterial
                    color="#ffffff"
                    wireframe
                    opacity={0.1}
                    transparent
                    emissive="#ffffff"
                    emissiveIntensity={0.05}
                />
            </mesh>
        </>
    );
}

function CameraController() {
    const { camera } = useThree();
    const [mousePos, setMousePos] = useState({ x: 0, y: 0 });

    useEffect(() => {
        const handleMouseMove = (e: MouseEvent) => {
            const x = (e.clientX / window.innerWidth) * 2 - 1;
            const y = -(e.clientY / window.innerHeight) * 2 + 1;
            setMousePos({ x, y });
        };

        window.addEventListener('mousemove', handleMouseMove);
        return () => window.removeEventListener('mousemove', handleMouseMove);
    }, []);

    useFrame(() => {
        const targetX = mousePos.x * 2;
        const targetY = mousePos.y * 2;
        camera.position.set(
            camera.position.x + (targetX - camera.position.x) * 0.05,
            camera.position.y + (targetY - camera.position.y) * 0.05,
            camera.position.z
        );
        camera.lookAt(0, 0, 0);
    });

    return null;
}

export default function Scene3D() {
    return (
        <div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', zIndex: 1, pointerEvents: 'none' }}>
            <Canvas
                camera={{ position: [0, 0, 10], fov: 75 }}
                gl={{ alpha: true, antialias: true, powerPreference: 'high-performance' }}
                style={{ background: 'transparent', pointerEvents: 'none' }}
            >
                <CameraController />
                <ambientLight intensity={0.5} />
                <Particles count={3000} />
                <MeshGeometry />
            </Canvas>
        </div>
    );
}

