/* global React, GOLA, PinContext */
// =========================================================
// Raw Results tab — surfaces every relevant cut as evidence
// cards. Generative query bar (AI "researcher hat"), four cut
// families, Pin-to-Insights on each card. Reads shared PinStore.
// =========================================================

// ---- Shared bar viz (exported for the Insights tab too) ----
function EvBars({ bars, unit }) {
  const max = Math.max(...bars.map((b) => Math.abs(b.val)), 0.0001);
  const fmt = (v) => {
    if (unit === "%") return Math.round(v * 10) / 10 + "%";
    if (unit === "score") return Math.round(v * 10) / 10;
    if (unit === "pts") return (v >= 0 ? "+" : "") + (Math.round(v * 10) / 10).toFixed(1);
    return Math.round(v).toLocaleString();
  };
  const scale = (unit === "%" || unit === "score") ? (v) => Math.max(2, v) : (v) => Math.max(2, (Math.abs(v) / max) * 100);
  return (
    <div className="gl-bars">
      {bars.map((b, i) => (
        <div className="gl-bar" key={i}>
          <span className={"gl-bar__label" + (b.hi ? " is-hi" : "")} title={b.label}>{b.label}</span>
          <span className="gl-bar__track">
            <span className={"gl-bar__fill" + (b.hi ? " is-hi" : b.low ? " is-low" : "")} style={{ width: scale(b.val) + "%" }}></span>
          </span>
          <span className="gl-bar__val">{fmt(b.val)}</span>
        </div>
      ))}
    </div>
  );
}

// ---- Objectives left rail (shared, design-system nav) ----
function ObjRail({ activeObj, onPick, counts, hideAll }) {
  return (
    <aside className="gl-objrail">
      <div className="gl-objrail__label">Research objectives · gospel</div>
      {!hideAll && <button className={"gl-objrail__all" + (!activeObj ? " is-active" : "")} onClick={() => onPick(null)}>All evidence</button>}
      {GOLA.OBJECTIVES.map((o) => (
        <button
          key={o.id}
          className={"gl-objrail__item" + (activeObj === o.id ? " is-active" : "")}
          onClick={() => onPick(activeObj === o.id ? null : o.id)}
          title="Filter to this objective"
        >
          <span className="gl-objrail__num">Objective {o.id} · {o.short}</span>
          <span className="gl-objrail__text">{o.text}</span>
        </button>
      ))}
    </aside>
  );
}

