/**
 * Constellations component - renders major constellations with connecting lines
 */
import { useEffect, useState, useMemo } from 'react';
import { Line, Text, Billboard } from '@react-three/drei';
import * as THREE from 'three';

interface ConstellationStar {
  name: string;
  ra: number; // Right Ascension in degrees
  dec: number; // Declination in degrees
}

interface Constellation {
  name: string;
  name_zh: string;
  stars: ConstellationStar[];
  lines: [number, number][]; // Indices of stars to connect
}

/**
 * Convert RA/Dec to Cartesian coordinates
 * Use fixed distance for constellation stars to create celestial sphere effect
 */
function raDecToCartesian(ra: number, dec: number, distance: number = 100) {
  const raRad = (ra * Math.PI) / 180;
  const decRad = (dec * Math.PI) / 180;

  const x = distance * Math.cos(decRad) * Math.cos(raRad);
  const y = distance * Math.cos(decRad) * Math.sin(raRad);
  const z = distance * Math.sin(decRad);

  return new THREE.Vector3(x, y, z);
}

export function Constellations() {
  const [constellations, setConstellations] = useState<Constellation[]>([]);

  useEffect(() => {
    // Load constellation data
    fetch('/data/constellations.json')
      .then((res) => res.json())
      .then((data) => setConstellations(data))
      .catch((err) => console.error('Failed to load constellations:', err));
  }, []);

  const constellationLines = useMemo(() => {
    return constellations.map((constellation) => {
      // Convert all stars to 3D positions
      const starPositions = constellation.stars.map((star) =>
        raDecToCartesian(star.ra, star.dec)
      );

      // Create line segments based on connection indices
      const lineSegments = constellation.lines.map(([startIdx, endIdx]) => ({
        start: starPositions[startIdx],
        end: starPositions[endIdx],
      }));

      // Calculate center position for label (average of all stars)
      const center = starPositions.reduce(
        (acc, pos) => acc.add(pos),
        new THREE.Vector3()
      ).divideScalar(starPositions.length);

      return {
        name: constellation.name,
        nameZh: constellation.name_zh,
        starPositions,
        lineSegments,
        center,
      };
    });
  }, [constellations]);

  if (constellationLines.length === 0) {
    return null;
  }

  return (
    <group>
      {constellationLines.map((constellation) => (
        <group key={constellation.name}>
          {/* Render constellation stars */}
          {constellation.starPositions.map((pos, idx) => (
            <mesh key={`${constellation.name}-star-${idx}`} position={pos}>
              <sphereGeometry args={[0.3, 8, 8]} />
              <meshBasicMaterial color="#FFFFFF" transparent opacity={0.8} />
            </mesh>
          ))}

          {/* Render connecting lines */}
          {constellation.lineSegments.map((segment, idx) => (
            <Line
              key={`${constellation.name}-line-${idx}`}
              points={[segment.start, segment.end]}
              color="#4488FF"
              lineWidth={1}
              transparent
              opacity={0.5}
            />
          ))}

          {/* Constellation name label */}
          <Billboard position={constellation.center}>
            <Text
              fontSize={2}
              color="#88AAFF"
              anchorX="center"
              anchorY="middle"
              outlineWidth={0.1}
              outlineColor="#000000"
            >
              {constellation.nameZh}
            </Text>
          </Billboard>
        </group>
      ))}
    </group>
  );
}
