// Prima — animated in-chat loader (v1)
// Three variants: "reasoning" (default), "indexing", "drafting" — plus a large "hero" layered version.
// Drop-in for front_end_v1: exposes <PrimaLoader /> on window; also mounts a hidden #prima-mark <defs>
// symbol on first render so any <svg><use href="#prima-mark" /></svg> elsewhere reuses the same artwork.
//
// Usage in the chat screen:
//   <PrimaLoader />                                    // default reasoning + caption + typing dots
//   <PrimaLoader variant="indexing" />                 // slow, ambient-glow — for ingestion
//   <PrimaLoader variant="drafting" />                 // reverse breathing — long deep-report generations
//   <PrimaLoader variant="hero" caption="Prima is thinking…" sublabel="Reasoning across 12 sources" />
//   <PrimaLoader size={48} bare />                     // just the spinning mandala, no chrome

// ── Hidden mandala symbol (mounted once) ──────────────────────────────────
const PRIMA_MARK_SYMBOL = "<symbol id=\"prima-mark\" viewBox=\"0 0 100 100\" overflow=\"visible\">\n      <g fill=\"none\" stroke=\"currentColor\" stroke-linejoin=\"round\" stroke-linecap=\"round\">\n        <path d=\"M 50.00 5.00 L 92.80 63.91 L 23.55 86.41 L 23.55 13.59 L 92.80 36.09 L 50.00 95.00 L 7.20 36.09 L 76.45 13.59 L 76.45 86.41 L 7.20 63.91 Z\" stroke-width=\"1.1\"></path>\n        <path d=\"M 59.89 19.57 L 75.89 68.81 L 24.11 68.81 L 40.11 19.57 L 82.00 50.00 L 40.11 80.43 L 24.11 31.19 L 75.89 31.19 L 59.89 80.43 L 18.00 50.00 Z\" stroke-width=\"0.9\" opacity=\"0.85\"></path>\n        <path d=\"M 50.00 5.00 L 76.45 13.59 L 92.80 36.09 L 92.80 63.91 L 76.45 86.41 L 50.00 95.00 L 23.55 86.41 L 7.20 63.91 L 7.20 36.09 L 23.55 13.59 Z\" stroke-width=\"0.55\" opacity=\"0.5\"></path>\n        <path d=\"M 50.00 32.00 L 60.58 35.44 L 67.12 44.44 L 67.12 55.56 L 60.58 64.56 L 50.00 68.00 L 39.42 64.56 L 32.88 55.56 L 32.88 44.44 L 39.42 35.44 Z\" stroke-width=\"0.55\" opacity=\"0.55\"></path>\n        <path d=\"M 50 50 L 50.00 5.00 M 50 50 L 76.45 13.59 M 50 50 L 92.80 36.09 M 50 50 L 92.80 63.91 M 50 50 L 76.45 86.41 M 50 50 L 50.00 95.00 M 50 50 L 23.55 86.41 M 50 50 L 7.20 63.91 M 50 50 L 7.20 36.09 M 50 50 L 23.55 13.59\" stroke-width=\"0.3\" opacity=\"0.35\"></path>\n        <path d=\"M 50.00 32.00 L 59.89 19.57 M 60.58 35.44 L 75.89 31.19 M 67.12 44.44 L 82.00 50.00 M 67.12 55.56 L 75.89 68.81 M 60.58 64.56 L 59.89 80.43 M 50.00 68.00 L 40.11 80.43 M 39.42 64.56 L 24.11 68.81 M 32.88 55.56 L 18.00 50.00 M 32.88 44.44 L 24.11 31.19 M 39.42 35.44 L 40.11 19.57\" stroke-width=\"0.3\" opacity=\"0.45\"></path>\n      </g>\n      <g fill=\"currentColor\">\n        <circle cx=\"50\" cy=\"5\" r=\"1.5\"></circle><circle cx=\"76.45\" cy=\"13.59\" r=\"1.4\"></circle><circle cx=\"92.80\" cy=\"36.09\" r=\"1.4\"></circle><circle cx=\"92.80\" cy=\"63.91\" r=\"1.4\"></circle><circle cx=\"76.45\" cy=\"86.41\" r=\"1.4\"></circle><circle cx=\"50\" cy=\"95\" r=\"1.5\"></circle><circle cx=\"23.55\" cy=\"86.41\" r=\"1.4\"></circle><circle cx=\"7.20\" cy=\"63.91\" r=\"1.4\"></circle><circle cx=\"7.20\" cy=\"36.09\" r=\"1.4\"></circle><circle cx=\"23.55\" cy=\"13.59\" r=\"1.4\"></circle>\n        <circle cx=\"59.89\" cy=\"19.57\" r=\"1\"></circle><circle cx=\"75.89\" cy=\"31.19\" r=\"1\"></circle><circle cx=\"82\" cy=\"50\" r=\"1\"></circle><circle cx=\"75.89\" cy=\"68.81\" r=\"1\"></circle><circle cx=\"59.89\" cy=\"80.43\" r=\"1\"></circle><circle cx=\"40.11\" cy=\"80.43\" r=\"1\"></circle><circle cx=\"24.11\" cy=\"68.81\" r=\"1\"></circle><circle cx=\"18\" cy=\"50\" r=\"1\"></circle><circle cx=\"24.11\" cy=\"31.19\" r=\"1\"></circle><circle cx=\"40.11\" cy=\"19.57\" r=\"1\"></circle>\n        <circle cx=\"50\" cy=\"32\" r=\"0.9\"></circle><circle cx=\"60.58\" cy=\"35.44\" r=\"0.9\"></circle><circle cx=\"67.12\" cy=\"44.44\" r=\"0.9\"></circle><circle cx=\"67.12\" cy=\"55.56\" r=\"0.9\"></circle><circle cx=\"60.58\" cy=\"64.56\" r=\"0.9\"></circle><circle cx=\"50\" cy=\"68\" r=\"0.9\"></circle><circle cx=\"39.42\" cy=\"64.56\" r=\"0.9\"></circle><circle cx=\"32.88\" cy=\"55.56\" r=\"0.9\"></circle><circle cx=\"32.88\" cy=\"44.44\" r=\"0.9\"></circle><circle cx=\"39.42\" cy=\"35.44\" r=\"0.9\"></circle>\n      </g>\n      <circle cx=\"50\" cy=\"50\" r=\"4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.8\"></circle>\n      <circle cx=\"50\" cy=\"50\" r=\"1.6\" fill=\"currentColor\"></circle>\n    </symbol>";

