import React, { useEffect, useState } from "react";
import { Canvas, useFrame, useThree } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import { getSpiralPosition } from "@/lib/spiral";
import { Vector3 } from "three";


interface StarProps {
  position: [number, number, number];
}

const Star: React.FC<StarProps> = ({ position }) => {
  return (
    <mesh position={position} frustumCulled={true}>
      <sphereGeometry args={[0.5, 16, 16]} />
      <meshStandardMaterial color="#ffd700" />
    </mesh>
  );
};

interface ConstellationProps {
  stars: Vector3[];
  position: [number, number, number];
}

const Constellation: React.FC<ConstellationProps> = ({ stars, position }) => {
  const {camera} = useThree()
  const [flag, setFlag] = useState(false)
  useFrame(({ clock }) => {
    if(camera.position.distanceTo(new Vector3(position[0], position[1], position[2])) > 200){
      setFlag(false)
    }else{
      setFlag(true)
    }
  });
  return (
    <>
    {
      flag &&
      <group position={position} visible={flag}>
        {stars.map((star, index) => (
          <Star key={index} position={star.toArray() as [number, number, number]} />
        ))}
      </group>
    }
    </>
  );
};

const generateRandomStarPositions = (): Vector3[] => {
  const stars: Vector3[] = [];
  for (let i = 0; i < 5; i++) {
    // stars.push(new Vector3(Math.random() * 10 - 5, Math.random() * 10 - 5, Math.random() * 10 - 5));
    stars.push(new Vector3(0, 0, 0));
  }
  return stars;
};

const Visualization: React.FC = () => {
  const [constellations, setConstellations] = useState<
    { position: [number, number, number]; stars: Vector3[] }[]
  >([]);

  const addConstellation = () => {
    setConstellations((prev) => {
      const newConstellations = prev.map((c, index) => ({
        ...c,
        position: getSpiralPosition(index + 1).toArray() as [number, number, number],
      }));

      const newConstellation = {
        position: [0, 0, 0] as [number, number, number],
        stars: generateRandomStarPositions(),
      };

      return [newConstellation, ...newConstellations];
    });
  };

  useEffect(()=>{
    const temp =[]
    for(let i = 0; i< 10; i++){
        const newConstellation = {
            position: getSpiralPosition(i+1).toArray() as [number, number, number],
            stars: generateRandomStarPositions(),
          };
        temp.push(newConstellation)
    }
    setConstellations(temp)
  },[])

  return (
    <>
      <button className="absolute top-4 left-4 text-white border z-10" onClick={addConstellation}>
        Add Constellation
      </button>
      <Canvas className="canvas-wrapper"
       camera={{fov:90, near:0.5, far:150000}}
      >
        <ambientLight intensity={0.5} />
        <pointLight position={[10, 10, 10]} />
        <OrbitControls />
        {constellations.map((constellation, index) => (
          <Constellation
            key={index}
            stars={constellation.stars}
            position={constellation.position}
          />
        ))}
        <axesHelper args={[1500]}/>
      </Canvas>
    </>
  );
};

export default Visualization;
