/* global React, GOLA, REAL_FINDINGS, CURATION */
// =========================================================
// v4 · Curate workspace (CSM-only, behind the scenes).
// LEFT  — the findings pool (every uncurated finding card).
// RIGHT — the story outline: objective-seeded sections the CSM
//         fills by dragging findings in. Each section synthesizes
//         to an interpretive headline + actionable recommendation,
//         is edited, then published into the client view.
// Drag-to-assign: a finding STAYS in the pool and gains a
// membership chip — one finding can live in several sections.
// =========================================================

function rfIndexCW() {
  var RF = window.REAL_FINDINGS;
  var idx = {};
  if (RF && RF.CLAIMS) RF.CLAIMS.forEach(function (f) { idx[f.id] = f; });
  return idx;
}

// --- small accent swatch for a section ---
function SecDot({ color }) {
  return <span className="cw-secdot" style={{ background: color }}></span>;
}

// =========================================================
// Pool card — compact, draggable. Shows which sections own it.
// =========================================================
function PoolCard({ f, sections, store, study, bench, onDragState }) {
  const [menuOpen, setMenuOpen] = React.useState(false);
  const owners = CURATION.sectionsWith(sections, f.id);
  const ownerIds = owners.map((o) => o.id);
  const RealCard = window.RealClaimCard;

  return (
    <div className={"cw-pcard cw-pcard--full" + (owners.length ? " is-assigned" : "")}>
      {/* drag handle, next to the heading */}
      <span
        className="cw-pcard__grip"
        draggable
        onDragStart={(e) => {
          e.dataTransfer.setData("text/plain", f.id);
          e.dataTransfer.effectAllowed = "copy";
          onDragState(f.id);
        }}
        onDragEnd={() => onDragState(null)}
        title="Drag into a section"
      >
        <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><circle cx="8" cy="6" r="1.7"/><circle cx="16" cy="6" r="1.7"/><circle cx="8" cy="12" r="1.7"/><circle cx="16" cy="12" r="1.7"/><circle cx="8" cy="18" r="1.7"/><circle cx="16" cy="18" r="1.7"/></svg>
      </span>

      {/* the real V2 finding card — charts, diagrams & Details drawer */}
      {RealCard
        ? <RealCard c={f} objId={f.objs ? f.objs[0] : null} study={study} bench={bench} showVerbatim={false} />
        : <div className="cw-pcard__fallback">{f.statement}</div>}
    </div>
  );
}

// =========================================================
// Assigned row inside a section (compact, removable).
// =========================================================
function AssignedRow({ f, onRemove }) {
  return (
    <div className="cw-arow">
      <span className={"cw-dot cw-dot--" + f.sig}></span>
      <span className="cw-arow__stmt">{f.statement}</span>
      <span className="cw-arow__metric">{f.metricVal}</span>
      {onRemove && <button className="cw-arow__x" title="Remove from section" onClick={onRemove}>×</button>}
    </div>
  );
}

// =========================================================
// Assigned finding preview — the real card rendered at the
// section's width, reflowing naturally (same as the pool cards;
// no transform-scale, so headings stay at their true size).
// =========================================================
function FindingThumb({ f, n, study, bench, badge, onRemove }) {
  const RealCard = window.RealClaimCard;
  return (
    <div className="cw-thumb">
      {RealCard
        ? <RealCard c={f} objId={f.objs ? f.objs[0] : null} study={study} bench={bench} showVerbatim={false} />
        : <div className="cw-pcard__fallback">{f.statement}</div>}
      {badge && <span className="cw-thumb__exc">{badge}</span>}
      {onRemove && <button className="cw-thumb__x" title="Remove from section" onClick={onRemove}>×</button>}
    </div>
  );
}