const PrimaMarkDefs = () => {
  React.useEffect(() => {
    if (document.getElementById("prima-mark-defs-root")) return;
    const holder = document.createElement("div");
    holder.id = "prima-mark-defs-root";
    holder.setAttribute("aria-hidden", "true");
    holder.style.cssText = "position:absolute; width:0; height:0; overflow:hidden;";
    holder.innerHTML = "<svg width=\"0\" height=\"0\"><defs>" + PRIMA_MARK_SYMBOL + "</defs></svg>";
    document.body.appendChild(holder);
  }, []);
  return null;
};

// ── Scoped stylesheet (mounted once) ──────────────────────────────────────
const PRIMA_LOADER_CSS = "@keyframes primaSpinSlow { to { transform:rotate(360deg); } }\n@keyframes primaSpinRev  { to { transform:rotate(-360deg); } }\n@keyframes primaSpinFast { to { transform:rotate(360deg); } }\n@keyframes primaPulse    { 0%,100%{transform:scale(1);} 50%{transform:scale(1.06);} }\n@keyframes primaGlow     { 0%,100%{opacity:0.55;} 50%{opacity:1;} }\n@keyframes primaSparkle  { 0%,100%{opacity:0.5;} 50%{opacity:1;} }\n@keyframes primaTyping   { 0%,60%,100%{opacity:0.3; transform:translateY(0);} 30%{opacity:1; transform:translateY(-3px);} }\n.prima-loader-inner-spin { animation:primaSpinFast 9s linear infinite, primaPulse 2.6s ease-in-out infinite; }\n.prima-loader-shell { position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:24px; }\n.prima-loader-shell.on-dark  { color:#F6EFE2; }\n.prima-loader-shell.on-light { color:#3E0E0E; }\n@media (prefers-reduced-motion: reduce) { .prima-loader-shell *, .prima-mandala * { animation:none !important; } }";
const PrimaLoaderStyles = () => {
  React.useEffect(() => {
    if (document.getElementById("prima-loader-styles")) return;
    const s = document.createElement("style");
    s.id = "prima-loader-styles";
    s.textContent = PRIMA_LOADER_CSS;
    document.head.appendChild(s);
  }, []);
  return null;
};

// ── Variant configs ──────────────────────────────────────────────────────
// `speed` is a duration multiplier applied to the whole mandala (1 = reasoning pace).
const VARIANTS = {
  reasoning: { speed: 1 },
  indexing:  { speed: 1.8 },
  drafting:  { speed: 2.4 },
};

