'use client'

import { useRef, useMemo } from 'react'
import { useFrame } from '@react-three/fiber'
import { Mesh, Vector3 } from 'three'
import * as THREE from 'three'

interface Node {
  id: string
  name: string
  position: [number, number, number]
  health: number
  type: 'region' | 'cluster' | 'service'
}

interface Edge {
  from: string
  to: string
  latency?: number
  bandwidth?: number
}

interface NetworkTopologyProps {
  nodes?: Node[]
  edges?: Edge[]
}

export default function NetworkTopology({ 
  nodes = defaultNodes, 
  edges = defaultEdges 
}: NetworkTopologyProps) {
  const nodeRefs = useRef<{ [key: string]: Mesh }>({})

  useFrame((state) => {
    // Animate nodes
    Object.values(nodeRefs.current).forEach((node, index) => {
      if (node) {
        node.rotation.y += 0.005
        const time = state.clock.elapsedTime
        node.position.y = nodes[index]?.position[1] + Math.sin(time + index) * 0.1
      }
    })
  })

  const nodePositions = useMemo(() => {
    return nodes.map((node) => new Vector3(...node.position))
  }, [nodes])

  const getNodeColor = (health: number, type: string) => {
    if (health >= 90) return '#00FF88'
    if (health >= 70) return '#FFB800'
    if (health >= 50) return '#FF8C00'
    return '#FF0040'
  }

  const getNodeSize = (type: string) => {
    switch (type) {
      case 'region': return 0.3
      case 'cluster': return 0.2
      case 'service': return 0.15
      default: return 0.2
    }
  }

  return (
    <group>
      {/* Render edges/connections */}
      {edges.map((edge, index) => {
        const fromNode = nodes.find((n) => n.id === edge.from)
        const toNode = nodes.find((n) => n.id === edge.to)
        
        if (!fromNode || !toNode) return null

        const from = new Vector3(...fromNode.position)
        const to = new Vector3(...toNode.position)

        return (
          <line key={`edge-${index}`}>
            <bufferGeometry>
              <bufferAttribute
                attach="attributes-position"
                count={2}
                array={new Float32Array([
                  from.x, from.y, from.z,
                  to.x, to.y, to.z,
                ])}
                itemSize={3}
              />
            </bufferGeometry>
            <lineBasicMaterial color="#00FFD1" opacity={0.3} transparent />
          </line>
        )
      })}

      {/* Render nodes */}
      {nodes.map((node, index) => (
        <mesh
          key={node.id}
          ref={(ref) => {
            if (ref) nodeRefs.current[node.id] = ref
          }}
          position={node.position}
        >
          <sphereGeometry args={[getNodeSize(node.type), 16, 16]} />
          <meshStandardMaterial
            color={getNodeColor(node.health, node.type)}
            emissive={getNodeColor(node.health, node.type)}
            emissiveIntensity={0.3}
            metalness={0.4}
            roughness={0.3}
          />
        </mesh>
      ))}
    </group>
  )
}

// Default data for demonstration
const defaultNodes: Node[] = [
  { id: '1', name: 'Region 1', position: [-2, 0, 0], health: 95, type: 'region' },
  { id: '2', name: 'Region 2', position: [2, 0, 0], health: 88, type: 'region' },
  { id: '3', name: 'Cluster 1', position: [-1, 1, 0], health: 92, type: 'cluster' },
  { id: '4', name: 'Cluster 2', position: [1, 1, 0], health: 85, type: 'cluster' },
  { id: '5', name: 'Service 1', position: [-1.5, -1, 0], health: 90, type: 'service' },
  { id: '6', name: 'Service 2', position: [1.5, -1, 0], health: 75, type: 'service' },
]

const defaultEdges: Edge[] = [
  { from: '1', to: '2' },
  { from: '1', to: '3' },
  { from: '2', to: '4' },
  { from: '3', to: '5' },
  { from: '4', to: '6' },
]

