const { useEffect, useRef, useState, useMemo } = React;

// ======== WORLD MAP ========
// A proper dotted world map built from a low-res landmass mask. Nodes sit
// on real approximate coordinates (equirectangular projection onto a 960x420 canvas).
// Continent silhouettes encoded as a coarse bitmap string so the map reads as
// geographically credible rather than a random scatter.

// Rows = 30 bands of ~5° latitude from +80° (top) to -70° (bottom).
// Cols = 72 bands of 5° longitude from -180° (left) to +180° (right).
// Encoding is a coarse approximation of real landmasses — recognisable
// continental shapes (N.America, S.America, Europe, Africa, Asia, Australia, Antarctica).
const LANDMASS = [
  // +80  row 0  (polar cap of land shards / Greenland / Svalbard)
  "...........#####.......#..##...........................................",
  // +75
  "........#########........##..#.......##................................",
  // +70  (Alaska, N.Canada, Greenland, N.Scandinavia, N.Russia, N.Siberia)
  "......####.########.#####.####.#####.########..########################",
  // +65
  "....#######.##############.##########################################..",
  // +60  (Canada, Britain, Scandinavia, Russia, Siberia)
  "....##########################..########################################",
  // +55
  "....############################..######################################",
  // +50
  "...###########################....##############.##################.....",
  // +45  (US/Canada border, Europe, C.Asia, NE China, Japan)
  "...#########################......##########.#..###############.####....",
  // +40  (US, Mediterranean, Turkey, Iran, China, Korea, Japan)
  "....######################.........##########..###############...##.....",
  // +35
  ".....#####################..........#######......##############.##......",
  // +30  (Mexico, N.Africa, Arabia, India, S.China)
  "......##################.............######......###########...........",
  // +25
  ".......###############.................####......######..###...........",
  // +20  (C.America, Sahara, Arabia, India, SE.Asia)
  "........##########.##..................####.....#####....###.##........",
  // +15
  ".........#########.....................####.....####......###..........",
  // +10  (N.S.America, Africa, SE.Asia islands)
  "...........#######......................###....####.......###..........",
  // +5
  "............######.......................###...####.......#.##.........",
  // 0    (equator — Amazon, Congo, Indonesia)
  ".............#######......................####...####......####........",
  // -5
  "..............#########....................####...##.......###.........",
  // -10  (Brazil, Angola, Indonesia, N.Australia)
  "...............##########..................####............###....####.",
  // -15
  "................#########....................###............##.....###.",
  // -20  (Brazil, S.Africa, Australia)
  "................########......................##...................####",
  // -25
  "................#######........................##..................####",
  // -30  (Argentina/Chile, S.Africa, S.Australia)
  "................######..........................#..................###.",
  // -35
  ".................####..............................................###.",
  // -40
  ".................##.................................................##.",
  // -45
  "..................#.....................................................",
  // -50  (Patagonia tip)
  "..................#.....................................................",
  // -55
  "........................................................................",
  // -60
  "........................................................................",
  // -65 (Antarctica)
  "########################################################################",
];

function landDots() {
  const dots = [];
  const cols = LANDMASS[0].length; // 72
  const rows = LANDMASS.length; // 30
  const W = 960,
    H = 420;
  const cw = W / cols;
  const rh = H / rows;
  // oversample each cell into a 2x2 grid with jitter for organic texture
  for (let ry = 0; ry < rows; ry++) {
    for (let cx = 0; cx < cols; cx++) {
      if (LANDMASS[ry][cx] !== "#") continue;
      for (let sy = 0; sy < 2; sy++) {
        for (let sx = 0; sx < 2; sx++) {
          const seed = (ry * 131 + cx * 17 + sy * 7 + sx * 3) % 10;
          if (seed < 2) continue; // ~20% gaps for organic feel
          const jx = ((seed * 37) % 100) / 100 - 0.5;
          const jy = ((seed * 53) % 100) / 100 - 0.5;
          const x = cx * cw + (sx + 0.5) * (cw / 2) + jx * 1.4;
          const y = ry * rh + (sy + 0.5) * (rh / 2) + jy * 1.4;
          dots.push([x, y]);
        }
      }
    }
  }
  return dots;
}

// Convert (lon, lat) to canvas coordinates (matches bitmap's +80..-70 range)
function project(lon, lat, W = 960, H = 420) {
  const x = ((lon + 180) / 360) * W;
  const y = ((80 - lat) / 150) * H;
  return [x, y];
}

function greatCirclePath(A, B, curveAmt = 0.22) {
  // quadratic approximation of a great-circle arc — enough to feel globe-like
  const [ax, ay] = A;
  const [bx, by] = B;
  const mx = (ax + bx) / 2;
  const my = (ay + by) / 2;
  const dx = bx - ax;
  const dy = by - ay;
  const dist = Math.hypot(dx, dy);
  // perpendicular, curving "northward" for a rounded arc
  const nx = -dy / dist;
  const ny = dx / dist;
  const cx = mx + nx * dist * curveAmt;
  const cy = my + ny * dist * curveAmt - dist * 0.08; // additional lift
  return `M${ax.toFixed(1)} ${ay.toFixed(1)} Q ${cx.toFixed(1)} ${cy.toFixed(1)} ${bx.toFixed(1)} ${by.toFixed(1)}`;
}

