import { useEffect, useMemo, useState } from 'react'
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import ThreeGlobe from 'three-globe'
import { Color } from 'three'

type Arc = {
  order: number
  startLat: number; startLng: number
  endLat: number; endLng: number
  arcAlt: number; color: string
}

const COLORS = ['#22ade0', '#3b82f6', '#CD9E53', '#e0529c', '#34d399', '#f59e0b', '#a78bfa', '#ef4444']

/* global steel-trade arcs across many countries, varied colours */
const ARCS: Arc[] = [
  // Tehran hub
  { order: 1, startLat: 35.69, startLng: 51.39,  endLat: 31.23, endLng: 121.47, arcAlt: 0.3, color: COLORS[0] }, // → Shanghai
  { order: 1, startLat: 35.69, startLng: 51.39,  endLat: 33.31, endLng: 44.36,  arcAlt: 0.1, color: COLORS[2] }, // → Baghdad
  { order: 2, startLat: 35.69, startLng: 51.39,  endLat: 51.92, endLng: 4.47,   arcAlt: 0.3, color: COLORS[1] }, // → Rotterdam
  { order: 2, startLat: 35.69, startLng: 51.39,  endLat: 24.71, endLng: 46.68,  arcAlt: 0.15, color: COLORS[3] }, // → Riyadh
  { order: 3, startLat: 25.20, startLng: 55.27,  endLat: 35.69, endLng: 51.39,  arcAlt: 0.2, color: COLORS[2] }, // Dubai →
  { order: 3, startLat: 19.07, startLng: 72.88,  endLat: 35.69, endLng: 51.39,  arcAlt: 0.3, color: COLORS[4] }, // Mumbai →
  { order: 4, startLat: 41.01, startLng: 28.97,  endLat: 35.69, endLng: 51.39,  arcAlt: 0.2, color: COLORS[5] }, // Istanbul →
  { order: 4, startLat: 55.75, startLng: 37.62,  endLat: 35.69, endLng: 51.39,  arcAlt: 0.2, color: COLORS[6] }, // Moscow →
  // Shanghai / East-Asia hub
  { order: 2, startLat: 31.23, startLng: 121.47, endLat: 35.69, endLng: 51.39,  arcAlt: 0.2, color: COLORS[0] }, // → Tehran
  { order: 5, startLat: 37.56, startLng: 126.97, endLat: 31.23, endLng: 121.47, arcAlt: 0.2, color: COLORS[3] }, // Seoul → Shanghai
  { order: 5, startLat: 35.68, startLng: 139.65, endLat: 22.32, endLng: 114.17, arcAlt: 0.2, color: COLORS[7] }, // Tokyo → Hong Kong
  { order: 6, startLat: 1.35,  startLng: 103.82, endLat: 31.23, endLng: 121.47, arcAlt: 0.25, color: COLORS[1] }, // Singapore → Shanghai
  { order: 6, startLat: -6.21, startLng: 106.85, endLat: 35.68, endLng: 139.65, arcAlt: 0.3, color: COLORS[4] }, // Jakarta → Tokyo
  // Europe
  { order: 3, startLat: 51.51, startLng: -0.13,  endLat: 52.52, endLng: 13.40,  arcAlt: 0.1, color: COLORS[6] }, // London → Berlin
  { order: 7, startLat: 51.92, startLng: 4.47,   endLat: 40.71, endLng: -74.0,  arcAlt: 0.35, color: COLORS[2] }, // Rotterdam → New York
  { order: 7, startLat: 52.52, startLng: 13.40,  endLat: 41.01, endLng: 28.97,  arcAlt: 0.2, color: COLORS[5] }, // Berlin → Istanbul
  // Americas
  { order: 8, startLat: -23.55, startLng: -46.63, endLat: 31.23, endLng: 121.47, arcAlt: 0.5, color: COLORS[3] }, // São Paulo → Shanghai
  { order: 8, startLat: 40.71, startLng: -74.0,  endLat: 51.51, endLng: -0.13,  arcAlt: 0.3, color: COLORS[0] }, // New York → London
  { order: 9, startLat: 34.05, startLng: -118.24, endLat: 35.68, endLng: 139.65, arcAlt: 0.4, color: COLORS[7] }, // LA → Tokyo
  { order: 9, startLat: -34.60, startLng: -58.38, endLat: 6.45,  endLng: 3.39,   arcAlt: 0.4, color: COLORS[4] }, // Buenos Aires → Lagos
  { order: 10, startLat: 19.43, startLng: -99.13, endLat: 40.71, endLng: -74.0, arcAlt: 0.2, color: COLORS[1] }, // Mexico City → New York
  // Africa / Middle East
  { order: 10, startLat: 30.04, startLng: 31.24,  endLat: 41.01, endLng: 28.97, arcAlt: 0.15, color: COLORS[5] }, // Cairo → Istanbul
  { order: 11, startLat: 6.45,  startLng: 3.39,   endLat: 51.92, endLng: 4.47,  arcAlt: 0.4, color: COLORS[6] }, // Lagos → Rotterdam
  { order: 11, startLat: -26.20, startLng: 28.04, endLat: 19.07, endLng: 72.88, arcAlt: 0.4, color: COLORS[2] }, // Johannesburg → Mumbai
  { order: 12, startLat: -1.29, startLng: 36.82,  endLat: 25.20, endLng: 55.27, arcAlt: 0.3, color: COLORS[0] }, // Nairobi → Dubai
  // Oceania
  { order: 12, startLat: -33.87, startLng: 151.21, endLat: 31.23, endLng: 121.47, arcAlt: 0.35, color: COLORS[3] }, // Sydney → Shanghai
]

