// GlobeScene.jsx — full sphere with atmosphere, terminator, continent silhouettes, orbital ring and connection mesh.
function GlobeScene() {
  const rand = React.useMemo(() => {
    let x = 7;
    return () => { x = (x * 9301 + 49297) % 233280; return x / 233280; };
  }, []);

  const stars = React.useMemo(() => {
    const r = (() => { let x = 11; return () => { x = (x * 9301 + 49297) % 233280; return x / 233280; }; })();
    return Array.from({ length: 220 }, () => ({
      x: r() * 1600, y: r() * 900, s: r() * 1.3 + 0.25, o: r() * 0.7 + 0.2, tw: 1.6 + r() * 2.8, d: r() * 4,
    }));
  }, []);

  const dust = React.useMemo(() => ([
    { cx: 220,  cy: 240, r: 260, c: "rgba(99,102,241,0.18)" },
    { cx: 1380, cy: 700, r: 320, c: "rgba(217,70,239,0.12)" },
    { cx: 1500, cy: 200, r: 180, c: "rgba(34,211,238,0.14)" },
  ]), []);

  const cx = 800, cy = 540, R = 300;

  const project = (lat, lon, rotDeg = 0) => {
    const φ = (lat * Math.PI) / 180;
    const λ = ((lon + rotDeg) * Math.PI) / 180;
    const x = Math.cos(φ) * Math.sin(λ);
    const y = Math.sin(φ);
    const z = Math.cos(φ) * Math.cos(λ);
    return { x: cx + x * R, y: cy - y * R, z };
  };

  const nodes = React.useMemo(() => {
    const out = [];
    for (let lat = -60; lat <= 60; lat += 20) {
      const step = lat === 0 ? 18 : Math.max(20, 22 + Math.abs(lat) * 0.4);
      for (let lon = -180; lon < 180; lon += step) { out.push({ lat, lon }); }
    }
    return out;
  }, []);

  const continents = React.useMemo(() => ([
    [[20,-100],[35,-95],[40,-75],[25,-65],[5,-70],[-15,-55],[-35,-65],[-45,-70],[-30,-50],[-10,-45],[5,-55],[15,-80]],
    [[55,-10],[60,15],[55,40],[35,45],[20,40],[5,30],[-15,20],[-30,25],[-30,10],[-10,5],[10,-5],[35,-10]],
    [[60,55],[65,90],[55,130],[35,140],[20,120],[10,100],[20,80],[35,65]],
    [[-15,115],[-10,140],[-25,150],[-35,140],[-30,120]],
  ]), []);

  const arcs = React.useMemo(() => {
    const r = (() => { let x = 31; return () => { x = (x * 9301 + 49297) % 233280; return x / 233280; }; })();
    const out = [];
    for (let i = 0; i < 22; i++) {
      const a = nodes[Math.floor(r() * nodes.length)];
      const b = nodes[Math.floor(r() * nodes.length)];
      out.push({ a, b, d: r() * 4, dur: 4 + r() * 4 });
    }
    return out;
  }, [nodes]);

  return (
    <div className="sn-globe-scene" aria-hidden="true">
      <svg viewBox="0 0 1600 900" preserveAspectRatio="xMidYMid slice">
        <defs>
          <radialGradient id="sn-globe-body" cx="35%" cy="32%" r="75%">
            <stop offset="0%"   stopColor="#1E3A8A" stopOpacity="1" />
            <stop offset="35%"  stopColor="#0B1E54" stopOpacity="1" />
            <stop offset="70%"  stopColor="#070D2A" stopOpacity="1" />
            <stop offset="100%" stopColor="#02040E" stopOpacity="1" />
          </radialGradient>
          <radialGradient id="sn-globe-night" cx="78%" cy="55%" r="65%">
            <stop offset="0%"   stopColor="#000814" stopOpacity="0.0" />
            <stop offset="55%"  stopColor="#000814" stopOpacity="0.55" />
            <stop offset="100%" stopColor="#000000" stopOpacity="0.85" />
          </radialGradient>
          <radialGradient id="sn-globe-spec" cx="30%" cy="22%" r="35%">
            <stop offset="0%"   stopColor="#A5F3FC" stopOpacity="0.55" />
            <stop offset="60%"  stopColor="#38BDF8" stopOpacity="0.10" />
            <stop offset="100%" stopColor="#38BDF8" stopOpacity="0" />
          </radialGradient>
          <radialGradient id="sn-atmo-inner" cx="50%" cy="50%" r="55%">
            <stop offset="78%"  stopColor="#38BDF8" stopOpacity="0" />
            <stop offset="92%"  stopColor="#7DD3FC" stopOpacity="0.55" />
            <stop offset="100%" stopColor="#A5F3FC" stopOpacity="0" />
          </radialGradient>
          <radialGradient id="sn-atmo-outer" cx="50%" cy="50%" r="65%">
            <stop offset="60%"  stopColor="#6366F1" stopOpacity="0" />
            <stop offset="85%"  stopColor="#6366F1" stopOpacity="0.20" />
            <stop offset="100%" stopColor="#A5B4FC" stopOpacity="0" />
          </radialGradient>
          <linearGradient id="sn-land" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%"   stopColor="#5EEAD4" stopOpacity="0.35" />
            <stop offset="100%" stopColor="#22D3EE" stopOpacity="0.20" />
          </linearGradient>
          <linearGradient id="sn-arc" x1="0" x2="1" y1="0" y2="0">
            <stop offset="0%"   stopColor="#A5F3FC" stopOpacity="0" />
            <stop offset="50%"  stopColor="#A5F3FC" stopOpacity="0.95" />
            <stop offset="100%" stopColor="#A5F3FC" stopOpacity="0" />
          </linearGradient>
          <filter id="sn-soft" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="1.5" result="b" />
            <feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge>
          </filter>
          <filter id="sn-bigglow" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="6" />
          </filter>
          <clipPath id="sn-globe-clip">
            <circle cx={cx} cy={cy} r={R} />
          </clipPath>
        </defs>

        {/* Starfield */}
        {stars.map((s, i) => (
          <circle key={i} cx={s.x} cy={s.y} r={s.s} fill="#E0F2FE" opacity={s.o}>
            <animate attributeName="opacity" values={`${s.o};${s.o * 0.2};${s.o}`}
              dur={`${s.tw}s`} begin={`${s.d}s`} repeatCount="indefinite" />
          </circle>
        ))}

        {/* Nebula dust */}
        {dust.map((d, i) => (
          <circle key={i} cx={d.cx} cy={d.cy} r={d.r} fill={d.c} filter="url(#sn-bigglow)" />
        ))}

        {/* Atmosphere */}
        <circle cx={cx} cy={cy} r={R + 70} fill="url(#sn-atmo-outer)" />
        <circle cx={cx} cy={cy} r={R + 32} fill="url(#sn-atmo-inner)" />

        {/* Orbital rings */}
        <g opacity="0.35">
          <ellipse cx={cx} cy={cy} rx={R + 90} ry={R * 0.28}
            fill="none" stroke="rgba(165,243,252,0.35)" strokeWidth="0.6"
            transform={`rotate(-18 ${cx} ${cy})`} strokeDasharray="2 6" />
          <ellipse cx={cx} cy={cy} rx={R + 130} ry={R * 0.42}
            fill="none" stroke="rgba(99,102,241,0.30)" strokeWidth="0.6"
            transform={`rotate(12 ${cx} ${cy})`} strokeDasharray="1 5" />
        </g>

        {/* Globe body */}
        <g>
          <circle cx={cx} cy={cy} r={R} fill="url(#sn-globe-body)" />

          {/* Wireframe */}
          <g clipPath="url(#sn-globe-clip)" opacity="0.35">
            {[-60,-40,-20,0,20,40,60].map((lat) => {
              const φ = (lat * Math.PI) / 180;
              const ry = R * 0.10 * Math.cos(φ);
              const cyLat = cy - Math.sin(φ) * R;
              return (
                <ellipse key={`lat${lat}`} cx={cx} cy={cyLat}
                  rx={Math.cos(φ) * R} ry={Math.max(2, Math.abs(ry))}
                  fill="none" stroke="rgba(125,211,252,0.20)" strokeWidth="0.5" />
              );
            })}
            {[-75,-45,-15,15,45,75].map((lon) => (
              <ellipse key={`lon${lon}`} cx={cx} cy={cy}
                rx={R * Math.abs(Math.sin((lon * Math.PI) / 180))} ry={R}
                fill="none" stroke="rgba(125,211,252,0.18)" strokeWidth="0.5" />
            ))}
          </g>

          {/* Continents */}
          <g clipPath="url(#sn-globe-clip)">
            <g className="sn-globe-rotate">
              {continents.map((poly, idx) => {
                const d = poly.map((p, i) => {
                  const { x, y } = project(p[0], p[1], 0);
                  return `${i === 0 ? "M" : "L"} ${x.toFixed(1)} ${y.toFixed(1)}`;
                }).join(" ") + " Z";
                return <path key={idx} d={d} fill="url(#sn-land)" stroke="rgba(94,234,212,0.55)" strokeWidth="0.6" opacity="0.85" />;
              })}
              {continents.map((poly, idx) => {
                const d = poly.map((p, i) => {
                  const { x, y } = project(p[0], p[1] + 180, 0);
                  return `${i === 0 ? "M" : "L"} ${x.toFixed(1)} ${y.toFixed(1)}`;
                }).join(" ") + " Z";
                return <path key={`b${idx}`} d={d} fill="url(#sn-land)" stroke="rgba(94,234,212,0.45)" strokeWidth="0.6" opacity="0.55" />;
              })}
            </g>
          </g>

          {/* Nodes */}
          <g clipPath="url(#sn-globe-clip)" filter="url(#sn-soft)">
            {nodes.map((n, i) => {
              const p = project(n.lat, n.lon, 0);
              if (p.z < 0.05) return null;
              const op = 0.35 + p.z * 0.55;
              const r = 0.8 + p.z * 1.6;
              return (
                <circle key={i} cx={p.x} cy={p.y} r={r} fill="#A5F3FC" opacity={op}>
                  {(i % 9 === 0) && (
                    <animate attributeName="opacity" values={`${op};${op * 0.3};${op}`}
                      dur={`${2 + (i % 5) * 0.5}s`} begin={`${(i % 7) * 0.4}s`} repeatCount="indefinite" />
                  )}
                </circle>
              );
            })}
          </g>

          {/* Connection arcs */}
          <g clipPath="url(#sn-globe-clip)" filter="url(#sn-soft)">
            {arcs.map((arc, i) => {
              const A = project(arc.a.lat, arc.a.lon, 0);
              const B = project(arc.b.lat, arc.b.lon, 0);
              if (A.z < 0.05 || B.z < 0.05) return null;
              const mx = (A.x + B.x) / 2, my = (A.y + B.y) / 2;
              const dx = mx - cx, dy = my - cy;
              const len = Math.hypot(dx, dy) || 1;
              const lift = 24;
              const cxC = mx + (dx / len) * lift, cyC = my + (dy / len) * lift;
              const d = `M ${A.x} ${A.y} Q ${cxC} ${cyC} ${B.x} ${B.y}`;
              return (
                <g key={i}>
                  <path d={d} fill="none" stroke="rgba(165,243,252,0.18)" strokeWidth="0.6" />
                  <circle r="1.6" fill="#A5F3FC" opacity="0.9">
                    <animateMotion path={d} dur={`${arc.dur}s`} begin={`${arc.d}s`} repeatCount="indefinite" />
                  </circle>
                </g>
              );
            })}
          </g>

          <circle cx={cx} cy={cy} r={R} fill="url(#sn-globe-spec)" style={{ mixBlendMode: "screen" }} />
          <circle cx={cx} cy={cy} r={R} fill="url(#sn-globe-night)" />
          <circle cx={cx} cy={cy} r={R}   fill="none" stroke="rgba(125,211,252,0.55)" strokeWidth="0.8" />
          <circle cx={cx} cy={cy} r={R+1.5} fill="none" stroke="rgba(165,243,252,0.20)" strokeWidth="0.6" />
        </g>

        {/* Satellite */}
        <g>
          <circle r="3" fill="#A5F3FC">
            <animateMotion dur="14s" repeatCount="indefinite"
              path={`M ${cx+R+90} ${cy} a ${R+90} ${R*0.28} 0 1 0 ${-2*(R+90)} 0 a ${R+90} ${R*0.28} 0 1 0 ${2*(R+90)} 0`}
              rotate="auto" />
            <animate attributeName="opacity" values="1;0.4;1" dur="2s" repeatCount="indefinite" />
          </circle>
        </g>
      </svg>
    </div>
  );
}

window.GlobeScene = GlobeScene;