// ── Layered mandala (finalized "3A": two counter-rotating rings + breathing
// + three sparks orbiting the gap between them). Sparks auto-hide below 64px
// where they'd read as noise; prefers-reduced-motion freezes everything.
// theme="dark" (cream/rose, for maroon backgrounds) | "light" (maroon family,
// for the cream chat stream).
const MANDALA_TONES = {
  dark:  { outer: "#E9B8B8", outerOp: 0.45, inner: "#F6EFE2", innerShadow: "rgba(246,239,226,0.65)",
           glowBg: "radial-gradient(circle, rgba(223,69,69,0.28) 0%, rgba(223,69,69,0) 65%)",
           sparks: [["#E6C277", "rgba(230,194,119,0.75)"], ["#E9B8B8", "rgba(233,184,184,0.65)"], ["#F4C8A6", "rgba(244,200,166,0.6)"]] },
  light: { outer: "#B0625F", outerOp: 0.55, inner: "#7A1C1C", innerShadow: "rgba(122,28,28,0.3)",
           glowBg: "radial-gradient(circle, rgba(122,28,28,0.12) 0%, rgba(122,28,28,0) 65%)",
           sparks: [["#B9862E", "rgba(185,134,46,0.55)"], ["#A0524F", "rgba(160,82,79,0.5)"], ["#C98A6A", "rgba(201,138,106,0.5)"]] },
};
const PrimaMandala = ({ size = 120, speed = 1, glow = true, theme = "dark", style = {} }) => {
  const tone = MANDALA_TONES[theme] || MANDALA_TONES.dark;
  const inner = Math.round(size * 0.55);
  const pad = Math.round((size - inner) / 2);
  const inset = Math.round(size * 0.11);
  const showSparks = size >= 64;
  const dur = (s) => (s * speed).toFixed(1) + "s";
  const sparks = [
    // Halved in step with the rings below — the sparks orbit the gap between them, so
    // they have to keep pace or the composition comes apart at hero size.
    { anim: "primaSpinFast " + dur(4.5) + " linear infinite", color: tone.sparks[0][0], d: Math.max(4, size * 0.025), sh: tone.sparks[0][1], bottom: false },
    { anim: "primaSpinRev "  + dur(7)   + " linear infinite", color: tone.sparks[1][0], d: Math.max(3.5, size * 0.021), sh: tone.sparks[1][1], bottom: false },
    { anim: "primaSpinFast " + dur(10.5)+ " linear infinite", color: tone.sparks[2][0], d: Math.max(3, size * 0.017), sh: tone.sparks[2][1], bottom: true },
  ];
  return (
    <div className="prima-mandala" aria-hidden="true"
         style={{ position: "relative", width: size, height: size, ...style }}>
      {glow && (
        <div style={{
          position: "absolute", inset: "-8%", borderRadius: "50%",
          background: tone.glowBg,
          filter: "blur(5px)", animation: "primaGlow " + dur(3.6) + " ease-in-out infinite",
        }} />
      )}
      <div style={{ position: "absolute", inset: 0, animation: "primaPulse " + dur(3.2) + " ease-in-out infinite" }}>
        {/* Rotation only — the pulse/glow breathing above is deliberately left slower.
            28s/11s read as static at the 38px in-chat size (the loader this replaced ran
            at 2.5s); halved, the inner ring turns visibly while the outer stays ambient
            and the ~2.5:1 ratio that makes them read as two distinct rings is kept. */}
        <svg width={size} height={size} style={{ position: "absolute", inset: 0, color: tone.outer,
          opacity: tone.outerOp, animation: "primaSpinSlow " + dur(14) + " linear infinite" }}>
          <use href="#prima-mark" />
        </svg>
        <svg width={inner} height={inner} style={{ position: "absolute", top: pad, left: pad, color: tone.inner,
          filter: "drop-shadow(0 0 " + Math.round(size * 0.05) + "px " + tone.innerShadow + ")",
          animation: "primaSpinRev " + dur(5.5) + " linear infinite" }}>
          <use href="#prima-mark" />
        </svg>
        {showSparks && sparks.map((sp, i) => (
          <div key={i} style={{ position: "absolute", inset: inset, animation: sp.anim }}>
            <span style={{
              position: "absolute", left: "calc(50% - " + sp.d / 2 + "px)",
              [sp.bottom ? "bottom" : "top"]: -sp.d / 2,
              width: sp.d, height: sp.d, borderRadius: "50%", background: sp.color,
              boxShadow: "0 0 " + Math.round(sp.d * 1.6) + "px " + Math.round(sp.d * 0.4) + "px " + sp.sh,
            }} />
          </div>
        ))}
      </div>
    </div>
  );
};

// ── Small typing-dots component ──────────────────────────────────────────
const TypingDots = ({ color = "#E6C277" }) => (
  <div style={{ display: "flex", gap: 8 }}>
    {[0, 0.2, 0.4].map((d, i) => (
      <span key={i} style={{
        width: 6, height: 6, borderRadius: "50%", background: color,
        animation: "primaTyping 1.4s infinite " + d + "s",
      }} />
    ))}
  </div>
);

