// Generative cover art for /writing. Inline SVG so it inherits the theme CSS
// variables (adapts to dark/light automatically). One cohesive abstract visual
// language across all articles, in the vein AI labs use for their own writing:
// soft gradient fields + thin geometric line work, seeded per topic.
//
// Public: <CoverArt slug="..." variant="card|hero" />

// --- deterministic pseudo-random, seeded by slug (so a cover never reshuffles) ---
function artHash(s) {
  let h = 2166136261;
  for (let i = 0; i < (s || "").length; i++) { h ^= s.charCodeAt(i); h = Math.imul(h, 16777619); }
  return h >>> 0;
}
function artRng(seed) {
  let a = seed >>> 0;
  return function () {
    a = (a + 0x6d2b79f5) | 0;
    let t = Math.imul(a ^ (a >>> 15), 1 | a);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

// motif + tone per article. tone: cool=accent blue, warm=amber, mix=both.
const ART_MAP = {
  "predictions-2026": { m: "orbit", t: "mix" },
  "what-stays-human": { m: "bloom", t: "warm" },
  "future-of-jobs": { m: "strata", t: "warm" },
  "on-intelligence": { m: "bloom", t: "cool" },
  "turing-test": { m: "interfere", t: "cool" },
  "world-simulators": { m: "grid", t: "cool" },
  "responsibility-of-dialogue": { m: "interfere", t: "warm" },
  "incompleteness-of-ethics": { m: "loop", t: "cool" },
  "backpropagation-intuition": { m: "field", t: "cool" },
  "the-analog-spark": { m: "bloom", t: "mix" },
  "how-to-implement-ai-in-your-company": { m: "lattice", t: "cool" },
  "cum-implementez-ai-in-companie-ghid": { m: "lattice", t: "cool" },
  "ai-automation-for-business-what-is-worth-automating": { m: "field", t: "cool" },
  "automatizari-ai-pentru-companii-ce-merita-automatizat": { m: "field", t: "cool" },
  "ai-development-romania": { m: "lattice", t: "warm" },
  "dezvoltare-ai-romania": { m: "lattice", t: "warm" },
  "what-is-a-machine-learning-solution": { m: "strata", t: "cool" },
  "ce-este-o-solutie-machine-learning": { m: "strata", t: "cool" },
};
const ART_MOTIFS = ["bloom", "orbit", "grid", "interfere", "loop", "field", "lattice", "strata"];
const ART_TONES = ["cool", "warm", "mix"];

function artMeta(slug) {
  if (ART_MAP[slug]) return ART_MAP[slug];
  const h = artHash(slug || "x");
  return { m: ART_MOTIFS[h % ART_MOTIFS.length], t: ART_TONES[(h >> 5) % ART_TONES.length] };
}
function artColors(tone) {
  if (tone === "warm") return { a: "var(--warm)", b: "var(--warm)" };
  if (tone === "mix") return { a: "var(--accent)", b: "var(--warm)" };
  return { a: "var(--accent)", b: "var(--accent)" };
}

// ---- motif renderers: each returns { defs, body } for the 600x375 canvas ----
function motifBloom(id, rnd, col) {
  const orbs = [];
  const n = 3;
  for (let i = 0; i < n; i++) {
    orbs.push({
      cx: 120 + rnd() * 360, cy: 80 + rnd() * 215,
      r: 150 + rnd() * 130, fill: i === 1 ? "b" : "a",
      o: 0.5 + rnd() * 0.35,
    });
  }
  const dots = [];
  for (let i = 0; i < 22; i++) dots.push({ x: rnd() * 600, y: rnd() * 375, r: 0.7 + rnd() * 1.1 });
  return {
    defs: (
      <React.Fragment>
        <radialGradient id={id + "-ga"} cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor={col.a} stopOpacity="0.85" />
          <stop offset="55%" stopColor={col.a} stopOpacity="0.22" />
          <stop offset="100%" stopColor={col.a} stopOpacity="0" />
        </radialGradient>
        <radialGradient id={id + "-gb"} cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor={col.b} stopOpacity="0.8" />
          <stop offset="55%" stopColor={col.b} stopOpacity="0.2" />
          <stop offset="100%" stopColor={col.b} stopOpacity="0" />
        </radialGradient>
        <filter id={id + "-soft"} x="-40%" y="-40%" width="180%" height="180%">
          <feGaussianBlur stdDeviation="14" />
        </filter>
      </React.Fragment>
    ),
    body: (
      <React.Fragment>
        <g filter={"url(#" + id + "-soft)"}>
          {orbs.map((o, i) => (
            <circle key={i} cx={o.cx} cy={o.cy} r={o.r}
              fill={"url(#" + id + "-g" + o.fill + ")"} opacity={o.o} />
          ))}
        </g>
        <g fill={col.a} opacity="0.5">
          {dots.map((d, i) => <circle key={i} cx={d.x} cy={d.y} r={d.r} />)}
        </g>
      </React.Fragment>
    ),
  };
}

function motifOrbit(id, rnd, col) {
  const cx = 470, cy = 300;
  const rings = [60, 120, 185, 255, 330];
  const fan = [];
  for (let i = 0; i < 13; i++) {
    const ang = (Math.PI * 1.05) + (i / 12) * (Math.PI * 0.95);
    fan.push({ x: cx + Math.cos(ang) * 360, y: cy + Math.sin(ang) * 360 });
  }
  const nodes = rings.map((r, i) => {
    const ang = Math.PI + rnd() * Math.PI * 0.9;
    return { x: cx + Math.cos(ang) * r, y: cy + Math.sin(ang) * r, big: i % 2 === 0 };
  });
  return {
    defs: (
      <radialGradient id={id + "-glow"} cx="78%" cy="80%" r="60%">
        <stop offset="0%" stopColor={col.b} stopOpacity="0.5" />
        <stop offset="100%" stopColor={col.b} stopOpacity="0" />
      </radialGradient>
    ),
    body: (
      <React.Fragment>
        <rect x="0" y="0" width="600" height="375" fill={"url(#" + id + "-glow)"} />
        <g stroke={col.a} fill="none" opacity="0.32" strokeWidth="1">
          {fan.map((p, i) => <line key={i} x1={cx} y1={cy} x2={p.x} y2={p.y} />)}
        </g>
        <g stroke={col.a} fill="none" strokeWidth="1.2">
          {rings.map((r, i) => <circle key={i} cx={cx} cy={cy} r={r} opacity={0.5 - i * 0.06} />)}
        </g>
        <g fill={col.b}>
          {nodes.map((nd, i) => <circle key={i} cx={nd.x} cy={nd.y} r={nd.big ? 4.5 : 2.6} />)}
        </g>
        <circle cx={cx} cy={cy} r="6" fill={col.a} />
      </React.Fragment>
    ),
  };
}

function motifGrid(id, rnd, col) {
  const hzY = 150, vx = 300;
  const verts = [];
  for (let i = -7; i <= 7; i++) {
    verts.push({ x1: vx + i * 22, y1: hzY, x2: vx + i * 95, y2: 400 });
  }
  const horis = [];
  for (let i = 1; i <= 9; i++) {
    const t = i / 10;
    horis.push(hzY + Math.pow(t, 1.9) * 250);
  }
  return {
    defs: (
      <React.Fragment>
        <linearGradient id={id + "-fade"} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={col.a} stopOpacity="0" />
          <stop offset="40%" stopColor={col.a} stopOpacity="0.5" />
          <stop offset="100%" stopColor={col.a} stopOpacity="0.12" />
        </linearGradient>
        <radialGradient id={id + "-sun"} cx="50%" cy="40%" r="42%">
          <stop offset="0%" stopColor={col.b} stopOpacity="0.55" />
          <stop offset="100%" stopColor={col.b} stopOpacity="0" />
        </radialGradient>
      </React.Fragment>
    ),
    body: (
      <React.Fragment>
        <rect x="0" y="0" width="600" height="375" fill={"url(#" + id + "-sun)"} />
        <g stroke={"url(#" + id + "-fade)"} strokeWidth="1" fill="none">
          {verts.map((v, i) => <line key={i} x1={v.x1} y1={v.y1} x2={v.x2} y2={v.y2} />)}
          {horis.map((y, i) => <line key={"h" + i} x1="0" y1={y} x2="600" y2={y} opacity={0.25 + i * 0.06} />)}
        </g>
        <line x1="0" y1={hzY} x2="600" y2={hzY} stroke={col.b} strokeWidth="1.4" opacity="0.7" />
      </React.Fragment>
    ),
  };
}

function motifInterfere(id, rnd, col) {
  const a = { x: 195, y: 165 }, b = { x: 410, y: 215 };
  const ringsA = [], ringsB = [];
  for (let i = 1; i <= 9; i++) { ringsA.push(i * 26); ringsB.push(i * 26); }
  return {
    defs: null,
    body: (
      <React.Fragment>
        <g stroke={col.a} fill="none" strokeWidth="1">
          {ringsA.map((r, i) => <circle key={i} cx={a.x} cy={a.y} r={r} opacity={0.42 - i * 0.035} />)}
        </g>
        <g stroke={col.b} fill="none" strokeWidth="1">
          {ringsB.map((r, i) => <circle key={i} cx={b.x} cy={b.y} r={r} opacity={0.42 - i * 0.035} />)}
        </g>
        <circle cx={a.x} cy={a.y} r="4.5" fill={col.a} />
        <circle cx={b.x} cy={b.y} r="4.5" fill={col.b} />
      </React.Fragment>
    ),
  };
}

function motifLoop(id, rnd, col) {
  const cx = 300, cy = 188, r = 110;
  // an almost-complete ring with a gap (the unclosed argument)
  const gap = 0.42; // radians of opening
  const start = -Math.PI / 2 + gap / 2;
  const end = -Math.PI / 2 - gap / 2 + Math.PI * 2;
  const x1 = cx + Math.cos(start) * r, y1 = cy + Math.sin(start) * r;
  const x2 = cx + Math.cos(end) * r, y2 = cy + Math.sin(end) * r;
  const d = "M " + x1 + " " + y1 + " A " + r + " " + r + " 0 1 1 " + x2 + " " + y2;
  return {
    defs: (
      <radialGradient id={id + "-c"} cx="50%" cy="50%" r="50%">
        <stop offset="0%" stopColor={col.a} stopOpacity="0.4" />
        <stop offset="100%" stopColor={col.a} stopOpacity="0" />
      </radialGradient>
    ),
    body: (
      <React.Fragment>
        <circle cx={cx} cy={cy} r={r + 30} fill={"url(#" + id + "-c)"} />
        <circle cx={cx + 18} cy={cy + 14} r={r} fill="none" stroke={col.b} strokeWidth="1" opacity="0.28" />
        <path d={d} fill="none" stroke={col.a} strokeWidth="2" strokeLinecap="round" opacity="0.92" />
        <circle cx={x1} cy={y1} r="4.5" fill={col.a} />
        <circle cx={x2} cy={y2} r="3" fill={col.b} opacity="0.8" />
      </React.Fragment>
    ),
  };
}

function motifField(id, rnd, col) {
  // streamlines flowing down toward a basin (gradient descent)
  const basin = { x: 330, y: 330 };
  const lines = [];
  for (let i = 0; i < 16; i++) {
    const sx = i * 40 - 20;
    const sy = 30 + rnd() * 40;
    const c1x = sx + 60, c1y = sy + 120;
    const ex = basin.x + (rnd() - 0.5) * 70;
    const ey = basin.y - 6 - rnd() * 14;
    lines.push("M " + sx + " " + sy + " C " + c1x + " " + c1y + " " + (ex - 60) + " " + (ey - 40) + " " + ex + " " + ey);
  }
  return {
    defs: (
      <radialGradient id={id + "-basin"} cx="55%" cy="88%" r="48%">
        <stop offset="0%" stopColor={col.b} stopOpacity="0.6" />
        <stop offset="100%" stopColor={col.b} stopOpacity="0" />
      </radialGradient>
    ),
    body: (
      <React.Fragment>
        <rect x="0" y="0" width="600" height="375" fill={"url(#" + id + "-basin)"} />
        <g stroke={col.a} fill="none" strokeWidth="1">
          {lines.map((d, i) => <path key={i} d={d} opacity={0.2 + (i % 5) * 0.07} />)}
        </g>
        <circle cx={basin.x} cy={basin.y} r="5" fill={col.a} />
      </React.Fragment>
    ),
  };
}

function motifLattice(id, rnd, col) {
  const nodes = [];
  for (let i = 0; i < 11; i++) nodes.push({ x: 60 + rnd() * 480, y: 50 + rnd() * 275 });
  const edges = [];
  for (let i = 0; i < nodes.length; i++) {
    for (let j = i + 1; j < nodes.length; j++) {
      const dx = nodes[i].x - nodes[j].x, dy = nodes[i].y - nodes[j].y;
      if (Math.sqrt(dx * dx + dy * dy) < 175) edges.push([i, j]);
    }
  }
  return {
    defs: (
      <radialGradient id={id + "-g"} cx="40%" cy="35%" r="60%">
        <stop offset="0%" stopColor={col.b} stopOpacity="0.4" />
        <stop offset="100%" stopColor={col.b} stopOpacity="0" />
      </radialGradient>
    ),
    body: (
      <React.Fragment>
        <rect x="0" y="0" width="600" height="375" fill={"url(#" + id + "-g)"} />
        <g stroke={col.a} strokeWidth="1" opacity="0.3">
          {edges.map((e, i) => (
            <line key={i} x1={nodes[e[0]].x} y1={nodes[e[0]].y} x2={nodes[e[1]].x} y2={nodes[e[1]].y} />
          ))}
        </g>
        <g>
          {nodes.map((nd, i) => (
            <circle key={i} cx={nd.x} cy={nd.y} r={i % 3 === 0 ? 5 : 3}
              fill={i % 3 === 0 ? col.b : col.a} opacity={i % 3 === 0 ? 1 : 0.75} />
          ))}
        </g>
      </React.Fragment>
    ),
  };
}

function motifStrata(id, rnd, col) {
  // stacked topographic contour bands
  const bands = [];
  const count = 6;
  for (let b = 0; b < count; b++) {
    const baseY = 70 + b * 48;
    const amp = 16 + rnd() * 16;
    const phase = rnd() * 6.28;
    let d = "M 0 " + (baseY + Math.sin(phase) * amp);
    for (let x = 60; x <= 600; x += 60) {
      d += " Q " + (x - 30) + " " + (baseY + Math.sin(phase + x / 70) * amp) + " " + x + " " + (baseY + Math.sin(phase + x / 55) * amp);
    }
    bands.push({ d, b });
  }
  return {
    defs: (
      <linearGradient id={id + "-band"} x1="0" y1="0" x2="1" y2="0">
        <stop offset="0%" stopColor={col.a} stopOpacity="0.7" />
        <stop offset="100%" stopColor={col.b} stopOpacity="0.7" />
      </linearGradient>
    ),
    body: (
      <g fill="none" stroke={"url(#" + id + "-band)"} strokeWidth="1.4">
        {bands.map((bd, i) => <path key={i} d={bd.d} opacity={0.3 + bd.b * 0.1} />)}
      </g>
    ),
  };
}

const MOTIF_FN = {
  bloom: motifBloom, orbit: motifOrbit, grid: motifGrid, interfere: motifInterfere,
  loop: motifLoop, field: motifField, lattice: motifLattice, strata: motifStrata,
};

function CoverArt({ slug, variant }) {
  const meta = artMeta(slug);
  const col = artColors(meta.t);
  const id = "ca-" + (slug || "x").replace(/[^a-z0-9]/gi, "").slice(0, 24);
  const rnd = artRng(artHash(slug || "x"));
  const fn = MOTIF_FN[meta.m] || motifBloom;
  const { defs, body } = fn(id, rnd, col);
  return (
    <svg
      className={"coverart coverart--" + meta.m + (variant ? " coverart--" + variant : "")}
      viewBox="0 0 600 375" preserveAspectRatio="xMidYMid slice"
      role="img" aria-hidden="true" focusable="false">
      <defs>
        <linearGradient id={id + "-bg"} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="var(--bg-soft)" />
          <stop offset="100%" stopColor="var(--bg-elev)" />
        </linearGradient>
        {defs}
      </defs>
      <rect x="0" y="0" width="600" height="375" fill={"url(#" + id + "-bg)"} />
      {body}
    </svg>
  );
}

Object.assign(window, { CoverArt });
