// Globe — rotating wireframe sphere with transmission arcs (canvas 2D, no deps)
function Globe() {
  const canvasRef = React.useRef(null);

  React.useEffect(() => {
    const cvs = canvasRef.current;
    if (!cvs) return;
    const ctx = cvs.getContext('2d');
    if (!ctx) return;

    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

    let raf = 0;
    let rot = -1.4;          // initial rotation so HTX sits roughly facing the camera
    const tilt = 0.32;       // axial tilt (radians)
    const sinT = Math.sin(tilt), cosT = Math.cos(tilt);

    const cities = [
      { name: 'HTX',  lat:  29.76, lon:  -95.37, primary: true },
      { name: 'BLN',  lat:  52.52, lon:   13.40 },
      { name: 'TYO',  lat:  35.68, lon:  139.65 },
      { name: 'CDMX', lat:  19.43, lon:  -99.13 },
      { name: 'LDN',  lat:  51.51, lon:   -0.13 },
      { name: 'DTW',  lat:  42.33, lon:  -83.05 },
      { name: 'BUE',  lat: -34.60, lon:  -58.38 },
      { name: 'JNB',  lat: -26.20, lon:   28.04 },
    ];

    let dpr = Math.min(window.devicePixelRatio || 1, 2);
    let w = 0, h = 0;

    function resize() {
      dpr = Math.min(window.devicePixelRatio || 1, 2);
      const rect = cvs.getBoundingClientRect();
      w = Math.max(1, Math.floor(rect.width));
      h = Math.max(1, Math.floor(rect.height));
      cvs.width = w * dpr;
      cvs.height = h * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    resize();

    const ro = ('ResizeObserver' in window) ? new ResizeObserver(resize) : null;
    if (ro) ro.observe(cvs);
    else window.addEventListener('resize', resize);

    function readVar(name, fallback) {
      const v = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
      return v || fallback;
    }

    // (lat, lon) → 3D point on sphere of radius r, rotated around Y by `rotation`
    // and tilted around X by `tilt`. Returns { x, y, z } in screen-aligned coords
    // (z > 0 = toward camera).
    function project(lat, lon, r, rotation) {
      const phi = lat * Math.PI / 180;
      const lam = lon * Math.PI / 180 + rotation;
      const cp = Math.cos(phi);
      const x = r * cp * Math.sin(lam);
      const yy = r * Math.sin(phi);
      const zz = r * cp * Math.cos(lam);
      // Tilt: rotate around X axis
      const y = yy * cosT - zz * sinT;
      const z = yy * sinT + zz * cosT;
      return { x, y, z };
    }

    function drawGreatCircleArc(a, b, r, cx, cy, rotation, progress, tail, color) {
      const segments = 64;
      ctx.strokeStyle = color;
      ctx.lineWidth = 1.4;
      ctx.lineCap = 'round';

      let started = false;
      ctx.beginPath();
      for (let s = 0; s <= segments; s++) {
        const f = s / segments;
        if (f > progress) break;
        if (f < progress - tail) continue;

        const lat = a.lat + (b.lat - a.lat) * f;
        const lon = a.lon + (b.lon - a.lon) * f;
        const lift = Math.sin(f * Math.PI) * r * 0.28;
        const p = project(lat, lon, r + lift, rotation);

        if (p.z > -r * 0.05) {
          const sx = cx + p.x;
          const sy = cy - p.y;
          if (!started) { ctx.moveTo(sx, sy); started = true; }
          else ctx.lineTo(sx, sy);
        } else if (started) {
          ctx.stroke();
          ctx.beginPath();
          started = false;
        }
      }
      if (started) ctx.stroke();

      // Leading bright dot
      const lat = a.lat + (b.lat - a.lat) * progress;
      const lon = a.lon + (b.lon - a.lon) * progress;
      const lift = Math.sin(progress * Math.PI) * r * 0.28;
      const head = project(lat, lon, r + lift, rotation);
      if (head.z > 0) {
        const sx = cx + head.x, sy = cy - head.y;
        ctx.fillStyle = color;
        ctx.beginPath(); ctx.arc(sx, sy, 2.4, 0, Math.PI * 2); ctx.fill();
      }
    }

    let last = performance.now();
    function frame(now) {
      const dt = Math.min(64, now - last);
      last = now;

      const cx = w / 2;
      const cy = h / 2;
      const r = Math.min(w, h) * 0.42;

      if (!reduced) rot += dt * 0.00012;

      ctx.clearRect(0, 0, w, h);

      const accent = readVar('--accent', '#ff7a18');
      const ink = readVar('--ink', '#f4f1ea');
      const inkLine = readVar('--ink-line', 'rgba(244,241,234,0.18)');

      // Outer ring + inner ring (HUD reticle)
      ctx.lineWidth = 1;
      ctx.strokeStyle = inkLine;
      ctx.beginPath(); ctx.arc(cx, cy, r * 1.06, 0, Math.PI * 2); ctx.stroke();
      ctx.beginPath(); ctx.arc(cx, cy, r * 1.18, 0, Math.PI * 2); ctx.stroke();

      // Tick marks around outer ring
      ctx.strokeStyle = inkLine;
      for (let a = 0; a < 360; a += 6) {
        const big = a % 30 === 0;
        const len = big ? 8 : 4;
        const ang = a * Math.PI / 180;
        const r1 = r * 1.18;
        const r2 = r1 + len;
        ctx.beginPath();
        ctx.moveTo(cx + Math.cos(ang) * r1, cy + Math.sin(ang) * r1);
        ctx.lineTo(cx + Math.cos(ang) * r2, cy + Math.sin(ang) * r2);
        ctx.stroke();
      }

      // Latitude lines
      for (let lat = -75; lat <= 75; lat += 15) {
        ctx.beginPath();
        let started = false;
        let lastAlpha = 0;
        for (let lon = -180; lon <= 180; lon += 4) {
          const p = project(lat, lon, r, rot);
          const alpha = Math.max(0, p.z / r);
          if (alpha > 0.02) {
            const sx = cx + p.x, sy = cy - p.y;
            if (!started) { ctx.moveTo(sx, sy); started = true; }
            else ctx.lineTo(sx, sy);
            lastAlpha = Math.max(lastAlpha, alpha);
          } else if (started) {
            ctx.globalAlpha = 0.18 + lastAlpha * 0.5;
            ctx.strokeStyle = ink;
            ctx.lineWidth = 0.7;
            ctx.stroke();
            ctx.beginPath(); started = false; lastAlpha = 0;
          }
        }
        if (started) {
          ctx.globalAlpha = 0.18 + lastAlpha * 0.5;
          ctx.strokeStyle = ink;
          ctx.lineWidth = 0.7;
          ctx.stroke();
        }
        ctx.globalAlpha = 1;
      }

      // Longitude lines
      for (let lon = -180; lon < 180; lon += 15) {
        ctx.beginPath();
        let started = false;
        let lastAlpha = 0;
        for (let lat = -90; lat <= 90; lat += 4) {
          const p = project(lat, lon, r, rot);
          const alpha = Math.max(0, p.z / r);
          if (alpha > 0.02) {
            const sx = cx + p.x, sy = cy - p.y;
            if (!started) { ctx.moveTo(sx, sy); started = true; }
            else ctx.lineTo(sx, sy);
            lastAlpha = Math.max(lastAlpha, alpha);
          } else if (started) {
            ctx.globalAlpha = 0.18 + lastAlpha * 0.5;
            ctx.strokeStyle = ink;
            ctx.lineWidth = 0.7;
            ctx.stroke();
            ctx.beginPath(); started = false; lastAlpha = 0;
          }
        }
        if (started) {
          ctx.globalAlpha = 0.18 + lastAlpha * 0.5;
          ctx.strokeStyle = ink;
          ctx.lineWidth = 0.7;
          ctx.stroke();
        }
        ctx.globalAlpha = 1;
      }

      // Sphere terminator (great circle facing camera) — accent halo
      ctx.strokeStyle = accent;
      ctx.globalAlpha = 0.22;
      ctx.lineWidth = 1.2;
      ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI * 2); ctx.stroke();
      ctx.globalAlpha = 1;

      // City markers
      const houston = cities[0];
      cities.forEach((c) => {
        const p = project(c.lat, c.lon, r * 1.005, rot);
        if (p.z <= 0) return;
        const sx = cx + p.x, sy = cy - p.y;
        const size = c.primary ? 3.2 : 2;
        ctx.fillStyle = accent;
        ctx.globalAlpha = 0.55 + 0.45 * (p.z / r);
        ctx.beginPath(); ctx.arc(sx, sy, size, 0, Math.PI * 2); ctx.fill();
        ctx.globalAlpha = 1;

        if (c.primary) {
          // Pulsing reticle on Houston
          const pulse = (Math.sin(now * 0.0028) + 1) * 0.5;
          ctx.strokeStyle = accent;
          ctx.globalAlpha = 0.45 - pulse * 0.32;
          ctx.lineWidth = 1.2;
          ctx.beginPath();
          ctx.arc(sx, sy, 4 + pulse * 22, 0, Math.PI * 2);
          ctx.stroke();
          ctx.globalAlpha = 1;
        }
      });

      // Transmission arcs from Houston, staggered
      const targets = cities.slice(1);
      const cycle = 5200;
      targets.forEach((dest, i) => {
        const stagger = (i / targets.length) * cycle;
        const t = ((now + stagger) % cycle) / cycle;
        if (t < 0.85) {
          const progress = t / 0.85;
          drawGreatCircleArc(houston, dest, r, cx, cy, rot, progress, 0.45, accent);
        }
      });

      // Crosshair at center (subtle HUD)
      ctx.strokeStyle = inkLine;
      ctx.lineWidth = 0.7;
      ctx.beginPath();
      ctx.moveTo(cx - r * 1.32, cy); ctx.lineTo(cx - r * 1.22, cy);
      ctx.moveTo(cx + r * 1.22, cy); ctx.lineTo(cx + r * 1.32, cy);
      ctx.moveTo(cx, cy - r * 1.32); ctx.lineTo(cx, cy - r * 1.22);
      ctx.moveTo(cx, cy + r * 1.22); ctx.lineTo(cx, cy + r * 1.32);
      ctx.stroke();

      raf = requestAnimationFrame(frame);
    }

    raf = requestAnimationFrame(frame);

    function onVisibility() {
      if (document.hidden) {
        cancelAnimationFrame(raf);
        raf = 0;
      } else if (!raf) {
        last = performance.now();
        raf = requestAnimationFrame(frame);
      }
    }
    document.addEventListener('visibilitychange', onVisibility);

    return () => {
      cancelAnimationFrame(raf);
      document.removeEventListener('visibilitychange', onVisibility);
      if (ro) ro.disconnect();
      else window.removeEventListener('resize', resize);
    };
  }, []);

  return (
    <div className="globe-wrap" aria-hidden="true">
      <canvas ref={canvasRef} className="globe-canvas" />
      <div className="globe-scanlines" />
      <div className="globe-vignette" />
    </div>
  );
}

window.Globe = Globe;