// ── Main <PrimaLoader /> ─────────────────────────────────────────────────
const PrimaLoader = ({
  variant = "reasoning",         // "reasoning" | "indexing" | "drafting" | "hero"
  size = 120,                    // px — mandala diameter (ignored when variant="hero")
  caption,                       // main line
  sublabel,                      // secondary line
  showDots = true,               // typing dots below caption
  bare = false,                  // return just the animated mandala, no text/chrome
  theme = "dark",                // "dark" | "light" — sets caption colour
  style = {},
}) => {
  // Hero variant: three layered mandalas + ambient glow
  if (variant === "hero") {
    return (
      <>
        <PrimaMarkDefs />
        <PrimaLoaderStyles />
        <div className={"prima-loader-shell " + (theme === "light" ? "on-light" : "on-dark")}
             style={{ minHeight: 420, gap: 24, ...style }}>
          <div aria-hidden="true" style={{
            position: "absolute", width: 340, height: 340, borderRadius: "50%",
            background: "radial-gradient(circle at 50% 50%, rgba(223,69,69,0.35) 0%, rgba(223,69,69,0) 65%)",
            filter: "blur(6px)", animation: "primaGlow 3.6s ease-in-out infinite",
          }} />
          <div style={{ position: "relative", width: 260, height: 260 }}>
            <svg width="260" height="260" style={{ position: "absolute", inset: 0, color: "#E9B8B8",
              filter: "drop-shadow(0 0 18px rgba(240,160,160,0.5))",
              animation: "primaSpinSlow 22s linear infinite" }}>
              <use href="#prima-mark" />
            </svg>
            <svg width="200" height="200" style={{ position: "absolute", top: 30, left: 30, color: "#F4C8A6",
              opacity: 0.75, filter: "drop-shadow(0 0 12px rgba(255,180,140,0.45))",
              animation: "primaSpinRev 14s linear infinite" }}>
              <use href="#prima-mark" />
            </svg>
            <svg width="120" height="120" className="prima-loader-inner-spin"
                 style={{ position: "absolute", top: 70, left: 70, color: "#F6EFE2",
                          filter: "drop-shadow(0 0 14px rgba(246,239,226,0.7))" }}>
              <use href="#prima-mark" />
            </svg>
          </div>
          {(caption || sublabel) && (
            <div style={{ textAlign: "center", position: "relative" }}>
              {caption && (
                <div style={{
                  fontFamily: "Fraunces, Georgia, serif", fontSize: 22, fontWeight: 500,
                  color: theme === "light" ? "#3E0E0E" : "#F6EFE2",
                  letterSpacing: "-0.01em", marginBottom: 6,
                }}>{caption}</div>
              )}
              {sublabel && (
                <div style={{
                  fontSize: 12.5,
                  color: theme === "light" ? "#4A423B" : "rgba(240,233,222,0.65)",
                  letterSpacing: "0.02em",
                }}>{sublabel}</div>
              )}
            </div>
          )}
          {showDots && <TypingDots />}
        </div>
      </>
    );
  }

  // Compact variants (reasoning / indexing / drafting)
  const cfg = VARIANTS[variant] || VARIANTS.reasoning;

  if (bare) {
    return (
      <>
        <PrimaMarkDefs />
        <PrimaLoaderStyles />
        <PrimaMandala size={size} speed={cfg.speed} glow={false} theme={theme} style={style} />
      </>
    );
  }

  return (
    <>
      <PrimaMarkDefs />
      <PrimaLoaderStyles />
      <div className={"prima-loader-shell " + (theme === "light" ? "on-light" : "on-dark")}
           style={{ gap: 16, ...style }}>
        <PrimaMandala size={size} speed={cfg.speed} theme={theme} />
        {(caption || sublabel) && (
          <div style={{ textAlign: "center" }}>
            {caption && (
              <div style={{
                fontFamily: "Fraunces, Georgia, serif", fontSize: 17, fontWeight: 500,
                color: theme === "light" ? "#3E0E0E" : "#F6EFE2",
                letterSpacing: "-0.01em", marginBottom: 4,
              }}>{caption}</div>
            )}
            {sublabel && (
              <div style={{
                fontSize: 12,
                color: theme === "light" ? "#4A423B" : "rgba(240,233,222,0.65)",
              }}>{sublabel}</div>
            )}
          </div>
        )}
        {showDots && <TypingDots color={theme === "light" ? "#7A1C1C" : "#E6C277"} />}
      </div>
    </>
  );
};

// ── Expose on window ─────────────────────────────────────────────────────
Object.assign(window, { PrimaLoader, PrimaMandala });