// =========================================================
// Section card (right column) — drop target + synthesis + publish.
// =========================================================
function SectionCard({ s, idx, store, study, bench, dragging, dropOn, setDropOn }) {
  const RF = rfIndexCW();
  const findings = (s.findings || []).map((id) => RF[id]).filter(Boolean);
  const exc = s.findingsException && RF[s.findingsException.id] ? RF[s.findingsException.id] : null;
  const excNote = s.findingsException ? s.findingsException.note : null;
  const grp = s.findingsGroup
    ? { label: s.findingsGroup.label, sub: s.findingsGroup.sub,
        findings: s.findingsGroup.ids.map((id) => RF[id]).filter(Boolean) }
    : null;
  const count = findings.length + (exc ? 1 : 0) + (grp ? s.findingsGroup.ids.length : 0);
  const isLive = s.status === "live";
  const isOver = dropOn === s.id;

  return (
    <div className={"cw-sec" + (isLive ? " is-live" : "") + (isOver ? " is-over" : "") + (dragging ? " is-droppable" : "")}
      style={{ "--accent": s.accent }}
      onDragOver={(e) => { e.preventDefault(); e.dataTransfer.dropEffect = "copy"; if (dropOn !== s.id) setDropOn(s.id); }}
      onDragLeave={(e) => { if (e.currentTarget === e.target) setDropOn(null); }}
      onDrop={(e) => {
        e.preventDefault();
        const fid = e.dataTransfer.getData("text/plain");
        if (fid) store.assignFinding(s.id, fid);
        setDropOn(null);
      }}
    >
      {/* actions */}
      <div className="cw-sec__foot cw-sec__foot--top">
        <button className="cw-synthbtn" onClick={() => store.synthesizeSection(s.id)} disabled={s.synthesizing || count === 0}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v3M12 18v3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M3 12h3M18 12h3M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/></svg>
          {s.synthesized ? "Re-synthesize" : "Synthesize"}
        </button>
        <span className="cw-sec__footspacer"></span>
        {isLive ? (
          <button className="cw-unpublishbtn" onClick={() => store.unpublishSection(s.id)}>Unpublish</button>
        ) : (
          <button className="cw-publishbtn" disabled={!s.synthesized} title={s.synthesized ? "Publish into the client view" : "Synthesize first"}
            onClick={() => store.publishSection(s.id)}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
            Publish
          </button>
        )}
      </div>

      <div className="cw-sec__head">
        <SecDot color={s.accent} />
        <span className="cw-sec__num">{s.num}</span>
        <div className="cw-sec__titlewrap">
          {s.objId
            ? <span className="cw-sec__obj">Objective {s.objId} · {s.short}</span>
            : <input className="cw-sec__nameinput" value={s.short || ""} placeholder="Name this section…"
                onChange={(e) => store.renameSection(s.id, e.target.value)} />}
          {s.objText && <span className="cw-sec__objtext">{s.objText}</span>}
        </div>
        <span className="cw-sec__spacer"></span>
        <span className="cw-sec__count">{count} finding{count === 1 ? "" : "s"}</span>
        <span className={"cw-statuspill cw-statuspill--" + (isLive ? "live" : "draft")}>{isLive ? "Live" : "Draft"}</span>
        {!s.objId && (
          <button className="cw-iconbtn" title="Delete section" onClick={() => store.deleteSection(s.id)}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14"/></svg>
          </button>
        )}
      </div>

      {/* synthesized output */}
      {s.synthesizing ? (
        <div className="cw-synthrow"><span className="cw-shimmer">✦</span> Synthesizing headline & recommendation…</div>
      ) : s.synthesized ? (
        <div className="cw-output">
          <div className="cw-output__hl" contentEditable suppressContentEditableWarning
            onBlur={(e) => store.editHeadline(s.id, e.currentTarget.textContent.trim())}>{s.title}</div>
          <div className="cw-output__reco">
            <span className="cw-output__recolab">Recommendation</span>
            <span className="cw-output__recotxt" contentEditable suppressContentEditableWarning
              onBlur={(e) => store.editReco(s.id, e.currentTarget.textContent.trim())}>{s.action}</span>
          </div>
        </div>
      ) : (
        <div className="cw-unsynth">
          <span className="cw-unsynth__txt">{count > 0 ? "Findings grouped — synthesize to draft the headline & recommendation." : "Drag findings in, then synthesize."}</span>
        </div>
      )}

      {/* assigned findings — slide-thumbnail previews */}
      <div className="cw-sec__body">
        {findings.length === 0 && !exc && !grp ? (
          <div className="cw-drop-empty">Drag findings here</div>
        ) : (
          <React.Fragment>
            {findings.map((f, i) => (
              <FindingThumb key={f.id} f={f} n={i + 1} study={study} bench={bench} onRemove={() => store.unassignFinding(s.id, f.id)} />
            ))}
            {exc && (
              <div className="cw-excwrap">
                <div className="cw-excnote">
                  <span className="cw-excnote__tag">
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg>
                    Exception · qualifies the headline
                  </span>
                  {excNote && <span className="cw-excnote__txt">{excNote}</span>}
                </div>
                <FindingThumb key={exc.id} f={exc} n={findings.length + 1} study={study} bench={bench} badge="EXC" onRemove={() => store.clearException(s.id)} />
              </div>
            )}
            {grp && window.ConsistentGroup && (
              <div className="cw-grpwrap">
                <window.ConsistentGroup group={grp} />
                <button className="cw-grpwrap__x" title="Remove grouped block" onClick={() => store.clearGroup(s.id)}>× Remove group</button>
              </div>
            )}
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

// =========================================================
// Pool (left) — filters + draggable finding cards.
// =========================================================
function FindingsPool({ store, dragging, setDragging }) {
  const sections = store.sections;
  const RF = window.REAL_FINDINGS;
  const claims = (RF && RF.CLAIMS) || [];
  const { study, bench } = window.useFindingsStudyBench();
  const [filter, setFilter] = React.useState("all"); // all | cb | 1..4 | unassigned

  // "Consumer behavior" = the survey-distribution (bar-chart) findings, mirroring
  // the V3 Findings tab. They carry ids beginning with "f."; every other finding
  // is a sentiment_score / product_treatment cut tied to an objective.
  const isCB = (f) => String(f.id).indexOf("f.") === 0;

  const shown = claims.filter((f) => {
    if (filter === "all") return true;
    if (filter === "cb") return isCB(f);
    if (filter === "unassigned") return CURATION.sectionsWith(sections, f.id).length === 0;
    return !isCB(f) && (f.objs || []).indexOf(Number(filter)) >= 0;
  });
  const unassignedCount = claims.filter((f) => CURATION.sectionsWith(sections, f.id).length === 0).length;

  const pills = [{ k: "all", label: "All" }, { k: "cb", label: "Consumer behavior" }]
    .concat(GOLA.OBJECTIVES.map((o) => ({ k: String(o.id), label: o.short })))
    .concat([{ k: "unassigned", label: "Ungrouped · " + unassignedCount }]);

  return (
    <div className="cw-pool">
      <div className="cw-pool__head">
        <span className="cw-pool__title">Findings Vault</span>
        <span className="cw-pool__sub">{claims.length} uncurated · drag into a section</span>
      </div>
      <div className="cw-pool__filters">
        {pills.map((p) => (
          <button key={p.k} className={"cw-fpill" + (filter === p.k ? " is-on" : "")} onClick={() => setFilter(p.k)}>{p.label}</button>
        ))}
      </div>
      <div className="cw-pool__list">
        {shown.map((f) => (
          <PoolCard key={f.id} f={f} sections={sections} store={store} study={study} bench={bench} onDragState={setDragging} />
        ))}
        {shown.length === 0 && <div className="cw-pool__empty">Nothing here — every finding in this filter is grouped.</div>}
      </div>
    </div>
  );
}

// =========================================================
// Workspace shell.
// =========================================================
function CurateWorkspace({ store }) {
  const [dragging, setDragging] = React.useState(null);
  const [dropOn, setDropOn] = React.useState(null);
  const sections = store.sections;
  const liveCount = sections.filter((s) => s.status === "live").length;
  const { study, bench } = window.useFindingsStudyBench();

  // Resizable split between the story outline (left) and findings pool (right).
  const gridRef = React.useRef(null);
  const [leftW, setLeftW] = React.useState(() => {
    try { const v = parseInt(window.localStorage.getItem("gola-v4-split") || "", 10); return isNaN(v) ? null : v; } catch (e) { return null; }
  });
  const leftWRef = React.useRef(leftW);
  const draggingSplit = React.useRef(false);
  const applyW = (w) => { leftWRef.current = w; setLeftW(w); };

  const onResizeDown = (e) => {
    e.preventDefault();
    draggingSplit.current = true;
    document.body.style.cursor = "col-resize";
    document.body.style.userSelect = "none";
  };
  React.useEffect(() => {
    const MINL = 380, MINR = 340, BAR = 7;
    function move(e) {
      if (!draggingSplit.current || !gridRef.current) return;
      const r = gridRef.current.getBoundingClientRect();
      let w = e.clientX - r.left;
      w = Math.max(MINL, Math.min(r.width - MINR - BAR, w));
      applyW(w);
    }
    function up() {
      if (!draggingSplit.current) return;
      draggingSplit.current = false;
      document.body.style.cursor = "";
      document.body.style.userSelect = "";
      try { if (leftWRef.current != null) window.localStorage.setItem("gola-v4-split", String(Math.round(leftWRef.current))); } catch (e) {}
    }
    window.addEventListener("mousemove", move);
    window.addEventListener("mouseup", up);
    return () => { window.removeEventListener("mousemove", move); window.removeEventListener("mouseup", up); };
  }, []);

  const gridCols = leftW != null
    ? leftW + "px 7px minmax(0,1fr)"
    : "minmax(440px,1.2fr) 7px minmax(340px,0.9fr)";

  return (
    <div className="cw">
      <div className="cw-grid" ref={gridRef} style={{ gridTemplateColumns: gridCols }}>
        <div className="cw-outline">
          <div className="cw-outline__head">
            <div>
              <span className="cw-outline__title">Executive summary</span>
            </div>
            <button className="cw-newsec" onClick={() => store.createSection()}>
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
              Add summary
            </button>
          </div>
          <div className="cw-outline__list">
            {sections.map((s, i) => (
              <SectionCard key={s.id} s={s} idx={i} store={store} study={study} bench={bench} dragging={!!dragging} dropOn={dropOn} setDropOn={setDropOn} />
            ))}
          </div>
        </div>

        <div className="cw-resizer" onMouseDown={onResizeDown} title="Drag to resize" role="separator" aria-orientation="vertical">
          <span className="cw-resizer__bar"></span>
        </div>

        <FindingsPool store={store} dragging={!!dragging} setDragging={setDragging} />
      </div>
    </div>
  );
}

Object.assign(window, { CurateWorkspace, FindingsPool, SectionCard, PoolCard });
