// PRISMA C2-style globe background — D3 orthographic projection on canvas
// Exposes window.focusGlobe(lat, lng, duration) for programmatic control

function GlobeBackground() {
  const canvasRef = React.useRef(null);
  const stateRef = React.useRef({
    rotation: [0, 35],        // [lambda, phi] — centered on Mediterranean/Europe
    scale: 1,                 // current scale multiplier
    baseScale: 1,             // computed from window size
    target: null,             // { rotation, scale, startTime, duration, from, fromScale }
    autoRotate: true,
    width: 0,
    height: 0,
    worldData: null,
    projection: null,
    path: null,
    animFrame: null,
    highlightId: null,        // ISO numeric id of the focused country
    pulse: false,             // pulsing glow on the focused country (GM thinking)
  });

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

    // Sizing
    const resize = () => {
      const dpr = window.devicePixelRatio || 1;
      s.width = window.innerWidth;
      s.height = window.innerHeight;
      canvas.width = s.width * dpr;
      canvas.height = s.height * dpr;
      canvas.style.width = s.width + 'px';
      canvas.style.height = s.height + 'px';
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);

      s.baseScale = Math.min(s.width, s.height) * 0.8;
      s.projection = d3.geoOrthographic()
        .scale(s.baseScale * s.scale)
        .translate([s.width / 2, s.height / 2])
        .clipAngle(90);
      s.path = d3.geoPath(s.projection, ctx);
    };

    resize();
    window.addEventListener('resize', resize);

    // Load world data
    fetch('https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json')
      .then(r => r.json())
      .then(world => {
        const countries = topojson.feature(world, world.objects.countries);
        s.worldData = {
          land: topojson.feature(world, world.objects.land),
          countries: countries,  // individual country features (for highlight)
          borders: topojson.mesh(world, world.objects.countries, (a, b) => a !== b),
          graticule: d3.geoGraticule10(),
        };
      });

    // Easing
    const easeInOut = t => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;

    // Shortest-path delta for angles (always within -180..180)
    const shortAngle = (from, to) => {
      let d = ((to - from) % 360 + 540) % 360 - 180;
      return d;
    };

    // Render loop
    const render = () => {
      s.animFrame = requestAnimationFrame(render);
      if (!s.worldData) return;

      const now = performance.now();

      // Animate to target
      if (s.target) {
        const elapsed = now - s.target.startTime;
        const t = Math.min(1, elapsed / s.target.duration);
        const e = easeInOut(t);
        s.rotation = [
          s.target.from[0] + s.target.deltaLng * e,
          s.target.from[1] + s.target.deltaLat * e,
        ];
        s.scale = s.target.fromScale + (s.target.scale - s.target.fromScale) * e;
        if (t >= 1) {
          s.rotation = s.target.rotation;
          s.scale = s.target.scale;
          s.target = null;
        }
      } else if (s.autoRotate) {
        s.rotation[0] += 0.03;
      }

      s.projection
        .rotate([-s.rotation[0], -s.rotation[1]])
        .scale(s.baseScale * s.scale);

      // Clear
      ctx.clearRect(0, 0, s.width, s.height);

      // Globe sphere (subtle fill + outline)
      ctx.beginPath();
      s.path({ type: 'Sphere' });
      ctx.fillStyle = 'rgba(10, 20, 30, 0.3)';
      ctx.fill();
      ctx.strokeStyle = 'rgba(34, 211, 238, 0.15)';
      ctx.lineWidth = 1;
      ctx.stroke();

      // Graticule
      ctx.beginPath();
      s.path(s.worldData.graticule);
      ctx.strokeStyle = 'rgba(34, 211, 238, 0.04)';
      ctx.lineWidth = 0.5;
      ctx.stroke();

      // Land fill
      ctx.beginPath();
      s.path(s.worldData.land);
      ctx.fillStyle = 'rgba(34, 211, 238, 0.03)';
      ctx.fill();

      // Country borders
      ctx.beginPath();
      s.path(s.worldData.borders);
      ctx.strokeStyle = 'rgba(34, 211, 238, 0.15)';
      ctx.lineWidth = 0.6;
      ctx.stroke();

      // Coastlines
      ctx.beginPath();
      s.path(s.worldData.land);
      ctx.strokeStyle = 'rgba(34, 211, 238, 0.2)';
      ctx.lineWidth = 0.8;
      ctx.stroke();

      // Pulsing glow: focused country while the GM thinks, hovered choice's country
      const drawCountryPulse = (id) => {
        s._featCache = s._featCache || {};
        if (!(id in s._featCache)) {
          s._featCache[id] = s.worldData.countries.features.find(f => f.id === id) || null;
        }
        const feat = s._featCache[id];
        if (!feat) return;
        const pulse = 0.5 + 0.5 * Math.sin(now / 280); // ~1.8s cycle
        ctx.beginPath();
        s.path(feat);
        ctx.fillStyle = `rgba(34, 211, 238, ${0.08 + 0.14 * pulse})`;
        ctx.fill();
        ctx.save();
        ctx.shadowColor = 'rgba(34, 211, 238, 0.9)';
        ctx.shadowBlur = 8 + 14 * pulse;
        ctx.strokeStyle = `rgba(34, 211, 238, ${0.45 + 0.4 * pulse})`;
        ctx.lineWidth = 1.4;
        ctx.stroke();
        ctx.restore();
      };

      if (s.pulse && s.highlightId) drawCountryPulse(s.highlightId);

    };

    render();

    // Country name → [lat, lng, ISO-3166-1-numeric-id]
    const COUNTRY_DATA = {
      'united states': [39, -98, '840'], 'usa': [39, -98, '840'], 'russia': [60, 100, '643'], 'china': [35, 105, '156'],
      'france': [46, 2, '250'], 'germany': [51, 10, '276'], 'united kingdom': [54, -2, '826'], 'uk': [54, -2, '826'],
      'japan': [36, 138, '392'], 'india': [20, 78, '356'], 'brazil': [-14, -51, '076'], 'australia': [-25, 134, '036'],
      'south korea': [36, 128, '410'], 'north korea': [40, 127, '408'], 'iran': [32, 53, '364'], 'iraq': [33, 44, '368'],
      'israel': [31, 35, '376'], 'saudi arabia': [24, 45, '682'], 'turkey': [39, 35, '792'], 'egypt': [27, 30, '818'],
      'ukraine': [49, 32, '804'], 'poland': [52, 20, '616'], 'taiwan': [23, 121, '158'], 'pakistan': [30, 70, '586'],
      'afghanistan': [33, 65, '004'], 'syria': [35, 38, '760'], 'nigeria': [10, 8, '566'], 'south africa': [-29, 25, '710'],
      'mexico': [23, -102, '484'], 'canada': [56, -106, '124'], 'argentina': [-38, -63, '032'], 'venezuela': [7, -66, '862'],
      'indonesia': [-5, 120, '360'], 'philippines': [13, 122, '608'], 'vietnam': [14, 108, '704'], 'thailand': [15, 100, '764'],
      'italy': [42, 12, '380'], 'spain': [40, -4, '724'], 'greece': [39, 22, '300'], 'sweden': [62, 15, '752'],
      'norway': [62, 10, '578'], 'finland': [64, 26, '246'], 'cuba': [22, -80, '192'], 'colombia': [4, -72, '170'],
      'chile': [-35, -71, '152'], 'peru': [-10, -76, '604'], 'ethiopia': [9, 40, '231'], 'kenya': [-1, 38, '404'],
      'morocco': [32, -5, '504'], 'algeria': [28, 3, '012'], 'libya': [27, 17, '434'], 'sudan': [13, 30, '729'],
      'myanmar': [19, 96, '104'], 'bangladesh': [24, 90, '050'], 'nepal': [28, 84, '524'], 'sri lanka': [7, 81, '144'],
    };

    // Focus by country name + highlight its borders
    window.focusGlobeOnCountry = (countryName, duration = 1500) => {
      if (!countryName) return;
      const key = countryName.toLowerCase().trim();
      const data = COUNTRY_DATA[key];
      if (data) {
        stateRef.current.highlightId = data[2];
        window.focusGlobe(data[0], data[1], duration);
      }
    };

    // Pulsing highlight on the focused country (used while the GM responds)
    window.setGlobePulse = (on) => {
      stateRef.current.pulse = !!on;
    };


    // Global API
    window.focusGlobe = (lat, lng, duration = 1500, zoom = 1.6) => {
      const s = stateRef.current;
      s.target = {
        rotation: [lng, lat],
        scale: zoom,
        from: [...s.rotation],
        fromScale: s.scale,
        deltaLng: shortAngle(s.rotation[0], lng),
        deltaLat: shortAngle(s.rotation[1], lat),
        startTime: performance.now(),
        duration,
      };
    };

    window.stopGlobeRotation = () => {
      stateRef.current.autoRotate = false;
    };

    window.startGlobeRotation = () => {
      stateRef.current.autoRotate = true;
    };

    window.resetGlobe = () => {
      const s = stateRef.current;
      s.autoRotate = true;
      s.target = {
        rotation: [...s.rotation],
        scale: 1,
        from: [...s.rotation],
        fromScale: s.scale,
        deltaLng: 0,
        deltaLat: 0,
        startTime: performance.now(),
        duration: 1500,
      };
    };

    return () => {
      window.removeEventListener('resize', resize);
      if (s.animFrame) cancelAnimationFrame(s.animFrame);
      delete window.focusGlobe;
      delete window.stopGlobeRotation;
      delete window.startGlobeRotation;
      delete window.resetGlobe;
      delete window.focusGlobeOnCountry;
      delete window.setGlobePulse;
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      style={{
        position: 'fixed',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        zIndex: 0,
        pointerEvents: 'none',
      }}
    />
  );
}