// ---- Objectives anchor bar (legacy top banner — retained, unused) ----
function ObjBar({ activeObj, onPick, counts }) {
  return (
    <div className="gl-obj-bar">
      <div className="gl-obj-bar__lead">
        <span className="gl-obj-bar__lead-eyebrow">Brief · gospel</span>
        <span className="gl-obj-bar__lead-title">Gola Women's Sneaker Lab</span>
        <span className="gl-obj-bar__lead-sub">4 objectives · n = 785</span>
      </div>
      <div className="gl-obj-bar__items">
        {GOLA.OBJECTIVES.map((o) => (
          <div
            key={o.id}
            className={"gl-obj" + (activeObj === o.id ? " is-active" : "")}
            onClick={() => onPick(activeObj === o.id ? null : o.id)}
            title="Filter evidence to this objective"
          >
            <div className="gl-obj__num">Objective {o.id}</div>
            <div className="gl-obj__text">{o.text}</div>
            {counts && (
              <div className="gl-obj__count"><b>{counts[o.id] || 0}</b> pinned</div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

// ---- Generative query presets ----
const QUERY_PRESETS = [
  { q: "Which products should anchor the FW26 sell-in?",
    plan: "I'll score every SMU on a <b>0–100 sentiment score</b> (the P1 1–5 average, rescaled), then check whether the leaders hold across <b>retailer accounts</b> so the core is defensible in every deck.",
    cuts: ["Sentiment rank · overall", "Sentiment × Q2 retailer", "rank stability"], fams: ["cross"], objs: [2] },
  { q: "Is it the silhouette or the material that drives sentiment?",
    plan: "I'll hold silhouette constant and read <b>within-franchise sentiment spread</b> — comparing each variant's upper/material against its franchise siblings.",
    cuts: ["Sentiment × franchise", "top vs bottom variant", "material treatment"], fams: ["franchise"], objs: [3] },
  { q: "Do aspirational shoppers want different product?",
    plan: "I'll cut <b>P1 by retailer overlap</b> (Anthropologie / Free People / Madewell) and compare the segment's top-five against the overall top-five.",
    cuts: ["P1 × Q2 aspirational", "segment vs overall", "retailer union"], fams: ["buyer"], objs: [1, 4] },
  { q: "What's driving demand — and is it durable?",
    plan: "I'll pull <b>purchase motivation (Q6)</b>, <b>wear frequency (Q5)</b> and <b>pairs owned (Q4)</b> to test whether this is wardrobe behavior or replacement utility.",
    cuts: ["Q6 reason", "Q5 frequency", "Q4 pairs owned", "× age/gender"], fams: ["buyer", "segment"], objs: [1, 3] },
  { q: "Where is Gola's brand whitespace?",
    plan: "I'll compare <b>granted permission (Q17 credibility)</b> against <b>current association (Q15)</b> and consideration (Q16) to size the unactivated gap.",
    cuts: ["Q17 credibility", "Q15 association", "Q16 consideration"], fams: ["buyer", "segment"], objs: [4] },
];

// ---- Insight-grounded design feedback (for uploaded designs) ----
async function groundedDesignFeedback(query) {
  const insights = (window.GOLA && window.GOLA.INSIGHTS) || [];
  const summary = insights
    .map((i) => "- " + i.title + (i.action ? " (Action: " + i.action + ")" : ""))
    .join("\n");
  const ask = query || "What should I change about this design?";
  const prompt =
    "You are MakerSights AI advising a footwear designer who just uploaded a sneaker design they made and asked: \"" + ask + "\". " +
    "Using ONLY the brand's validated consumer-research insights below, give specific, actionable design feedback — 3 to 4 concrete changes covering things like upper/material treatment, silhouette choice, color or print, and which franchise to lean into. " +
    "Write plainly and directively for a designer: short sentences, no research jargon, no preamble. Format as bullet lines, each starting with \"• \" and separated by newlines.\n\n" +
    "Validated insights:\n" + summary;
  try {
    if (!window.claude || !window.claude.complete) throw new Error("no claude");
    const raw = await window.claude.complete(prompt);
    return {
      text: String(raw).trim(),
      confidence: "High",
      sources: ["Materialization spread", "Top-five SMU ranking", "Purchase-reason data"],
    };
  } catch (e) {
    return {
      text: "A few changes grounded in the research:\n• Make the upper material the hero — the same silhouette swings 12–19 points on fabric alone, so favor a clean twill or satin over mesh or heavy quilt.\n• Keep the shape close to a proven core (Hawk, Championship, Sprinter Reflect) — shoppers reward materialization, not brand-new silhouettes.\n• Lead with design detail and colorway — 59% buy for the look, not to replace a worn pair.\n• Steer away from mule and heavy-quilt directions; they sit consistently at the bottom of sentiment.",
      confidence: "Moderate",
      sources: ["Materialization spread", "Top-five SMU ranking"],
    };
  }
}

// ---- Reusable "Ask MakerLab" floating chat (used on Evidence + Insights) ----
const AskMakerLab = React.forwardRef(function AskMakerLab({ greeting, presets, onRun, badge, thinkingText, placeholder, dock, presetsFor, answerFor, greetingFor, activeItem, activeLabel }, ref) {
  const [panelOpen, setPanelOpen] = React.useState(false);
  const [query, setQuery] = React.useState("");
  const [thinking, setThinking] = React.useState(false);
  const [reviewing, setReviewing] = React.useState(false);
  const [attachment, setAttachment] = React.useState(null);
  const [pinned, setPinned] = React.useState(null);
  const [qlog, setQlog] = React.useState([{ role: "ai", text: greeting }]);
  const convoRef = React.useRef(null);
  const inputRef = React.useRef(null);
  const fileRef = React.useRef(null);

  React.useImperativeHandle(ref, () => ({
    openWith(item) {
      setPinned(item);
      setPanelOpen(true);
      setQlog([{ role: "ai", text: (greetingFor && item) ? greetingFor(item) : greeting }]);
    },
    open() { setPanelOpen(true); },
  }));

  function pinItem(item) {
    setPinned(item);
    setQlog([{ role: "ai", text: (greetingFor && item) ? greetingFor(item) : greeting }]);
  }
  function unpin() {
    setPinned(null);
    setQlog([{ role: "ai", text: greeting }]);
  }
  function runContext(preset) {
    setQlog((l) => [...l, { role: "user", text: preset.q }]);
    setThinking(true);
    setQuery("");
    setTimeout(() => {
      setThinking(false);
      const reply = answerFor ? answerFor(pinned, preset) : null;
      setQlog((l) => [...l, { role: "ai", ...(reply || { text: "" }) }]);
    }, 820);
  }
  React.useEffect(() => {
    if (convoRef.current) convoRef.current.scrollTop = convoRef.current.scrollHeight;
  }, [qlog.length, thinking]);
  React.useEffect(() => {
    if (panelOpen && inputRef.current) inputRef.current.focus({ preventScroll: true });
  }, [panelOpen]);

  function run(preset) {
    setQlog((l) => [...l, { role: "user", text: preset.q }]);
    setThinking(true);
    setQuery("");
    setTimeout(() => {
      setThinking(false);
      const reply = onRun ? onRun(preset) : null;
      setQlog((l) => [...l, { role: "ai", ...(reply || { plan: preset.plan, cuts: preset.cuts }) }]);
    }, 750);
  }
  function runFree() {
    const q = query.trim();
    if (!q && !attachment) return;
    const att = attachment;
    setQlog((l) => [...l, { role: "user", text: q, image: att ? att.url : null, fileName: att ? att.name : null }]);
    setQuery("");
    setAttachment(null);
    setThinking(true);
    if (att) {
      setReviewing(true);
      groundedDesignFeedback(q).then((reply) => {
        setThinking(false);
        setReviewing(false);
        setQlog((l) => [...l, { role: "ai", ...reply }]);
      });
    } else {
      setTimeout(() => {
        setThinking(false);
        const reply = (pinned && answerFor) ? answerFor(pinned, { q, free: true })
          : (onRun ? onRun({ q, free: true }) : null);
        setQlog((l) => [...l, { role: "ai", ...(reply || { plan: "", cuts: [] }) }]);
      }, 750);
    }
  }
  function handleFile(e) {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    const reader = new FileReader();
    reader.onload = () => setAttachment({ url: reader.result, name: f.name });
    reader.readAsDataURL(f);
    e.target.value = "";
  }

  return (
    <React.Fragment>
      {!panelOpen && (
        <button className="gl-fab" onClick={() => setPanelOpen(true)}>
          <span className="gl-fab__spark">✦</span>
          Ask MakerLab
          {badge && <span className="gl-fab__badge">{badge}</span>}
        </button>
      )}
      {panelOpen && (
        <div className={"gl-qpanel" + (dock ? " gl-qpanel--dock" : "")}>
          <div className="gl-qpanel__head">
            <span className="gl-fab__spark">✦</span>
            <span className="gl-qpanel__title">Ask MakerLab</span>
            <button className="gl-qpanel__x" onClick={() => setPanelOpen(false)} aria-label="Close">×</button>
          </div>
          {pinned ? (
            <div className="gl-ml-ctx">
              <span className="gl-ml-ctx__icon">✦</span>
              <div className="gl-ml-ctx__body">
                <div className="gl-ml-ctx__lab">Looking at this finding</div>
                <div className="gl-ml-ctx__title">{pinned.statement || pinned.title}</div>
              </div>
              <button className="gl-ml-ctx__x" onClick={unpin} aria-label="Unpin finding">×</button>
            </div>
          ) : (activeItem ? (
            <div className="gl-ml-view">
              <span className="gl-ml-view__lab">Viewing</span>
              <span className="gl-ml-view__txt">{activeLabel || activeItem.statement}</span>
              <button className="gl-ml-view__pin" onClick={() => pinItem(activeItem)}>✦ Ask about this</button>
            </div>
          ) : null)}
          <div className="gl-qconvo" ref={convoRef}>
            {qlog.map((m, i) => (
              m.role === "user" ? (
                <div className="gl-qmsg gl-qmsg--user" key={i}>
                  <div className="gl-qmsg__bub">
                    {m.image && <img className="gl-qmsg__img" src={m.image} alt={m.fileName || "upload"} />}
                    {m.text && <div>{m.text}</div>}
                  </div>
                </div>
              ) : (
                <div className="gl-qmsg" key={i}>
                  <span className="gl-qmsg__av">✦</span>
                  <div className={"gl-qmsg__bub" + (m.node ? " gl-qmsg__bub--wide" : "")}>
                    {m.text && <div>{m.text}</div>}
                    {m.node && m.node}
                    {m.plan && <div className="gl-qmsg__plan" dangerouslySetInnerHTML={{ __html: m.plan }}></div>}
                    {m.cuts && (
                      <div className="gl-genui__cuts" style={{ marginTop: 8 }}>
                        {m.cuts.map((c, j) => <span key={j} className="gl-genui__cut">{c}</span>)}
                      </div>
                    )}
                    {(m.confidence || m.sources) && (
                      <div className="gl-qmeta">
                        {m.confidence && (
                          <span className={"gl-qmeta__conf gl-qmeta__conf--" + m.confidence.toLowerCase()}>
                            <span className="gl-qmeta__dot"></span>{m.confidence} confidence
                          </span>
                        )}
                        {m.sources && m.sources.length > 0 && (
                          <span className="gl-qmeta__src">Based on {m.sources.join(" · ")}</span>
                        )}
                      </div>
                    )}
                  </div>
                </div>
              )
            ))}
            {thinking && (
              <div className="gl-qmsg">
                <span className="gl-qmsg__av">✦</span>
                <div className="gl-qmsg__bub"><span className="gl-shimmer">●●●</span> {reviewing ? "Reviewing your design against the research…" : thinkingText}</div>
              </div>
            )}
          </div>
          <div className="gl-qfoot">
            <div className="gl-qsuggest">
              {(pinned && presetsFor ? presetsFor(pinned) : presets).map((p, i) => (
                <button key={i} className={"gl-chip-q" + (pinned && presetsFor ? " gl-chip-q--ctx" : "")} onClick={() => (pinned && presetsFor ? runContext(p) : run(p))}>{p.q}</button>
              ))}
            </div>
            {attachment && (
              <div className="gl-qattach-preview">
                <img src={attachment.url} alt="" />
                <span className="gl-qattach-preview__name">{attachment.name}</span>
                <button onClick={() => setAttachment(null)} aria-label="Remove attachment">×</button>
              </div>
            )}
            <div className="gl-qinput">
              <input type="file" accept="image/*" ref={fileRef} style={{ display: "none" }} onChange={handleFile} />
              <button
                className="gl-qattach"
                onClick={() => fileRef.current && fileRef.current.click()}
                title="Attach a design or screenshot"
                aria-label="Attach image"
              >
                <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
              </button>
              <input
                ref={inputRef}
                className="gl-query__input"
                placeholder={attachment ? "Ask for feedback on your design…" : placeholder}
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                onKeyDown={(e) => { if (e.key === "Enter") runFree(); }}
              />
              <button className="gl-query__go" onClick={runFree} disabled={!query.trim() && !attachment}>Ask</button>
            </div>
          </div>
        </div>
      )}
    </React.Fragment>
  );
});

function RawLoop() {
  const store = React.useContext(PinContext);
  const [objFilter, setObjFilter] = React.useState(null);
  const [active, setActive] = React.useState(null); // active generative plan

  function handleRun(preset) {
    if (preset.free) {
      const fp = {
        q: preset.q,
        plan: "I'll put on my researcher hat: cut <b>sentiment</b> by the segments most relevant to that question, surface the <b>franchise spreads</b>, and flag any account differences worth a look.",
        cuts: ["Sentiment × relevant segments", "franchise drill-down", "account check"],
        fams: null, objs: null,
      };
      setActive(fp);
      return { plan: fp.plan, cuts: fp.cuts };
    }
    setActive(preset);
    return { plan: preset.plan, cuts: preset.cuts };
  }
  function clearQuery() { setActive(null); }

  // Filter evidence by active query + objective chip
  let shown = GOLA.EVIDENCE;
  if (active && active.fams) shown = shown.filter((e) => active.fams.includes(e.fam));
  if (active && active.objs) shown = shown.filter((e) => e.objs.some((o) => active.objs.includes(o)));
  if (objFilter) shown = shown.filter((e) => e.objs.includes(objFilter));

  const pinnedIds = new Set(store.insights.flatMap((i) => i.ev));
  const counts = {};
  pinnedIds.forEach((id) => {
    const card = GOLA.EV_INDEX[id];
    if (card) card.objs.forEach((o) => { counts[o] = (counts[o] || 0) + 1; });
  });

  return (
    <div className="gl gl-raw">
      <ObjRail activeObj={objFilter} onPick={setObjFilter} counts={counts} />
      <div className="gl-raw-main">
        {/* Selected-objective banner */}
        {objFilter && (() => {
          const o = GOLA.OBJECTIVES.find((x) => x.id === objFilter);
          return (
            <div className="gl-objbanner">
              <span className="gl-objbanner__num">Objective {o.id} · {o.short}</span>
              <span className="gl-objbanner__text">{o.text}</span>
            </div>
          );
        })()}
        {/* Active-cut banner (set from the floating Ask panel) */}
        {active && (
          <div className="gl-activecut">
            <span>Surfacing cuts for “{active.q}” · {shown.length} {shown.length === 1 ? "cut" : "cuts"}</span>
            <span className="gl-activecut__clear" onClick={clearQuery}>Clear</span>
          </div>
        )}

      {/* Evidence families */}
      {GOLA.FAMILIES.map((fam) => {
        const cards = shown.filter((e) => e.fam === fam.key);
        if (cards.length === 0) return null;
        return (
          <div key={fam.key}>
            <div className="gl-fam">
              <span className="gl-fam__glyph">{fam.glyph}</span>
              <span className="gl-fam__title">{fam.title}</span>
              <span className="gl-fam__sub">· {fam.sub}</span>
              <span className="gl-fam__count">{cards.length} {cards.length === 1 ? "cut" : "cuts"}</span>
            </div>
            <div className="gl-ev-grid">
              {cards.map((card) => (
                <EvidenceCard key={card.id} card={card} store={store} />
              ))}
            </div>
          </div>
        );
      })}
      {shown.length === 0 && (
        <div className="gl-empty" style={{ marginTop: 16 }}>
          <div className="gl-empty__title">No cuts match that filter</div>
          <div className="gl-empty__sub">Clear the objective filter or the query to see all evidence.</div>
        </div>
      )}
      </div>

      {/* Floating "Ask MakerLab" chat */}
      <AskMakerLab
        greeting="Tell me what you're digging for and I'll pull the cuts that answer it — or tap a suggestion below."
        presets={QUERY_PRESETS}
        onRun={handleRun}
        badge={active ? "1" : null}
        thinkingText="Deciding which cuts make the most sense…"
        placeholder="Ask a question…"
      />
    </div>
  );
}

function EvidenceCard({ card, store }) {
  const members = store.membershipsOf(card.id);
  const pinned = members.length > 0;
  const [open, setOpen] = React.useState(false);
  return (
    <article className={"gl-ev" + (pinned ? " is-pinned" : "") + (open ? " is-popopen" : "")}>
      <div className="gl-ev__head">
        <span className="gl-ev__title">{card.title}</span>
        <span
          className={"gl-sigflag gl-sigflag--" + GOLA.evSig(card.id)}
          data-tip={GOLA.SIG_META[GOLA.evSig(card.id)].short + " significance — " + GOLA.SIG_META[GOLA.evSig(card.id)].tip}
        >
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path>
            <line x1="4" y1="22" x2="4" y2="15"></line>
          </svg>
        </span>
      </div>
      <div className="gl-ev__q">{card.q}</div>
      <div className="gl-ev__metric">
        <span className="gl-ev__metric-val">{card.metric.val}</span>
        <span className="gl-ev__metric-label">{card.metric.label}</span>
      </div>
      <EvBars bars={card.bars} unit={card.unit} />
      <div className="gl-ev__foot">
        <span className="gl-ev__n">n = {card.n.toLocaleString()}</span>
        <div className="gl-pinwrap">
          <button
            className={"gl-pin-btn" + (pinned ? " is-pinned" : "")}
            onClick={(e) => { e.stopPropagation(); setOpen((o) => !o); }}
          >
            <span className="gl-pin-btn__ico">{pinned ? "✓" : "+"}</span>
            {pinned ? "Pinned · " + members.length : "Pin to insight"}
            <svg className={"gl-pin-btn__caret" + (open ? " is-open" : "")} width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 9l6 6 6-6"/></svg>
          </button>
          {open && (
            <PinPopover card={card} store={store} members={members} onClose={() => setOpen(false)} />
          )}
        </div>
      </div>
    </article>
  );
}

// ---- Destination picker — pin a cut to an existing or new insight ----
function PinPopover({ card, store, members, onClose }) {
  const [q, setQ] = React.useState("");
  const ref = React.useRef(null);
  const inputRef = React.useRef(null);
  React.useEffect(() => {
    function onDoc(e) { if (ref.current && !ref.current.contains(e.target)) onClose(); }
    function onKey(e) { if (e.key === "Escape") onClose(); }
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onKey);
    if (inputRef.current) inputRef.current.focus({ preventScroll: true });
    return () => { document.removeEventListener("mousedown", onDoc); document.removeEventListener("keydown", onKey); };
  }, [onClose]);

  const memberSet = new Set(members);
  const needle = q.trim().toLowerCase();
  const list = store.insights.filter((i) => {
    if (!needle) return true;
    return (i.title + " " + (i.nav || "") + " " + (i.tagline || "") + " " + i.num).toLowerCase().includes(needle);
  });

  function toggle(i) {
    if (memberSet.has(i.id)) store.removeEvidence(i.id, card.id);
    else store.addEvidence(i.id, card.id);
  }
  function createNew() { store.createInsight(card.id); onClose(); }

  return (
    <div className="gl-pinpop" ref={ref}>
      <div className="gl-pinpop__head">
        <span className="gl-pinpop__eyebrow">Pin this cut to</span>
        <button className="gl-pinpop__x" onClick={onClose} aria-label="Close">×</button>
      </div>
      <div className="gl-pinpop__search">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
        <input
          ref={inputRef}
          placeholder="Search insights…"
          value={q}
          onChange={(e) => setQ(e.target.value)}
        />
      </div>
      <div className="gl-pinpop__list">
        {list.map((i) => {
          const on = memberSet.has(i.id);
          return (
            <button key={i.id} className={"gl-pinpop__opt" + (on ? " is-on" : "")} onClick={() => toggle(i)}>
              <span className={"gl-pinpop__check" + (on ? " is-on" : "")}>
                {on && <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5"/></svg>}
              </span>
              <span className="gl-pinpop__optmain">
                <span className="gl-pinpop__optnum">
                  Insight {i.num}
                  {i.source === "user" && <em className="gl-pinpop__yours">yours</em>}
                </span>
                <span className="gl-pinpop__opttitle">
                  {i.title || (i.drafting ? "Drafting headline…" : "Untitled insight")}
                </span>
              </span>
              <span className="gl-pinpop__optobjs">
                {i.objs.map((o) => <span key={o} className="gl-ev__tag">O{o}</span>)}
              </span>
            </button>
          );
        })}
        {list.length === 0 && (
          <div className="gl-pinpop__empty">No insights match “{q}”.</div>
        )}
      </div>
      <button className="gl-pinpop__new" onClick={createNew}>
        <span className="gl-pinpop__newico">+</span>
        <span className="gl-pinpop__newtxt">
          <b>New insight from this cut</b>
          <em>✦ headline auto-drafted for you</em>
        </span>
      </button>
    </div>
  );
}

Object.assign(window, { RawLoop, EvBars, ObjBar, ObjRail, AskMakerLab, PinPopover });
