/* global React */

// HexGlobe — animated bioluminescent Earth.
// Rebrand: amber/cyan → bloom (emerald) leads, ember (gold) for active hexes.
function HexGlobe({ size = 520, accent = 'bloom' }) {
  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    let raf, start = performance.now();
    const tick = (now) => { setT((now - start) / 1000); raf = requestAnimationFrame(tick); };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const cx = size / 2, cy = size / 2;
  const R = size * 0.42;

  // accent: which color leads — bloom or ember
  const leadCol  = accent === 'ember' ? '#ecc781' : '#6cd49a';
  const leadGlow = accent === 'ember' ? 'rgba(217,166,72,0.45)' : 'rgba(108,212,154,0.45)';
  const subCol   = accent === 'ember' ? '#6cd49a' : '#ecc781';

  const points = React.useMemo(() => {
    const N = 380;
    const pts = [];
    const phi = Math.PI * (3 - Math.sqrt(5));
    for (let i = 0; i < N; i++) {
      const y = 1 - (i / (N - 1)) * 2;
      const r = Math.sqrt(1 - y * y);
      const theta = phi * i;
      pts.push({ x0: Math.cos(theta) * r, y0: y, z0: Math.sin(theta) * r, seed: (i * 9301 + 49297) % 233280 / 233280 });
    }
    return pts;
  }, []);

  const activeIdx = [12, 40, 78, 130, 175, 220, 270, 320];
  const rot = t * 0.10;
  const cosR = Math.cos(rot), sinR = Math.sin(rot);

  const hexPath = (x, y, r) => {
    let d = '';
    for (let i = 0; i < 6; i++) {
      const a = (Math.PI / 3) * i + Math.PI / 6;
      d += (i === 0 ? 'M' : 'L') + (x + Math.cos(a) * r).toFixed(2) + ' ' + (y + Math.sin(a) * r).toFixed(2);
    }
    return d + 'Z';
  };

  const projected = points.map((p, i) => {
    const x1 = p.x0 * cosR + p.z0 * sinR;
    const z1 = -p.x0 * sinR + p.z0 * cosR;
    const tilt = 0.35;
    const y1 = p.y0 * Math.cos(tilt) - z1 * Math.sin(tilt);
    const z2 = p.y0 * Math.sin(tilt) + z1 * Math.cos(tilt);
    return { i, sx: cx + x1 * R, sy: cy + y1 * R, depth: z2, seed: p.seed };
  });

  return (
    <svg viewBox={`0 0 ${size} ${size}`} style={{ overflow: 'visible', width: '100%', height: '100%', display: 'block' }}>
      <defs>
        <radialGradient id="globeGlow" cx="50%" cy="50%" r="60%">
          <stop offset="0%" stopColor={leadGlow} />
          <stop offset="100%" stopColor="rgba(108,212,154,0)" />
        </radialGradient>
        <radialGradient id="globeFill" cx="40%" cy="35%" r="70%">
          <stop offset="0%" stopColor="#1a221c" />
          <stop offset="100%" stopColor="#050807" />
        </radialGradient>
        <radialGradient id="atmo" cx="50%" cy="50%" r="50%">
          <stop offset="92%" stopColor="rgba(139,127,207,0)" />
          <stop offset="98%" stopColor="rgba(139,127,207,0.35)" />
          <stop offset="100%" stopColor="rgba(139,127,207,0)" />
        </radialGradient>
      </defs>

      {/* Outer halo */}
      <circle cx={cx} cy={cy} r={R * 1.4} fill="url(#globeGlow)" />
      <circle cx={cx} cy={cy} r={R * 1.04} fill="url(#atmo)" />
      <circle cx={cx} cy={cy} r={R} fill="url(#globeFill)" stroke="rgba(108,212,154,0.18)" />

      {/* Lat/lon graticule */}
      <g stroke="rgba(236,239,232,0.05)" strokeWidth="1" fill="none">
        <ellipse cx={cx} cy={cy} rx={R} ry={R * 0.32} />
        <ellipse cx={cx} cy={cy} rx={R} ry={R * 0.62} />
        <ellipse cx={cx} cy={cy} rx={R * 0.45} ry={R} />
        <ellipse cx={cx} cy={cy} rx={R * 0.85} ry={R} />
      </g>

      {/* Hex field */}
      <g>
        {projected.filter(p => p.depth > -0.05).sort((a,b) => a.depth - b.depth).map(p => {
          const isActive = activeIdx.includes(p.i);
          const pulse = isActive ? (Math.sin(t * 1.4 + p.i) * 0.5 + 0.5) : 0;
          const r = 8 + p.seed * 4;
          const opacity = 0.10 + p.depth * 0.55;
          if (isActive) {
            return (
              <g key={p.i}>
                <path d={hexPath(p.sx, p.sy, r)} fill="rgba(217,166,72,0.16)" stroke="#ecc781" strokeWidth={1 + pulse} opacity={0.55 + pulse * 0.45} />
                <path d={hexPath(p.sx, p.sy, r * (1 + pulse * 0.5))} fill="none" stroke="#ecc781" strokeWidth="1" opacity={1 - pulse} />
              </g>
            );
          }
          // AI-evolving hexes: bloom-tinted
          const isAi = (p.i % 23 === 0) || (p.i % 31 === 0);
          return (
            <path
              key={p.i}
              d={hexPath(p.sx, p.sy, r)}
              fill={isAi ? 'rgba(43,182,115,0.12)' : 'none'}
              stroke={isAi ? 'rgba(108,212,154,0.55)' : 'rgba(236,239,232,0.16)'}
              strokeWidth="0.8"
              opacity={opacity}
            />
          );
        })}
      </g>

      {/* Trade arcs (cyan) */}
      <g fill="none" stroke="#5ec5d4" strokeWidth="1" opacity="0.6">
        {[[0,2],[1,4],[3,5],[2,6],[4,7]].map(([a, b], k) => {
          const pa = projected[activeIdx[a]], pb = projected[activeIdx[b]];
          if (!pa || !pb || pa.depth < 0 || pb.depth < 0) return null;
          const mx = (pa.sx + pb.sx) / 2, my = (pa.sy + pb.sy) / 2;
          const dx = pb.sx - pa.sx, dy = pb.sy - pa.sy;
          const len = Math.sqrt(dx*dx + dy*dy);
          const lift = Math.min(60, len * 0.35);
          const cx2 = mx - dy / len * lift, cy2 = my + dx / len * lift;
          const dash = (t * 30 + k * 17) % 60;
          return <path key={k} d={`M${pa.sx} ${pa.sy} Q${cx2} ${cy2} ${pb.sx} ${pb.sy}`} strokeDasharray="3 6" strokeDashoffset={-dash} opacity={0.5} />;
        })}
      </g>

      {/* Corner readouts */}
      <g fontFamily="JetBrains Mono, monospace" fontSize="9" fill="rgba(199,204,195,0.55)" letterSpacing="0.12em">
        <text x={cx - R} y={cy - R - 14}>SHARD · EARTH-1</text>
        <text x={cx + R} y={cy - R - 14} textAnchor="end">RES 6 · 36 km²</text>
        <text x={cx - R} y={cy + R + 22}>32,194 HEXES</text>
        <text x={cx + R} y={cy + R + 22} textAnchor="end">TICK · {(t % 1).toFixed(2)}s</text>
      </g>
    </svg>
  );
}

window.HexGlobe = HexGlobe;
