/**
 * Stars component - renders nearby stars in 3D space
 */
import { useEffect, useState, useMemo } from 'react';
import { Text, Billboard } from '@react-three/drei';
import * as THREE from 'three';

interface Star {
  name: string;
  name_zh: string;
  distance_ly: number;
  ra: number; // Right Ascension in degrees
  dec: number; // Declination in degrees
  magnitude: number;
  color: string;
}

/**
 * Convert RA/Dec to Cartesian coordinates
 * RA: Right Ascension (0-360 degrees)
 * Dec: Declination (-90 to 90 degrees)
 * Distance: fixed distance for celestial sphere
 */
function raDecToCartesian(ra: number, dec: number, distance: number = 150) {
  // Convert to radians
  const raRad = (ra * Math.PI) / 180;
  const decRad = (dec * Math.PI) / 180;

  // Convert to Cartesian coordinates
  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);
}

/**
 * Scale star brightness based on magnitude
 * Lower magnitude = brighter star
 */
function magnitudeToSize(magnitude: number): number {
  // Brighter stars (lower magnitude) should be slightly larger
  // But all stars should be very small compared to planets
  const normalized = Math.max(-2, Math.min(12, magnitude));
  return Math.max(0.15, 0.6 - normalized * 0.04);
}

export function Stars() {
  const [stars, setStars] = useState<Star[]>([]);

  useEffect(() => {
    // Load star data from API
    fetch('http://localhost:8000/api/celestial/static/star')
      .then((res) => {
        if (!res.ok) {
          throw new Error(`HTTP error! status: ${res.status}`);
        }
        return res.json();
      })
      .then((data) => {
        // API returns { category, items: [{ id, name, name_zh, data: {...} }] }
        const starData = data.items.map((item: any) => ({
          name: item.name,
          name_zh: item.name_zh,
          distance_ly: item.data.distance_ly,
          ra: item.data.ra,
          dec: item.data.dec,
          magnitude: item.data.magnitude,
          color: item.data.color,
        }));
        setStars(starData);
      })
      .catch((err) => console.error('Failed to load stars:', err));
  }, []);

  const starData = useMemo(() => {
    return stars.map((star) => {
      // Place all stars on a celestial sphere at fixed distance (150 units)
      // This way they appear as background objects, similar to constellations
      const position = raDecToCartesian(star.ra, star.dec, 150);

      // Size based on brightness (magnitude)
      const size = magnitudeToSize(star.magnitude);

      return {
        ...star,
        position,
        size,
      };
    });
  }, [stars]);

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

  return (
    <group>
      {starData.map((star) => (
        <group key={star.name}>
          {/* Star sphere */}
          <mesh position={star.position}>
            <sphereGeometry args={[star.size, 16, 16]} />
            <meshBasicMaterial
              color={star.color}
              transparent
              opacity={0.9}
              blending={THREE.AdditiveBlending}
            />
          </mesh>

          {/* Star glow */}
          <mesh position={star.position}>
            <sphereGeometry args={[star.size * 2, 16, 16]} />
            <meshBasicMaterial
              color={star.color}
              transparent
              opacity={0.2}
              blending={THREE.AdditiveBlending}
            />
          </mesh>

          {/* Star name label - positioned radially outward from star */}
          <Billboard position={star.position.clone().multiplyScalar(1.05)}>
            <Text
              fontSize={1.2}
              color="#FFFFFF"
              anchorX="center"
              anchorY="middle"
              outlineWidth={0.08}
              outlineColor="#000000"
            >
              {star.name_zh}
            </Text>
          </Billboard>
        </group>
      ))}
    </group>
  );
}
