"use client";

import { useMemo, useRef } from "react";
import { Canvas, useFrame, useThree } from "@react-three/fiber";
import { MeshDistortMaterial, Sphere, Preload, Float } from "@react-three/drei";
import { EffectComposer, Bloom, Vignette } from "@react-three/postprocessing";
import * as THREE from "three";

// --- CONFIGURATION ---
const NEURON_COUNT = 15; // Keep low for high-quality geometry
const CONNECTION_DISTANCE = 6.5; 
const PULSE_SPEED = 1.8;

// 1. REALISTIC CELL (Soma + Nucleus)
function NeuronCell({ position }: { position: [number, number, number] }) {
  const membraneRef = useRef<THREE.Mesh>(null!);
  const nucleusRef = useRef<THREE.Mesh>(null!);

  // Randomize biology
  const size = useMemo(() => 0.5 + Math.random() * 0.3, []);
  
  useFrame((state) => {
    const t = state.clock.getElapsedTime();
    
    // Biological breathing/pulsing
    if (membraneRef.current) {
      const scale = size + Math.sin(t * 2 + position[0]) * 0.05;
      membraneRef.current.scale.setScalar(scale);
    }
    
    // Nucleus gentle pulse (faster)
    if (nucleusRef.current) {
      const nScale = (size * 0.4) + Math.sin(t * 4) * 0.02;
      nucleusRef.current.scale.setScalar(nScale);
    }
  });

  return (
    <Float speed={1.5} rotationIntensity={0.6} floatIntensity={0.8}>
      <group position={position}>
        
        {/* A. The Membrane (Outer Shell) */}
        <Sphere ref={membraneRef} args={[1, 64, 64]}>
          <MeshDistortMaterial
            color="#083344" // Deep blue-black (organic tissue)
            emissive="#155e75" // Cyan glow from within
            emissiveIntensity={0.2}
            roughness={0.1}
            metalness={0.8}
            distort={0.5} // High distortion for "blobby" look
            speed={2}
            transparent
            opacity={0.7}
          />
        </Sphere>

        {/* B. The Nucleus (Inner Core) */}
        <Sphere ref={nucleusRef} args={[1, 32, 32]}>
          <meshStandardMaterial
            color="#a5f3fc" // Bright Cyan
            emissive="#22d3ee" // Strong Glow
            emissiveIntensity={2} // Push this high for Bloom to pick it up
            toneMapped={false}
          />
          <pointLight distance={4} intensity={2} color="#22d3ee" decay={2} />
        </Sphere>

      </group>
    </Float>
  );
}

// 2. SYNAPSE (Axon + Electric Pulse)
function Synapse({ start, end }: { start: THREE.Vector3; end: THREE.Vector3 }) {
  const curve = useMemo(() => {
    // Create organic curve
    const mid = new THREE.Vector3().lerpVectors(start, end, 0.5);
    // Randomize control point for "tendon" shape
    mid.add(new THREE.Vector3(
      (Math.random() - 0.5) * 3,
      (Math.random() - 0.5) * 3,
      (Math.random() - 0.5) * 3
    ));
    return new THREE.QuadraticBezierCurve3(start, mid, end);
  }, [start, end]);

  const points = useMemo(() => curve.getPoints(30), [curve]);
  const impulseRef = useRef<THREE.Mesh>(null!);

  useFrame((state) => {
    // Move electric pulse
    const t = (state.clock.getElapsedTime() * PULSE_SPEED) % 1; 
    if (impulseRef.current) {
      const pos = curve.getPointAt(t);
      impulseRef.current.position.copy(pos);
      
      // Stretch effect for speed illusion
      const tangent = curve.getTangent(t).normalize();
      impulseRef.current.lookAt(pos.clone().add(tangent));
      impulseRef.current.scale.set(0.6, 0.6, 2.5); // Stretch Z
    }
  });

  return (
    <group>
      {/* The physical connection (Axon) */}
      <line>
        <bufferGeometry>
          <bufferAttribute
            attach="attributes-position"
            count={points.length}
            array={new Float32Array(points.flatMap(p => [p.x, p.y, p.z]))}
            itemSize={3}
          />
        </bufferGeometry>
        <lineBasicMaterial color="#0e7490" transparent opacity={0.15} />
      </line>

      {/* The Traveling Spark (Electricity) */}
      <mesh ref={impulseRef}>
        <sphereGeometry args={[0.08, 8, 8]} />
        <meshBasicMaterial color="#ccfbf1" />
        <pointLight distance={3} intensity={3} color="#22d3ee" decay={2} />
      </mesh>
    </group>
  );
}

