/* ===========================================================================
   components.jsx — shared UI primitives + icon set (exported to window)
   =========================================================================== */
const { useState, useEffect, useRef } = React;

/* ---- Icon set (groovy line icons) -------------------------------------- */
function Icon({ name, size = 18, stroke = 2.2, style }) {
  const p = {
    width: size, height: size, viewBox: "0 0 24 24", fill: "none",
    stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round",
    strokeLinejoin: "round", style,
  };
  switch (name) {
    case "dashboard": return (<svg {...p}><rect x="3" y="3" width="7" height="9" rx="1.5"/><rect x="14" y="3" width="7" height="5" rx="1.5"/><rect x="14" y="12" width="7" height="9" rx="1.5"/><rect x="3" y="16" width="7" height="5" rx="1.5"/></svg>);
    case "spy": return (<svg {...p}><circle cx="7" cy="13" r="3.2"/><circle cx="17" cy="13" r="3.2"/><path d="M10.2 13c.6-1 3-1 3.6 0M2.5 9.5l3-2.5h13l3 2.5"/></svg>);
    case "grid": return (<svg {...p}><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg>);
    case "hook": return (<svg {...p}><path d="M14 4h4v4M18 4l-7 7M11 6H7a3 3 0 0 0-3 3v7a3 3 0 0 0 3 3h7a3 3 0 0 0 3-3v-4"/></svg>);
    case "angle": return (<svg {...p}><path d="M4 20V5M4 20h16M4 9l5 4 4-5 7 6"/></svg>);
    case "trophy": return (<svg {...p}><path d="M7 4h10v4a5 5 0 0 1-10 0V4ZM7 6H4v1a3 3 0 0 0 3 3M17 6h3v1a3 3 0 0 1-3 3M9 14.5V18M15 14.5V18M8 18h8"/></svg>);
    case "script": return (<svg {...p}><path d="M8 3h8a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2ZM9 8h6M9 12h6M9 16h3"/></svg>);
    case "sparkle": return (<svg {...p}><path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8L12 3ZM18 16l.8 2.2L21 19l-2.2.8L18 22l-.8-2.2L15 19l2.2-.8L18 16Z"/></svg>);
    case "search": return (<svg {...p}><circle cx="11" cy="11" r="7"/><path d="M21 21l-4-4"/></svg>);
    case "play": return (<svg {...p} fill="currentColor" stroke="none"><path d="M8 5.5v13l11-6.5-11-6.5Z"/></svg>);
    case "arrow": return (<svg {...p}><path d="M5 12h14M13 6l6 6-6 6"/></svg>);
    case "arrowLeft": return (<svg {...p}><path d="M19 12H5M11 6l-6 6 6 6"/></svg>);
    case "bolt": return (<svg {...p}><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg>);
    case "flame": return (<svg {...p}><path d="M12 3s5 4 5 9a5 5 0 0 1-10 0c0-1.5.6-2.8 1.4-3.8C9 10 9.5 11 10 11.5 10 9 11 5 12 3Z"/></svg>);
    case "clock": return (<svg {...p}><circle cx="12" cy="12" r="8"/><path d="M12 8v4l3 2"/></svg>);
    case "video": return (<svg {...p}><rect x="3" y="6" width="13" height="12" rx="2"/><path d="m16 10 5-3v10l-5-3"/></svg>);
    case "image": return (<svg {...p}><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="8.5" cy="9.5" r="1.6"/><path d="m4 18 5-5 4 4 3-3 4 4"/></svg>);
    case "gap": return (<svg {...p}><path d="M12 3v6m0 6v6M3 12h6m6 0h6"/><circle cx="12" cy="12" r="2.5"/></svg>);
    case "check": return (<svg {...p}><path d="M5 12.5 10 17l9-10"/></svg>);
    case "x": return (<svg {...p}><path d="M6 6l12 12M18 6 6 18"/></svg>);
    case "trash": return (<svg {...p}><path d="M4 7h16M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2M6 7l1 13a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1l1-13M10 11v6M14 11v6"/></svg>);
    case "mushroom": return (<svg {...p}><path d="M4 11a8 8 0 0 1 16 0c0 1.1-.9 2-2 2H6c-1.1 0-2-.9-2-2Z"/><path d="M10 13c0 3 0 5-1 7h6c-1-2-1-4-1-7"/></svg>);
    case "trend": return (<svg {...p}><path d="M3 17l6-6 4 4 8-8M21 7h-5M21 7v5"/></svg>);
    case "wand": return (<svg {...p}><path d="M15 4V2M15 10V8M11 6H9M21 6h-2M6 21 18 9l-3-3L3 18l3 3ZM16 8l-1-1"/></svg>);
    case "download": return (<svg {...p}><path d="M12 4v12M7 11l5 5 5-5M5 20h14"/></svg>);
    default: return (<svg {...p}><circle cx="12" cy="12" r="9"/></svg>);
  }
}

/* ---- Universal download helper -------------------------------------- */
/* Cross-origin assets (Higgsfield/FB CDN) get proxied via /download so the
   browser actually downloads instead of opening in a new tab. */
function downloadHref(url) {
  if (!url) return "";
  if (/^https?:\/\//i.test(url)) {
    const parts = url.split("/");
    const filename = parts[parts.length - 1].split("?")[0] || "asset";
    return "download?u=" + encodeURIComponent(url) + "&name=" + encodeURIComponent(filename);
  }
  return url;
}
window.downloadHref = downloadHref;

/* ---- Logo mark (clean) ------------------------------------------------- */
function SporeMark({ size = 30 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 32 32" fill="none">
      <rect x="1" y="1" width="30" height="30" rx="8" fill="var(--accent)"/>
      <circle cx="16" cy="16" r="7" fill="none" stroke="#fff" strokeWidth="2.2"/>
      <circle cx="16" cy="16" r="2.4" fill="#fff"/>
    </svg>
  );
}

/* ---- Sunburst decoration ----------------------------------------------- */
function Sunburst({ size = 120, color = "#E5A828", opacity = 0.12 }) {
  const rays = [];
  for (let i = 0; i < 24; i++) {
    const a = (i / 24) * Math.PI * 2;
    rays.push(<line key={i} x1="50" y1="50" x2={50 + 50 * Math.cos(a)} y2={50 + 50 * Math.sin(a)} stroke={color} strokeWidth="4"/>);
  }
  return <svg width={size} height={size} viewBox="0 0 100 100" style={{ opacity }}>{rays}</svg>;
}

/* ---- Sparkline --------------------------------------------------------- */
function Spark({ data, color }) {
  const max = Math.max(...data);
  return (
    <div className="spark">
      {data.map((d, i) => (
        <span key={i} style={{ height: `${(d / max) * 100}%`, background: color || "var(--accent)" }}/>
      ))}
    </div>
  );
}

/* ---- Chip -------------------------------------------------------------- */
function Chip({ children, tone = "ghost", dot }) {
  return (
    <span className={`chip ${tone}`}>
      {dot && <span className="dot" style={{ background: dot }}/>}
      {children}
    </span>
  );
}

function LevelPill({ level }) {
  return <span className={`level-pill level-${level}`}>{level}</span>;
}

/* ---- Deterministic retro thumbnail backgrounds ------------------------- */
const THUMB_THEMES = [
  { bg: "#eef0fb", fg: "#2c3360", pat: "dots" },
  { bg: "#e9f6ef", fg: "#1f4633", pat: "dots" },
  { bg: "#faf2e0", fg: "#5a4413", pat: "dots" },
  { bg: "#f0ebfb", fg: "#3c2a5e", pat: "dots" },
  { bg: "#e8f0fb", fg: "#1f3d63", pat: "dots" },
  { bg: "#fbecea", fg: "#5e2723", pat: "dots" },
];
function themeFor(id) {
  let h = 0;
  for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) >>> 0;
  return THUMB_THEMES[h % THUMB_THEMES.length];
}
function PatternBG({ pat, fg }) {
  // subtle, clean dot texture regardless of requested pattern
  const c = [];
  for (let y = 0; y < 6; y++) for (let x = 0; x < 6; x++)
    c.push(<circle key={`${x}${y}`} cx={8 + x * 17} cy={8 + y * 17} r="1.6" fill={fg} opacity={0.07}/>);
  return <svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style={absFill}>{c}</svg>;
}
const absFill = { position: "absolute", inset: 0, width: "100%", height: "100%" };

