// topo.jsx — generative topographic contour-line backgrounds

// Deterministic pseudo-random based on a string seed
function seededRng(seed) {
  let h = 2166136261 >>> 0;
  for (let i = 0; i < seed.length; i++) {
    h ^= seed.charCodeAt(i);
    h = Math.imul(h, 16777619);
  }
  return () => {
    h += 0x6D2B79F5;
    let t = h;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

// Build a "topographic" SVG: a stack of irregular closed contour rings,
// each one nudged slightly so they look like elevation lines on a map.
function TopoSVG({ seed = "everest", width = 600, height = 400, stroke = "rgba(252,250,244,.18)", strokeBold = "rgba(252,250,244,.32)", rings = 14, peakX, peakY }) {
  const rand = seededRng(seed);
  const cx = peakX != null ? peakX : (0.35 + rand() * 0.3) * width;
  const cy = peakY != null ? peakY : (0.45 + rand() * 0.25) * height;

  // a couple of "wind" lobes to push contours into non-circular shapes
  const lobes = [];
  const nLobes = 3 + Math.floor(rand() * 3);
  for (let i = 0; i < nLobes; i++) {
    lobes.push({
      angle: rand() * Math.PI * 2,
      strength: 0.15 + rand() * 0.35,
      sharpness: 1 + rand() * 2.5,
    });
  }

  const paths = [];
  const baseR = Math.min(width, height) * 0.12;
  const ringSpacing = (Math.max(width, height) * 0.95) / rings;

  for (let r = 0; r < rings; r++) {
    const radius = baseR + r * ringSpacing * 0.45;
    const steps = 96;
    let d = "";
    for (let i = 0; i <= steps; i++) {
      const t = (i / steps) * Math.PI * 2;
      let rr = radius;
      // apply lobes
      for (const L of lobes) {
        const a = Math.cos(t - L.angle);
        rr += L.strength * radius * Math.sign(a) * Math.pow(Math.abs(a), L.sharpness);
      }
      // micro jitter (consistent per ring + step)
      const jrng = seededRng(seed + "|" + r + "|" + i);
      rr += (jrng() - 0.5) * radius * 0.06;

      const x = cx + Math.cos(t) * rr;
      const y = cy + Math.sin(t) * rr * 0.78; // squish vertically
      d += (i === 0 ? "M" : "L") + x.toFixed(1) + "," + y.toFixed(1) + " ";
    }
    d += "Z";
    paths.push({ d, bold: r % 4 === 0 });
  }

  return (
    <svg viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="xMidYMid slice">
      <defs>
        <radialGradient id={`topo-fade-${seed}`} cx={cx / width} cy={cy / height} r="0.85">
          <stop offset="0%" stopColor="rgba(201,81,43,.18)" />
          <stop offset="60%" stopColor="rgba(74,110,133,.08)" />
          <stop offset="100%" stopColor="rgba(0,0,0,0)" />
        </radialGradient>
      </defs>
      <rect width={width} height={height} fill={`url(#topo-fade-${seed})`} />
      {paths.map((p, i) => (
        <path
          key={i}
          d={p.d}
          fill="none"
          stroke={p.bold ? strokeBold : stroke}
          strokeWidth={p.bold ? 1.1 : 0.7}
        />
      ))}
      {/* tiny summit triangle */}
      <g transform={`translate(${cx},${cy})`}>
        <circle r="2.5" fill="rgba(252,250,244,.9)" />
        <circle r="6" fill="none" stroke="rgba(252,250,244,.5)" strokeWidth="0.6" />
      </g>
    </svg>
  );
}

// Full-page faint topo lines (paper)
function TopoBackdrop() {
  return (
    <svg className="topo-bg" viewBox="0 0 1600 1000" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
      <TopoSVGPaper />
    </svg>
  );
}

// Inline SVG paper-colored backdrop (light contour lines on paper)
function TopoSVGPaper() {
  const rand = seededRng("paper-2026");
  const cx = 1100;
  const cy = 380;
  const rings = 22;
  const baseR = 60;
  const lobes = [
    { angle: 0.4, strength: 0.32, sharpness: 1.6 },
    { angle: 2.1, strength: 0.22, sharpness: 2.0 },
    { angle: 4.4, strength: 0.18, sharpness: 1.2 },
  ];
  const paths = [];
  for (let r = 0; r < rings; r++) {
    const radius = baseR + r * 60;
    const steps = 120;
    let d = "";
    for (let i = 0; i <= steps; i++) {
      const t = (i / steps) * Math.PI * 2;
      let rr = radius;
      for (const L of lobes) {
        const a = Math.cos(t - L.angle);
        rr += L.strength * radius * Math.sign(a) * Math.pow(Math.abs(a), L.sharpness);
      }
      const jrng = seededRng("paper|" + r + "|" + i);
      rr += (jrng() - 0.5) * radius * 0.04;
      const x = cx + Math.cos(t) * rr;
      const y = cy + Math.sin(t) * rr * 0.78;
      d += (i === 0 ? "M" : "L") + x.toFixed(1) + "," + y.toFixed(1) + " ";
    }
    d += "Z";
    paths.push({ d, bold: r % 5 === 0 });
  }
  return (
    <g>
      {paths.map((p, i) => (
        <path
          key={i}
          d={p.d}
          fill="none"
          stroke={p.bold ? "rgba(58,65,83,.35)" : "rgba(58,65,83,.18)"}
          strokeWidth={p.bold ? 0.9 : 0.5}
        />
      ))}
    </g>
  );
}

Object.assign(window, { TopoSVG, TopoBackdrop });