// 3. BACKGROUND PARTICLES (Neurotransmitters)
function NeuroDust() {
  const count = 200;
  const mesh = useRef<THREE.InstancedMesh>(null!);
  
  const particles = useMemo(() => {
    const temp = [];
    for(let i=0; i<count; i++) {
      const t = Math.random() * 100;
      const factor = 20 + Math.random() * 10;
      const speed = 0.01 + Math.random() / 200;
      const x = (Math.random() - 0.5) * 30;
      const y = (Math.random() - 0.5) * 30;
      const z = (Math.random() - 0.5) * 15;
      temp.push({ t, factor, speed, x, y, z, mx: 0, my: 0 });
    }
    return temp;
  }, []);

  const dummy = useMemo(() => new THREE.Object3D(), []);

  useFrame((state) => {
    particles.forEach((particle, i) => {
      let { t, factor, speed, x, y, z } = particle;
      t = particle.t += speed / 2;
      const a = Math.cos(t) + Math.sin(t * 1) / 10;
      const b = Math.sin(t) + Math.cos(t * 2) / 10;
      const s = Math.cos(t);
      
      dummy.position.set(
        x + Math.cos(t) + Math.sin(t) * 2,
        y + Math.sin(t) + Math.cos(t) * 2,
        z + Math.cos(t)
      );
      dummy.scale.setScalar(s * 0.03); // Tiny dust
      dummy.rotation.set(s * 5, s * 5, s * 5);
      dummy.updateMatrix();
      
      if (mesh.current) mesh.current.setMatrixAt(i, dummy.matrix);
    });
    if (mesh.current) mesh.current.instanceMatrix.needsUpdate = true;
  });

  return (
    <instancedMesh ref={mesh} args={[undefined, undefined, count]}>
      <dodecahedronGeometry args={[0.2, 0]} />
      <meshPhongMaterial color="#0891b2" emissive="#06b6d4" transparent opacity={0.4} />
    </instancedMesh>
  );
}

// 4. MAIN SCENE
function Scene() {
  const { viewport } = useThree();
  
  // Generate random positions for neurons
  const neurons = useMemo(() => {
    const temp = [];
    for (let i = 0; i < NEURON_COUNT; i++) {
      temp.push({
        position: new THREE.Vector3(
          (Math.random() - 0.5) * 22,
          (Math.random() - 0.5) * 22,
          (Math.random() - 0.5) * 10
        ),
        id: i
      });
    }
    return temp;
  }, []);

  // Connect them
  const connections = useMemo(() => {
    const conns = [];
    for(let i=0; i<neurons.length; i++) {
      for(let j=i+1; j<neurons.length; j++) {
        if(neurons[i].position.distanceTo(neurons[j].position) < CONNECTION_DISTANCE) {
          conns.push({ start: neurons[i].position, end: neurons[j].position, key: `${i}-${j}` });
        }
      }
    }
    return conns;
  }, [neurons]);

  useFrame((state) => {
    // Subtle Camera Parallax based on Mouse
    const x = (state.pointer.x * viewport.width) / 12;
    const y = (state.pointer.y * viewport.height) / 12;
    state.camera.position.x = THREE.MathUtils.lerp(state.camera.position.x, x, 0.02);
    state.camera.position.y = THREE.MathUtils.lerp(state.camera.position.y, y, 0.02);
    state.camera.lookAt(0,0,0);
  });

  return (
    <>
      <color attach="background" args={["#020617"]} /> {/* Match gray-950 */}
      <ambientLight intensity={0.2} />
      <pointLight position={[10, 10, 10]} intensity={1} color="#22d3ee" />
      
      {neurons.map(n => <NeuronCell key={n.id} position={[n.position.x, n.position.y, n.position.z]} />)}
      {connections.map(c => <Synapse key={c.key} start={c.start} end={c.end} />)}
      <NeuroDust />

      {/* POST PROCESSING - The Secret Sauce for Realism */}
      <EffectComposer disableNormalPass>
        <Bloom 
          luminanceThreshold={1} // Only very bright things glow
          mipmapBlur 
          intensity={1.5} // Strength of the glow
          radius={0.6}
        />
        <Vignette eskil={false} offset={0.1} darkness={1.1} />
      </EffectComposer>
    </>
  );
}

export default function RealisticNeurons() {
  return (
    <div className="absolute inset-0 z-0 h-full w-full">
      <Canvas
        camera={{ position: [0, 0, 16], fov: 40 }}
        gl={{ alpha: false, antialias: false, toneMapping: THREE.ReinhardToneMapping }}
        dpr={[1, 1.5]} // Limit DPR for performance with post-processing
      >
        <Scene />
        <Preload all />
      </Canvas>
    </div>
  );
}