import { useState, useEffect } from 'react';
import WorldMap from './world-map';
import { motion } from 'framer-motion'; 

// Interface for the simplified data passed to WorldMap
interface GeoNode {
  lat: number;
  lng: number;
  label?: string;
  color?: string;
}

// Interface for the raw data structure expected from the gridproxy API
interface RawNode {
    node_id: number;
    location: {
        latitude: string; // API often returns these as strings
        longitude: string; // API often returns these as strings
        city: string;
        country: string;
    };
    // ... other raw fields you don't need
}

const clusterNodes = (nodeList: GeoNode[], cellSize = 2) => {
  const buckets = new Map<
    string,
    { latSum: number; lngSum: number; count: number }
  >();

  nodeList.forEach((node) => {
    const latBucket = Math.round(node.lat / cellSize) * cellSize;
    const lngBucket = Math.round(node.lng / cellSize) * cellSize;
    const key = `${latBucket}|${lngBucket}`;

    const bucket = buckets.get(key);
    if (bucket) {
      bucket.latSum += node.lat;
      bucket.lngSum += node.lng;
      bucket.count += 1;
    } else {
      buckets.set(key, {
        latSum: node.lat,
        lngSum: node.lng,
        count: 1,
      });
    }
  });

  return Array.from(buckets.values()).map((bucket) => {
    const avgLat = bucket.latSum / bucket.count;
    const avgLng = bucket.lngSum / bucket.count;
    const count = bucket.count;

    let color = "#06b6d4";
    if (count > 20) {
      color = "#0891b2";
    } else if (count > 5) {
      color = "#22d3ee";
    }

    return {
      lat: avgLat,
      lng: avgLng,
      color,
      label: `${count} nodes`,
    };
  });
};

function DynamicMapContainer() {
  const [loading, setLoading] = useState(true);
  const [nodes, setNodes] = useState<GeoNode[]>([]);
  const API_URL = "https://gridproxy.grid.tf/nodes?healthy=true&size=99999";

  useEffect(() => {
    async function fetchNodeData() {
      try {
        const response = await fetch(API_URL);
        const data: RawNode[] = await response.json(); // Type the incoming data
        
        // 🚨 Map the API response to your component's expected GeoNode format
        const geoNodes: GeoNode[] = data
          .filter((node: RawNode) => node.location && node.location.latitude && node.location.longitude)
          .map((node: RawNode) => ({
            // Convert string coordinates to numbers
            lat: parseFloat(node.location.latitude), 
            lng: parseFloat(node.location.longitude), 
            label: `${node.location.city}, ${node.location.country} (${node.node_id})`,
            // Optionally set color based on some node property if available
          }));

        const clusteredNodes = clusterNodes(geoNodes);
        setNodes(clusteredNodes);
        setLoading(false);
      } catch (error) {
        console.error("Failed to fetch node data:", error);
        setLoading(false);
      }
    }

    fetchNodeData();
  }, []);

  // --- RENDERING ---
  
  if (loading) {
    // Show a loading state while data is being fetched
    return (
        <div className="flex justify-center items-center w-full aspect-[2/1] bg-[#111111] rounded-lg text-cyan-500">
            <motion.span 
                animate={{ rotate: 360 }} 
                transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
                className="text-4xl"
            >
                🌎
            </motion.span>
            <p className="ml-4">Loading nodes...</p>
        </div>
    );
  }

  // Pass the dynamically fetched nodes to your WorldMap component
  return (
    <WorldMap 
      nodes={nodes} 
    />
  );
}

export default DynamicMapContainer;