function GlobeObject({ countries }: { countries: { features: object[] } }) {
  const globe = useMemo(() => {
    const g = new ThreeGlobe()
      .hexPolygonsData(countries.features)
      .hexPolygonResolution(3)
      .hexPolygonMargin(0.62)
      .hexPolygonUseDots(true)
      .hexPolygonColor(() => 'rgba(150,200,255,0.95)')
      .showAtmosphere(true)
      .atmosphereColor('#7cc4ff')
      .atmosphereAltitude(0.22)

    g.arcsData(ARCS)
      .arcStartLat((d: object) => (d as Arc).startLat)
      .arcStartLng((d: object) => (d as Arc).startLng)
      .arcEndLat((d: object) => (d as Arc).endLat)
      .arcEndLng((d: object) => (d as Arc).endLng)
      .arcColor((d: object) => (d as Arc).color)
      .arcAltitude((d: object) => (d as Arc).arcAlt)
      .arcStroke(0.5)
      .arcDashLength(0.9)
      .arcDashGap(4)
      .arcDashInitialGap((d: object) => (d as Arc).order)
      .arcDashAnimateTime(1400)

    const points = ARCS.flatMap((a) => [
      { lat: a.startLat, lng: a.startLng, color: a.color },
      { lat: a.endLat, lng: a.endLng, color: a.color },
    ])
    g.pointsData(points)
      .pointColor((d: object) => (d as { color: string }).color)
      .pointAltitude(0)
      .pointRadius(0.55)
      .pointsMerge(true)

    // material → lighter, distinguishable blue sphere
    const mat = g.globeMaterial() as unknown as {
      color: Color; emissive: Color; emissiveIntensity: number; shininess: number
    }
    mat.color = new Color('#1b386e')
    mat.emissive = new Color('#23508f')
    mat.emissiveIntensity = 0.45
    mat.shininess = 0.6

    return g
  }, [countries])

  return <primitive object={globe} />
}

export function World() {
  const [countries, setCountries] = useState<{ features: object[] } | null>(null)

  useEffect(() => {
    let alive = true
    fetch('/globe-countries.geojson')
      .then((r) => r.json())
      .then((geo) => { if (alive) setCountries(geo) })
      .catch(() => {})
    return () => { alive = false }
  }, [])

  return (
    <Canvas camera={{ fov: 50, near: 180, far: 1800, position: [0, 0, 320] }} gl={{ alpha: true, antialias: true }}>
      <ambientLight color="#dce9ff" intensity={1.6} />
      <directionalLight color="#ffffff" position={[-400, 200, 400]} intensity={1.6} />
      <directionalLight color="#6cc4ff" position={[300, 200, 200]} intensity={1} />
      <pointLight color="#ffffff" position={[-200, 500, 200]} intensity={1.1} />
      {countries && <GlobeObject countries={countries} />}
      <OrbitControls
        enablePan={false}
        enableZoom={false}
        minDistance={320}
        maxDistance={320}
        autoRotate
        autoRotateSpeed={0.6}
        minPolarAngle={Math.PI / 3.5}
        maxPolarAngle={Math.PI - Math.PI / 3}
      />
    </Canvas>
  )
}

/* default wrapper sized to fit the section */
export default function Globe({ size = 600 }: { size?: number }) {
  return (
    <div style={{ width: '100%', maxWidth: size, aspectRatio: '1', margin: '0 auto', position: 'relative' }}>
      <World />
    </div>
  )
}