function WorldMap() {
  const dots = useMemo(() => landDots(), []);
  // Major hubs with real-ish coordinates
  const hubs = [
    { n: "NEW YORK", lon: -74, lat: 40.7, tier: 1, off: [10, -4] },
    { n: "LONDON", lon: -0.1, lat: 51.5, tier: 1, off: [10, -4] },
    { n: "ZÜRICH", lon: 8.5, lat: 47.4, tier: 2, off: [10, 12] },
    { n: "DUBAI", lon: 55.3, lat: 25.2, tier: 1, off: [10, -4] },
    { n: "MUMBAI", lon: 72.8, lat: 19.1, tier: 2, off: [10, 12] },
    { n: "SINGAPORE", lon: 103.8, lat: 1.35, tier: 1, off: [10, -4] },
    { n: "HONG KONG", lon: 114.2, lat: 22.3, tier: 2, off: [10, -4] },
    { n: "TOKYO", lon: 139.7, lat: 35.7, tier: 1, off: [10, 12] },
    { n: "SÃO PAULO", lon: -46.6, lat: -23.5, tier: 2, off: [10, 12] },
    { n: "SYDNEY", lon: 151.2, lat: -33.9, tier: 2, off: [-80, -4] },
  ];

  // Animated routes — pairs of hubs with a great-circle arc between them
  const routePairs = [
    [0, 1],
    [1, 3],
    [3, 5],
    [5, 7],
    [1, 7],
    [0, 8],
    [3, 4],
    [5, 9],
    [1, 2],
  ];

  return (
    <svg
      viewBox="0 0 960 420"
      fill="none"
      style={{ width: "100%", height: "auto", display: "block" }}
    >
      <defs>
        <radialGradient id="nodeGlow" cx="0.5" cy="0.5" r="0.5">
          <stop offset="0" stopColor="#E5C88F" stopOpacity="0.55" />
          <stop offset="1" stopColor="#E5C88F" stopOpacity="0" />
        </radialGradient>
        <linearGradient id="arcGrad" x1="0" y1="0" x2="1" y2="0">
          <stop offset="0" stopColor="#C9A961" stopOpacity="0" />
          <stop offset="0.5" stopColor="#E5C88F" stopOpacity="0.9" />
          <stop offset="1" stopColor="#C9A961" stopOpacity="0" />
        </linearGradient>
      </defs>

      {/* Frame + graticule */}
      <rect
        x="0.5"
        y="0.5"
        width="959"
        height="419"
        stroke="#C9A961"
        strokeOpacity="0.08"
        fill="none"
      />
      {/* Latitude parallels (subtle) */}
      {[-60, -30, 0, 30, 60].map((lat) => {
        const [, y] = project(0, lat);
        return (
          <line
            key={"p" + lat}
            x1="0"
            x2="960"
            y1={y}
            y2={y}
            stroke="#C9A961"
            strokeOpacity={lat === 0 ? 0.14 : 0.06}
            strokeDasharray={lat === 0 ? "0" : "1 6"}
          />
        );
      })}
      {/* Meridians at every 30° */}
      {[-150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150].map((lon) => {
        const [x] = project(lon, 0);
        return (
          <line
            key={"m" + lon}
            y1="0"
            y2="420"
            x1={x}
            x2={x}
            stroke="#C9A961"
            strokeOpacity="0.05"
            strokeDasharray="1 8"
          />
        );
      })}

      {/* Latitude tick labels — minimal */}
      {[60, 30, 0, -30, -60].map((lat) => {
        const [, y] = project(0, lat);
        return (
          <text
            key={"t" + lat}
            x="4"
            y={y - 3}
            fontFamily="JetBrains Mono, monospace"
            fontSize="7.5"
            fill="#E5C88F"
            opacity="0.35"
            letterSpacing="0.1em"
          >
            {(lat >= 0 ? "+" : "") + lat + "°"}
          </text>
        );
      })}

      {/* Landmass dotted map */}
      <g>
        {dots.map(([x, y], i) => (
          <circle
            key={i}
            cx={x}
            cy={y}
            r="0.85"
            fill="#C9A961"
            opacity={0.3 + ((i * 13) % 10) / 60}
          />
        ))}
      </g>

      {/* Great-circle arcs with traveling highlight */}
      {routePairs.map(([a, b], i) => {
        const A = project(hubs[a].lon, hubs[a].lat);
        const B = project(hubs[b].lon, hubs[b].lat);
        const d = greatCirclePath(A, B);
        const dur = 7 + (i % 4);
        return (
          <g key={"r" + i}>
            <path
              d={d}
              stroke="#C9A961"
              strokeOpacity="0.22"
              fill="none"
              strokeWidth="0.5"
              strokeDasharray="1 3"
            />
            <path
              d={d}
              stroke="#E5C88F"
              strokeOpacity="0.85"
              fill="none"
              strokeWidth="0.9"
              strokeDasharray="20 260"
              pathLength="280"
            >
              <animate
                attributeName="stroke-dashoffset"
                from="280"
                to="0"
                dur={`${dur}s`}
                repeatCount="indefinite"
                begin={`${i * 0.6}s`}
              />
            </path>
          </g>
        );
      })}

      {/* Hub nodes */}
      {hubs.map((h, i) => {
        const [x, y] = project(h.lon, h.lat);
        const r = h.tier === 1 ? 4.2 : 3.2;
        return (
          <g key={h.n}>
            <circle cx={x} cy={y} r="16" fill="url(#nodeGlow)">
              <animate
                attributeName="r"
                values="12;18;12"
                dur={`${3 + (i % 3)}s`}
                repeatCount="indefinite"
              />
              <animate
                attributeName="opacity"
                values="0.4;0.9;0.4"
                dur={`${3 + (i % 3)}s`}
                repeatCount="indefinite"
              />
            </circle>
            <circle
              cx={x}
              cy={y}
              r={r}
              fill="#0A0E1A"
              stroke="#E5C88F"
              strokeWidth="1"
            />
            <circle cx={x} cy={y} r={r * 0.45} fill="#E5C88F" />
            <text
              x={x + h.off[0]}
              y={y + h.off[1]}
              fontFamily="JetBrains Mono, monospace"
              fontSize="8.5"
              fill="#D4CDB8"
              letterSpacing="0.16em"
              opacity="0.82"
            >
              {h.n}
            </text>
          </g>
        );
      })}
    </svg>
  );
}