/* short headline pulled from copy for thumbnail */
function headlineFor(ad) {
  const c = ad.copy;
  const first = c.split(/[.!?]/)[0];
  return first.length > 64 ? first.slice(0, 60).trim() + "…" : first;
}

/* ---- Match ring (radial) ----------------------------------------------- */
function MatchRing({ value }) {
  const r = 17, circ = 2 * Math.PI * r;
  return (
    <div className="match-ring">
      <svg width="46" height="46" viewBox="0 0 46 46">
        <circle cx="23" cy="23" r={r} fill="none" stroke="rgba(8,9,10,0.10)" strokeWidth="4"/>
        <circle cx="23" cy="23" r={r} fill="none" stroke="var(--accent)" strokeWidth="4" strokeLinecap="round"
          strokeDasharray={circ} strokeDashoffset={circ * (1 - value / 100)} transform="rotate(-90 23 23)"/>
        <text x="23" y="27" textAnchor="middle" fontFamily="var(--display)" fontWeight="700" fontSize="12" fill="var(--ink)">{value}</text>
      </svg>
      <div className="match-lab">match</div>
    </div>
  );
}

Object.assign(window, {
  Icon, SporeMark, Sunburst, Spark, Chip, LevelPill,
  PatternBG, themeFor, headlineFor, MatchRing, absFill,
});
