/* global React, d3, topojson */
/* Real-country-outline globe for the Overture scene.
   Uses d3-geo orthographic projection + world-atlas countries-110m.
   Monochrome brown on off-white; slow auto-rotate; subtle whirl arcs
   rotating around the globe.
   Render targets a square container; canvas + whirl SVGs are absolutely
   positioned to fill it.
*/

const Globe = () => {
  const wrapRef = React.useRef(null);
  const canvasRef = React.useRef(null);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    const wrap = wrapRef.current;
    if (!canvas || !wrap || !window.d3 || !window.topojson) return;

    const ctx = canvas.getContext('2d');
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const INK = (getComputedStyle(document.documentElement)
      .getPropertyValue('--kd-brown-700').trim()) || '#864D39';
    const BG = (getComputedStyle(document.documentElement)
      .getPropertyValue('--bg-1').trim()) || '#F5EFE6';

    let cssSize = wrap.clientWidth;
    const setSize = () => {
      cssSize = wrap.clientWidth;
      canvas.width = cssSize * dpr;
      canvas.height = cssSize * dpr;
      canvas.style.width = cssSize + 'px';
      canvas.style.height = cssSize + 'px';
      ctx.setTransform(1, 0, 0, 1, 0, 0);
      ctx.scale(dpr, dpr);
      projection
        .scale(cssSize * 0.44)
        .translate([cssSize / 2, cssSize / 2]);
    };

    const projection = window.d3.geoOrthographic()
      .clipAngle(90)
      .precision(0.4);
    const path = window.d3.geoPath(projection, ctx);
    const sphere = { type: 'Sphere' };
    const graticule = window.d3.geoGraticule10();

    let land = null;
    let borders = null;
    let rafId = null;
    let disposed = false;

    const load = async () => {
      try {
        const res = await fetch('https://unpkg.com/world-atlas@2.0.2/countries-110m.json');
        const topology = await res.json();
        if (disposed) return;
        land = window.topojson.feature(topology, topology.objects.countries);
        borders = window.topojson.mesh(topology, topology.objects.countries, (a, b) => a !== b);
      } catch (err) {
        console.error('Globe: failed to load countries', err);
      }
    };

    setSize();
    const ro = new ResizeObserver(() => setSize());
    ro.observe(wrap);

    const start = performance.now();
    const draw = () => {
      const t = performance.now() - start;
      const rotation = (t / 1000) * 8; // slow rotate — 45s per full turn
      projection.rotate([rotation, -12, 0]);

      ctx.clearRect(0, 0, cssSize, cssSize);

      // Subtle sphere body
      ctx.beginPath();
      path(sphere);
      ctx.fillStyle = 'rgba(134, 77, 57, 0.045)';
      ctx.fill();

      // Graticule — faint grid
      ctx.beginPath();
      path(graticule);
      ctx.strokeStyle = 'rgba(134, 77, 57, 0.12)';
      ctx.lineWidth = 0.6;
      ctx.stroke();

      // Land
      if (land) {
        ctx.beginPath();
        path(land);
        ctx.fillStyle = INK;
        ctx.fill();
      }

      // Country borders — bg color as separation lines
      if (borders) {
        ctx.beginPath();
        path(borders);
        ctx.strokeStyle = BG;
        ctx.lineWidth = 0.55;
        ctx.stroke();
      }

      // Sphere outline
      ctx.beginPath();
      path(sphere);
      ctx.strokeStyle = INK;
      ctx.lineWidth = 1;
      ctx.stroke();

      rafId = requestAnimationFrame(draw);
    };

    load();
    draw();

    return () => {
      disposed = true;
      cancelAnimationFrame(rafId);
      ro.disconnect();
    };
  }, []);

  return (
    <div ref={wrapRef} className="globe" aria-hidden="true">
      <canvas ref={canvasRef} className="globe__canvas" />

      {/* Whirl arcs — three rings rotating at different speeds */}
      <svg className="globe__whirl globe__whirl--c" viewBox="0 0 200 200">
        <defs>
          <linearGradient id="glb-c" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="var(--kd-brown-700)" stopOpacity="0" />
            <stop offset="60%" stopColor="var(--kd-brown-700)" stopOpacity="0.18" />
            <stop offset="100%" stopColor="var(--kd-brown-700)" stopOpacity="0.55" />
          </linearGradient>
        </defs>
        <circle cx="100" cy="100" r="98" fill="none" stroke="var(--kd-brown-700)" strokeOpacity="0.08" strokeWidth="0.45" />
        <circle cx="100" cy="100" r="98" fill="none" stroke="url(#glb-c)" strokeWidth="0.9" strokeLinecap="round" strokeDasharray="460 160" />
      </svg>
      <svg className="globe__whirl globe__whirl--b" viewBox="0 0 200 200">
        <defs>
          <linearGradient id="glb-b" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="var(--kd-brown-700)" stopOpacity="0" />
            <stop offset="100%" stopColor="var(--kd-brown-700)" stopOpacity="0.5" />
          </linearGradient>
        </defs>
        <circle cx="100" cy="100" r="92" fill="none" stroke="var(--kd-brown-700)" strokeOpacity="0.06" strokeWidth="0.4" />
        <circle cx="100" cy="100" r="92" fill="none" stroke="url(#glb-b)" strokeWidth="1" strokeLinecap="round" strokeDasharray="180 500" />
        <circle cx="192" cy="100" r="1.4" fill="var(--kd-brown-700)" />
      </svg>
      <svg className="globe__whirl globe__whirl--a" viewBox="0 0 200 200">
        <defs>
          <linearGradient id="glb-a" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="var(--kd-brown-700)" stopOpacity="0" />
            <stop offset="100%" stopColor="var(--kd-brown-700)" stopOpacity="0.7" />
          </linearGradient>
        </defs>
        <circle cx="100" cy="100" r="84" fill="none" stroke="url(#glb-a)" strokeWidth="1.1" strokeLinecap="round" strokeDasharray="56 500" />
        <circle cx="184" cy="100" r="1.8" fill="var(--kd-brown-700)" />
      </svg>
    </div>
  );
};

window.Globe = Globe;