// ======== STAT COLUMN ========
function StatItem({ idx, target, suffix = "", prefix = "", label, detail }) {
  const [ref, inView] = useInView();
  const n = useCountUp(target, inView);
  const formatted = target >= 1000 ? n.toLocaleString() : n;
  return (
    <div ref={ref} className={`gl-stat ${inView ? "is-in" : ""}`}>
      <div className="gl-stat-idx">{idx}</div>
      <div className="gl-stat-num">
        {prefix}
        {formatted}
        <span className="gl-stat-unit">{suffix}</span>
      </div>
      <div className="gl-stat-label">{label}</div>
      <div className="gl-stat-rule" />
      <div className="gl-stat-detail">{detail}</div>
    </div>
  );
}

function Glance() {
  return (
    <section id="glance" className="glance-sec">
      {/* World map sits behind the whole section */}
      <div className="gl-map-bg" aria-hidden>
        <div className="gl-map-corners">
          <span />
          <span />
          <span />
          <span />
        </div>
        <div className="gl-map-legend">
          <span className="gl-legend-dot" /> Operational hub
          <span className="gl-legend-sep">·</span>
          <span className="gl-legend-arc" /> Active channel
        </div>
        <div className="gl-map-canvas">
          <WorldMap />
        </div>
        <div className="gl-map-footer">
          <span>EQUIRECTANGULAR · 180°W → 180°E</span>
          <span>3 PRIMARY NODES · 8 JURISDICTIONS</span>
        </div>
      </div>

      <div className="container gl-container">
        <Reveal className="section-head">
          <div>
            <div className="eyebrow" style={{ marginBottom: 24 }}>
              At a Glance
            </div>
            <h2 className="section-title">
              A <em>global</em> ecosystem,
              <br />
              quietly assembled.
            </h2>
          </div>
          <div className="right">
            <p className="body">
              Three continents of origin. Eight jurisdictions of reach. A
              network whose scale is matched only by its discretion — present
              where decisions are made, absent where they are not.
            </p>
          </div>
        </Reveal>

        <Reveal delay={180}>
          <div className="gl-stats">
            <StatItem
              idx="01"
              target={8}
              label="Jurisdictions of presence"
              detail="Americas · EMEA · APAC — operational reach across 3 primary financial centres."
            />
            <StatItem
              idx="02"
              target={300}
              suffix="+"
              label="Partners & Professionals"
              detail="Across advisory, capital markets, concierge, education and operating verticals."
            />
            <StatItem
              idx="03"
              target={500}
              suffix="+"
              label="Active network participants"
              detail="Principals, founders, family offices and accredited institutions — by invitation."
            />
          </div>
        </Reveal>

        <Reveal delay={320}>
          <p className="gl-footnote">
            Figures reflect the aggregate reach of the DeepRock Network as of
            the current fiscal period, including affiliated operating entities,
            partner funds and accredited member institutions.
          </p>
        </Reveal>
      </div>
    </section>
  );
}

Object.assign(window, { Glance });
