/* ============================================================
   Fynch AI — workshop2.jsx  (slides 12–16)  — v2, elevated
   Friction heatmap (+ scan-to-vote), product mapping, proofs.
   ============================================================ */
(function () {
  const SEED = window.FYNCH_SEED;
  function lerp(a, b, t) { return Math.round(a + (b - a) * t); }
  function hx(h) { return [parseInt(h.slice(1, 3), 16), parseInt(h.slice(3, 5), 16), parseInt(h.slice(5, 7), 16)]; }
  const LOW = hx("#eff6ff"), HIGH = hx("#1d4ed8");
  function cellColor(avg) {
    if (!avg) return { bg: "#f1f5f9", fg: "#cbd5e1" };
    const t = (avg - 1) / 4, c = [0, 1, 2].map((i) => lerp(LOW[i], HIGH[i], t));
    return { bg: `rgb(${c[0]},${c[1]},${c[2]})`, fg: t > 0.45 ? "#fff" : "#1e3a8a" };
  }

  /* ---- Slide 12 — intro ---- */
  function Intro2() {
    return (
      <div className="slide-pad" style={{ justifyContent: "center" }}>
        <Reveal variant="up" className="ws-badge" style={{ color: "var(--brand-300)", marginBottom: 24 }}><span className="num">2</span>WORKSHOP TWO</Reveal>
        <Reveal variant="up" delay={80} as="h2" className="slide-h2" style={{ fontSize: 64, maxWidth: 1400 }}>Score friction, risk &amp; automation potential.</Reveal>
        <Reveal variant="up" delay={160} as="p" className="lead" style={{ marginTop: 20, fontSize: 28 }}>Not about automating everything — about separating manual work from judgment-heavy work.</Reveal>
        <div style={{ marginTop: 46 }}>
          <Reveal variant="up" delay={220} className="label-meta" style={{ color: "#5b6b86", marginBottom: 16 }}>Score each mapped stage across</Reveal>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 16 }}>
            {SEED.WS2_COLUMNS.map((c, i) => (
              <Reveal key={c.id} variant="up" delay={280 + i * 70} className="card" style={{ padding: "22px 26px", fontSize: 24, fontWeight: 600, color: "#eaf0fa", display: "flex", alignItems: "center", gap: 14 }}>
                <span style={{ fontFamily: "var(--font-mono)", color: "var(--brand-300)", fontSize: 16 }}>1–5</span>{c.label}
              </Reveal>
            ))}
          </div>
        </div>
        <Foot no={12} section="Workshop 2" />
      </div>
    );
  }

  /* ---- Slide 13 — heatmap + scan-to-vote ---- */
  function Heatmap() {
    const store = useStore();
    const locked = FynchStore.isLocked("ws2");
    const [role, setRole] = useState("all");
    const stages = store.ws1.stages, cols = SEED.WS2_COLUMNS;
    function cell(stageId, dim) {
      const vals = [];
      Object.entries(store.ws2.scores).forEach(([pid, byStage]) => {
        if (role !== "all") { const p = store.participants[pid]; if (!p || p.role !== role) return; }
        const v = byStage[stageId] && byStage[stageId][dim];
        if (typeof v === "number") vals.push(v);
      });
      if (!vals.length) return { avg: 0, n: 0, variance: 0 };
      const avg = vals.reduce((a, b) => a + b, 0) / vals.length;
      const variance = vals.reduce((a, b) => a + (b - avg) ** 2, 0) / vals.length;
      return { avg, n: vals.length, variance };
    }
    function setHost(stageId, dim, cur) {
      if (locked) return; const next = cur >= 5 ? 0 : cur + 1;
      FynchStore.update((s) => { s.ws2.scores.host = s.ws2.scores.host || {}; s.ws2.scores.host[stageId] = s.ws2.scores.host[stageId] || {}; if (next === 0) delete s.ws2.scores.host[stageId][dim]; else s.ws2.scores.host[stageId][dim] = next; });
    }
    const votes = Object.keys(store.ws2.scores).filter((k) => k !== "host").length;
    return (
      <div className="slide-pad">
        <div className="ws">
          <WsHeader n="2" wsKey="ws2" title="Where the deal cycle leaks time" sub="The room scores on their phones · purple marks disagreement · filter by role to see where stakeholders differ"
            right={<select className="imp-select" style={{ maxWidth: 220, height: 38, fontSize: 15 }} value={role} onChange={(e) => setRole(e.target.value)}><option value="all">All roles</option>{SEED.ROLES.map((r) => <option key={r} value={r}>{r}</option>)}</select>} />
          <div className="cols grow" style={{ gridTemplateColumns: "1fr 332px", gap: 28, alignItems: "stretch", minHeight: 0 }}>
            <Reveal variant="up" delay={120} style={{ overflow: "auto" }}>
              <table className="heatmap">
                <thead><tr><th className="rowhead">Stage</th>{cols.map((c) => <th key={c.id}>{c.label}</th>)}</tr></thead>
                <tbody>
                  {stages.map((st, i) => (
                    <tr key={st.id}>
                      <td className="rowhead"><span className="ix">{String(i + 1).padStart(2, "0")}</span>{st.name}</td>
                      {cols.map((c) => {
                        const agg = cell(st.id, c.id), col = cellColor(agg.avg);
                        const cur = (store.ws2.scores.host && store.ws2.scores.host[st.id] && store.ws2.scores.host[st.id][c.id]) || 0;
                        return <td key={c.id} className="hcell"><div className={"box" + (agg.variance >= 1.2 ? " disagree" : "")} style={{ background: col.bg, color: col.fg }} onClick={() => setHost(st.id, c.id, cur)} title={agg.n ? `avg ${agg.avg.toFixed(1)} · n=${agg.n}` : "click to set host score"}><span className="sc">{agg.avg ? agg.avg.toFixed(1) : "·"}</span>{agg.n > 0 && <span className="var">n{agg.n}</span>}</div></td>;
                      })}
                    </tr>
                  ))}
                </tbody>
              </table>
            </Reveal>
            <div className="stack" style={{ gap: 18 }}>
              <QRJoin />
              <Reveal variant="right" delay={200} className="card" style={{ padding: "20px 22px", flex: 1, display: "flex", flexDirection: "column", justifyContent: "center", gap: 16 }}>
                <div><span className="bignum" style={{ fontSize: 56, color: "var(--brand-600)" }}><CountUp to={votes} /></span><div style={{ fontSize: 17, color: "var(--ink-500)" }}>participants scored so far</div></div>
                <div className="heat-legend" style={{ flexDirection: "column", alignItems: "flex-start", gap: 8 }}>
                  <span className="label-meta">Friction scale</span>
                  <div style={{ display: "flex", alignItems: "center", gap: 10, width: "100%" }}><span style={{ fontSize: 14 }}>low</span><span className="scale" style={{ flex: 1 }}>{[1, 2, 3, 4, 5].map((v) => { const c = cellColor(v); return <span key={v} style={{ background: c.bg }}></span>; })}</span><span style={{ fontSize: 14 }}>high</span></div>
                  <div style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 14, color: "var(--ink-500)" }}><span style={{ width: 10, height: 10, borderRadius: "50%", background: "#7c3aed" }}></span>roles disagree</div>
                </div>
              </Reveal>
            </div>
          </div>
        </div>
        <Foot no={13} section="Workshop 2" />
      </div>
    );
  }

  /* ---- Slide 14 — top handoff leaks + product mapping ---- */
  const MAPPING = [
    { key: "Intake", area: "Document intake & company inbox", test: (n) => /intake|sourced|received|data room/i.test(n) },
    { key: "Completeness", area: "Deal package & source coverage", test: (n) => /package|screen|complete/i.test(n) },
    { key: "Manual spreading", area: "Parsing & fact base", test: (n) => /underwriting|prelim|spread|model/i.test(n) },
    { key: "Review", area: "Evidence & review queues", test: (n) => /review|diligence|credit/i.test(n) },
    { key: "Quoting", area: "Policy & computed metrics", test: (n) => /quote|term|committee/i.test(n) },
    { key: "Memo prep", area: "Outputs & templates", test: (n) => /memo|closing|committee/i.test(n) },
  ];
  function TopLeaks() {
    const store = useStore();
    const scored = store.ws1.stages.map((st) => ({ st, score: FynchStore.agg.ws2StageScore(store, st.id), auto: FynchStore.agg.ws2Cell(store, st.id, "auto").avg, judg: FynchStore.agg.ws2Cell(store, st.id, "judgment").avg }));
    const topFriction = [...scored].filter((x) => x.score > 0).sort((a, b) => b.score - a.score).slice(0, 3);
    const topAuto = [...scored].filter((x) => x.auto > 0).sort((a, b) => b.auto - a.auto).slice(0, 3);
    const topJudg = [...scored].filter((x) => x.judg > 0).sort((a, b) => b.judg - a.judg).slice(0, 3);
    function mapFor(name) { const m = MAPPING.find((x) => x.test(name)); return m ? m.area : "Fact base & review"; }
    const empty = topFriction.length === 0;
    return (
      <div className="slide-pad">
        <Reveal variant="up"><div className="eyebrow-row" style={{ marginBottom: 8 }}><Kicker>Workshop 2 · output</Kicker></div></Reveal>
        <Reveal variant="up" delay={70} as="h2" className="slide-h2" style={{ marginBottom: 6 }}>The bottleneck is the handoff.</Reveal>
        <Reveal variant="up" delay={130} as="p" className="lead" style={{ marginBottom: 28, fontSize: 24 }}>Documents to facts · facts to model · model to memo · memo to committee.</Reveal>
        <div className="cols grow" style={{ gridTemplateColumns: "1fr 1.05fr", gap: 36, alignItems: "stretch", minHeight: 0 }}>
          <Reveal variant="up" delay={160} className="card" style={{ padding: "26px 30px", display: "flex", flexDirection: "column" }}>
            <div className="label-meta" style={{ marginBottom: 16 }}>Your top friction stages</div>
            <div className="stack" style={{ gap: 14 }}>
              {empty && <div className="muted" style={{ fontSize: 20 }}>Score the heatmap and the rankings appear here live.</div>}
              {topFriction.map((x, i) => <div key={x.st.id} style={{ display: "flex", alignItems: "center", gap: 16 }}><span className="numbadge" style={{ width: 40, height: 40 }}>{i + 1}</span><span style={{ fontSize: 23, fontWeight: 600 }}>{x.st.name}</span><span className="mono" style={{ marginLeft: "auto", color: "var(--brand-600)", fontWeight: 600, fontSize: 19 }}>{x.score.toFixed(1)}</span></div>)}
            </div>
            <hr className="hr" style={{ margin: "20px 0" }} />
            <div className="cols c2" style={{ gap: 28 }}>
              <div><div className="label-meta" style={{ marginBottom: 10 }}>Automation candidates</div>{topAuto.length ? topAuto.map((x) => <div key={x.st.id} style={{ fontSize: 17, color: "var(--ink-700)", padding: "4px 0" }}>· {x.st.name}</div>) : <div className="faint" style={{ fontSize: 17 }}>—</div>}</div>
              <div><div className="label-meta" style={{ marginBottom: 10 }}>Keep human-led</div>{topJudg.length ? topJudg.map((x) => <div key={x.st.id} style={{ fontSize: 17, color: "var(--ink-700)", padding: "4px 0" }}>· {x.st.name}</div>) : <div className="faint" style={{ fontSize: 17 }}>—</div>}</div>
            </div>
          </Reveal>
          <Reveal variant="right" delay={220} className="card" style={{ padding: "26px 30px", display: "flex", flexDirection: "column" }}>
            <div className="label-meta" style={{ marginBottom: 18 }}>Your friction → relevant product capability</div>
            <div className="stack" style={{ gap: 14, flex: 1, justifyContent: "center" }}>
              {(empty ? MAPPING.slice(0, 4).map((m) => ({ name: m.key, area: m.area })) : topFriction.map((x) => ({ name: x.st.name, area: mapFor(x.st.name) }))).map((row, i) => (
                <div key={i} style={{ display: "grid", gridTemplateColumns: "1fr auto 1.1fr", alignItems: "center", gap: 16 }}>
                  <div style={{ background: "var(--canvas)", border: "1px solid var(--line-200)", borderRadius: 10, padding: "14px 16px", fontSize: 18, fontWeight: 600 }}>{row.name}</div>
                  <span style={{ color: "var(--brand-500)" }}><Icon name="arrowR" size={22} /></span>
                  <div style={{ background: "var(--brand-50)", border: "1px solid var(--brand-200)", borderRadius: 10, padding: "14px 16px", fontSize: 18, fontWeight: 600, color: "var(--brand-700)" }}>{row.area}</div>
                </div>
              ))}
            </div>
          </Reveal>
        </div>
        <Foot no={14} section="Workshop 2" />
      </div>
    );
  }

  /* ---- Slides 15 & 16 — proofs (screenshot slots) ---- */
  function Proof2a() {
    return (
      <div className="slide-pad">
        <SolvesTag solves="Review risk · rework · fact confidence" status="live" />
        <Reveal variant="up" style={{ maxWidth: 1180, marginBottom: 22 }}><Kicker>Micro-proof</Kicker><h1 className="slide-title" style={{ fontSize: 38, marginTop: 8 }}>A fact is more than a number.</h1></Reveal>
        <div className="grow" style={{ minHeight: 0 }}><ScreenSlot label="Knowledge Base — fact detail" tab="Value · source citation · confidence · reviewer · conflicts · dependencies · version" note="Drop the fact-detail panel here — the NOI fact with its highlighted source page and lineage." /></div>
        <Foot no={15} section="Product proof 2" />
      </div>
    );
  }
  function Proof2b() {
    return (
      <div className="slide-pad">
        <SolvesTag solves="Package completeness · quote readiness" status="live" />
        <Reveal variant="up" style={{ maxWidth: 1180, marginBottom: 22 }}><Kicker>Micro-proof</Kicker><h1 className="slide-title" style={{ fontSize: 38, marginTop: 8 }}>Source coverage prevents false confidence.</h1></Reveal>
        <div className="grow" style={{ minHeight: 0 }}><ScreenSlot label="Source Coverage — checklist vs. fact support" tab="Received · Missing · Weak · Conflicted · Blocking · Sufficient" note="Drop the source-coverage view: a file checkbox beside the fact-level coverage it actually supports." /></div>
        <Foot no={16} section="Product proof 2" />
      </div>
    );
  }

  window.registerSlides([
    { no: 12, section: "Workshop 2", dark: true, Comp: Intro2 },
    { no: 13, section: "Workshop 2", ws: "ws2", Comp: Heatmap },
    { no: 14, section: "Workshop 2", ws: "ws2", Comp: TopLeaks },
    { no: 15, section: "Product proof 2", Comp: Proof2a },
    { no: 16, section: "Product proof 2", Comp: Proof2b },
  ]);
})();
