import { useMemo, useRef } from "react";
import { useFrame } from "@react-three/fiber";
import * as THREE from "three";

type SpaceEnvironmentProps = {
  density?: number;
  spread?: number;
  fog?: boolean;
  accents?: [string, string, string?];
};

export function SpaceEnvironment({
  density = 1800,
  spread = 900,
  fog = true,
  accents = ["#22d3ee", "#a78bfa", "#f0a030"],
}: SpaceEnvironmentProps) {
  const pointsRef = useRef<THREE.Points>(null);
  const positions = useMemo(() => {
    const array = new Float32Array(density * 3);
    for (let i = 0; i < density; i += 1) {
      array[i * 3] = (Math.random() - 0.5) * spread;
      array[i * 3 + 1] = (Math.random() - 0.5) * spread;
      array[i * 3 + 2] = (Math.random() - 0.5) * spread;
    }
    return array;
  }, [density, spread]);

  useFrame((_, dt) => {
    if (pointsRef.current) {
      pointsRef.current.rotation.y += dt * 0.01;
      pointsRef.current.rotation.x += dt * 0.003;
    }
  });

  return (
    <>
      {fog && <fogExp2 attach="fog" args={["#040810", 0.001]} />}
      <color attach="background" args={["#040810"]} />
      <ambientLight intensity={0.35} />
      <directionalLight position={[40, 60, 30]} intensity={1.6} color="#dbeafe" />
      <pointLight position={[-30, 20, -60]} intensity={1.4} color={accents[0]} />
      <pointLight position={[50, -10, -80]} intensity={1.0} color={accents[1]} />
      <points ref={pointsRef}>
        <bufferGeometry>
          <bufferAttribute attach="attributes-position" args={[positions, 3]} />
        </bufferGeometry>
        <pointsMaterial size={1.25} color="#dbeafe" transparent opacity={0.75} sizeAttenuation />
      </points>
      <mesh position={[-80, 25, -180]} scale={[95, 45, 95]}>
        <sphereGeometry args={[1, 24, 24]} />
        <meshBasicMaterial color={accents[0]} transparent opacity={0.045} side={THREE.BackSide} depthWrite={false} />
      </mesh>
      <mesh position={[90, -20, -140]} scale={[70, 36, 70]}>
        <sphereGeometry args={[1, 24, 24]} />
        <meshBasicMaterial color={accents[1]} transparent opacity={0.035} side={THREE.BackSide} depthWrite={false} />
      </mesh>
      {accents[2] && (
        <mesh position={[0, 50, -220]} scale={[80, 40, 80]}>
          <sphereGeometry args={[1, 24, 24]} />
          <meshBasicMaterial color={accents[2]} transparent opacity={0.025} side={THREE.BackSide} depthWrite={false} />
        </mesh>
      )}
    </>
  );
}
