// ═══════════════════════════════════════════════════════════════════
// COPILOT — Advisory Q&A over the project's Intelligence Report.
//
// SIO Objective 10 (CEO Advisory Mode): every answer is a senior-exec
// brief — Executive Summary · Findings · Risks · Opportunities ·
// Recommended Actions · Priority · Expected Business Impact — and is
// GROUNDED in the project Knowledge Base (window.INTEL_REPORTS[id]),
// never free consulting. Reads the same payload the report renders, so
// the advisory and the document can never disagree.
// ═══════════════════════════════════════════════════════════════════
(function () {
  const { useState, useRef, useEffect } = React;
  const K = window.IntelReportKit || {};
  const mono = K.mono || ((s, x) => <span style={{ fontFamily: "var(--mono)", fontSize: "8.5px", letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--ink-4)", ...x }}>{s}</span>);
  const card = K.card || ((x) => ({ border: "1px solid var(--rule-hard)", borderRadius: "var(--r-3)", background: "var(--bg)", padding: "15px 17px", ...x }));
  const sevTone = K.sevTone || ((s) => ({ high: "err", med: "warn", low: "neutral" }[String(s).toLowerCase()] || "neutral"));
  const PRI_TONE = { P0: "err", P1: "warn", P2: "info" };
  const impTone = (s) => ({ high: "ok", med: "accent", low: "neutral" }[String(s).toLowerCase()] || "neutral");

  // ── derive a structured advisory answer from the report payload ────
  const actionRow = (a) => (Array.isArray(a) ? { n: a[0], action: a[1], rationale: a[2], pri: a[3] } : a);

  function answerFor(qid, D) {
    const v = D.verdict || {};
    const acts = ((D.readiness && D.readiness.actions) || []).map(actionRow);
    const gaps = (D.diligence && D.diligence.gaps) || [];
    const ops = D.opportunities || [];
    const risks = D.risks || [];
    const base = {
      findings: (D.findings || []).slice(0, 3),
      risks: risks.slice(0, 2),
      opportunities: ops.slice(0, 2),
      actions: acts.slice(0, 3),
      priority: (acts[0] && acts[0].pri) || "P1",
    };
    if (qid === "risks") return {
      summary: "The downside is concentrated in " + risks.length + " rated items; the high-severity ones gate the decision. " + (v.headline || ""),
      findings: (D.findings || []).filter((f) => f.cls === "Q" || f.cls === "U").slice(0, 3),
      risks: risks.filter((r) => String(r.sev).toLowerCase() === "high").slice(0, 4).concat(risks.filter((r) => String(r.sev).toLowerCase() !== "high")).slice(0, 4),
      opportunities: [], actions: acts.filter((a) => a.pri === "P0").slice(0, 3), priority: "P0",
      impact: "Unmitigated, the high-severity items are existential — they block issuance until evidenced.",
    };
    if (qid === "gaps") return {
      summary: gaps.length + " open evidence gaps stand between the current draft and a publishable report; each names the document that closes it.",
      findings: gaps.slice(0, 4).map((g) => ({ cls: g.sev === "high" ? "Q" : "P", text: g.gap + " — " + (g.closes || g.today) + (g.due ? " (due " + g.due + ")" : "") })),
      risks: [], opportunities: [], actions: acts.slice(0, 2), priority: "P0",
      impact: "Closing the high-severity gaps is the critical path to clearing the publish gate.",
    };
    if (qid === "ops") return {
      summary: "The upside, symmetric to the risk register: " + ops.length + " forward opportunities, each scored for confidence and strategic impact.",
      findings: [], risks: [], opportunities: ops.slice(0, 4), actions: acts.filter((a) => a.pri !== "P0").slice(0, 2),
      priority: (ops[0] && impTone(ops[0].impact) === "ok") ? "P1" : "P2",
      impact: "The high-impact opportunities are contingent on the same evidence the gaps demand — clearing diligence unlocks both.",
    };
    if (qid === "digest" && D.digest) return {
      summary: "Since " + (D.digest.since || "the last version") + ", " + D.digest.items.length + " items changed. " + (v.headline || ""),
      findings: D.digest.items.map((it) => ({ cls: it.status === "updated" ? "P" : "V", text: "[" + (it.where || it.ref) + "] " + it.text })),
      risks: [], opportunities: [], actions: acts.slice(0, 2), priority: base.priority,
      impact: "The verdict and critical path are unchanged by this delta — the new items are additive evidence and one new opportunity.",
    };
    if (qid === "structure" && D.graphInsights) {
      const gi = D.graphInsights;
      return {
        summary: gi.insight || gi.note,
        findings: (gi.relations || []).slice(0, 5).map((r) => ({ cls: r.status === "at-risk" ? "Q" : r.status === "firm" ? "V" : "A", text: r.from + " " + r.rel + " " + r.to + " — " + r.note })),
        risks: [], opportunities: [], actions: acts.slice(0, 2), priority: base.priority,
        impact: "Structural risk is concentrated in the at-risk edges above; clearing them unblocks the value path through the graph.",
      };
    }
    // default — the verdict
    return {
      summary: (v.headline || "") + " " + (v.body || ""),
      findings: base.findings, risks: base.risks, opportunities: base.opportunities, actions: base.actions,
      priority: base.priority,
      impact: "Confidence sits at " + (v.confidence != null ? v.confidence + "/100" : "—") + "; the recommended actions above are the fastest path to raising it.",
    };
  }

  const PRESETS = [
    { id: "verdict", q: "What's the verdict, and why?" },
    { id: "risks",   q: "What are the biggest risks?" },
    { id: "gaps",    q: "Where are the open evidence gaps?" },
    { id: "ops",     q: "What's the upside here?" },
    { id: "structure", q: "How does the deal structure hang together?" },
    { id: "digest",  q: "What changed since the last version?" },
  ];
  const matchQid = (text) => {
    const t = text.toLowerCase();
    if (/risk|downside|danger|concern/.test(t)) return "risks";
    if (/gap|missing|evidence|need|outstanding/.test(t)) return "gaps";
    if (/opportun|upside|growth|partner|expand/.test(t)) return "ops";
    if (/structur|graph|relation|depend|edge|architecture|hang together/.test(t)) return "structure";
    if (/chang|new|since|update|delta|latest/.test(t)) return "digest";
    return "verdict";
  };

  // ── structured advisory card (the seven-part exec brief) ───────────
  function AdvisoryCard({ ans, D }) {
    const Badge = (K.mkBadge && D.CLASS) ? K.mkBadge(D.CLASS) : null;
    const block = (label, children) => (
      <div style={{ borderTop: "1px solid var(--rule-soft)", padding: "9px 0 2px" }}>
        {mono(label, { display: "block", marginBottom: 6, color: "var(--accent-lo)" })}
        {children}
      </div>
    );
    return (
      <div style={card({ background: "var(--bg)" })}>
        {mono("executive summary", { display: "block", marginBottom: 6, color: "var(--accent-lo)" })}
        <p style={{ margin: "0 0 4px", fontSize: "var(--fs-sm)", color: "var(--ink)", lineHeight: 1.6, fontWeight: 500 }}>{ans.summary}</p>

        {ans.findings && ans.findings.length > 0 && block("findings", (
          <div style={{ display: "flex", flexDirection: "column" }}>
            {ans.findings.map((f, i) => (
              <div key={i} style={{ display: "grid", gridTemplateColumns: "auto 1fr", gap: 9, alignItems: "baseline", padding: "4px 0" }}>
                {Badge && f.cls ? <Badge cls={f.cls} short /> : <span style={{ color: "var(--accent)", fontSize: 10, lineHeight: 1.8 }}>▪</span>}
                <span style={{ fontSize: "var(--fs-xs)", color: "var(--ink-2)", lineHeight: 1.5 }}>{f.text}</span>
              </div>
            ))}
          </div>
        ))}

        {ans.risks && ans.risks.length > 0 && block("risks", (
          <div style={{ display: "flex", flexDirection: "column" }}>
            {ans.risks.map((r) => (
              <div key={r.id} style={{ display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 9, alignItems: "baseline", padding: "4px 0" }}>
                <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "var(--fs-xs)", color: "var(--ink)" }}>{r.title}</span>
                <span style={{ fontSize: "var(--fs-xs)", color: "var(--ink-3)", lineHeight: 1.5 }}>{r.desc}</span>
                <window.Pill tone={sevTone(r.sev)}>{r.sev}</window.Pill>
              </div>
            ))}
          </div>
        ))}

        {ans.opportunities && ans.opportunities.length > 0 && block("opportunities", (
          <div style={{ display: "flex", flexDirection: "column" }}>
            {ans.opportunities.map((o) => (
              <div key={o.id} style={{ display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 9, alignItems: "baseline", padding: "4px 0" }}>
                <span style={{ fontFamily: "var(--ui-display)", fontWeight: 600, fontSize: "var(--fs-xs)", color: "var(--ink)" }}>{o.title}</span>
                <span style={{ fontSize: "var(--fs-xs)", color: "var(--ink-3)", lineHeight: 1.5 }}>{o.desc}</span>
                <window.Pill tone={impTone(o.impact)}>{o.impact}</window.Pill>
              </div>
            ))}
          </div>
        ))}

        {ans.actions && ans.actions.length > 0 && block("recommended actions", (
          <div style={{ display: "flex", flexDirection: "column" }}>
            {ans.actions.map((a, i) => (
              <div key={i} style={{ display: "grid", gridTemplateColumns: "20px 1fr auto", gap: 9, alignItems: "baseline", padding: "4px 0" }}>
                <span style={{ fontFamily: "var(--mono)", fontSize: "10px", fontWeight: 600, color: "var(--ink-4)" }}>{a.n}</span>
                <span style={{ fontSize: "var(--fs-xs)", color: "var(--ink-2)", lineHeight: 1.5 }}><span style={{ color: "var(--ink)", fontWeight: 500 }}>{a.action}</span> — {a.rationale}</span>
                <window.Pill tone={PRI_TONE[a.pri] || "neutral"}>{a.pri}</window.Pill>
              </div>
            ))}
          </div>
        ))}

        <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", borderTop: "1px solid var(--rule-soft)", marginTop: 8, paddingTop: 10 }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>{mono("priority")}<window.Pill tone={PRI_TONE[ans.priority] || "neutral"}>{ans.priority}</window.Pill></span>
          <span style={{ display: "grid", gridTemplateColumns: "auto 1fr", gap: 8, alignItems: "baseline", flex: 1, minWidth: 240 }}>{mono("expected impact")}<span style={{ fontSize: "var(--fs-xs)", color: "var(--ink-3)", lineHeight: 1.5 }}>{ans.impact}</span></span>
        </div>
      </div>
    );
  }

  function IntelCopilot({ proj, tenant, go }) {
    const D = (window.INTEL_REPORTS && window.INTEL_REPORTS[proj.id]) || null;
    const [thread, setThread] = useState([]);
    const [input, setInput] = useState("");
    const endRef = useRef(null);

    // seed with the verdict answer on first mount / project switch
    useEffect(() => {
      if (D) setThread([{ q: "What's the verdict, and why?", a: answerFor("verdict", D) }]);
      else setThread([]);
    }, [proj.id]);
    useEffect(() => { if (endRef.current) endRef.current.scrollTop = endRef.current.scrollHeight; }, [thread]);

    if (!D) {
      return (
        <div>
          <window.PageHead eyebrow={tenant.name + " · " + proj.name} title="Copilot"></window.PageHead>
          <div style={card({ background: "var(--bg-2)" })}><p style={{ margin: 0, fontSize: "var(--fs-sm)", color: "var(--ink-2)" }}>No report payload for this project yet — the Copilot grounds its answers in a composed Intelligence Report. Run the workflow first.</p></div>
        </div>
      );
    }

    const ask = (q) => { const t = q.trim(); if (!t) return; setThread((th) => [...th, { q: t, a: answerFor(matchQid(t), D) }]); setInput(""); };

    return (
      <div>
        <window.PageHead eyebrow={tenant.name + " · " + proj.name + " · grounded advisory"} title="Copilot"
          sub="Ask the Knowledge Base. Every answer is a senior-executive brief — summary, findings, risks, opportunities, recommended actions, priority and expected impact — composed from the same report payload the document renders, never free-written."
          right={<div style={{ textAlign: "right" }}>{mono("grounded on " + (D.kbLen || 0) + " sourced facts", { display: "block", marginBottom: 4, color: "var(--accent-lo)" })}{mono((D.classId || "") + " class · report " + (D.version || "—"))}</div>}>
        </window.PageHead>

        <div style={{ display: "flex", gap: 7, flexWrap: "wrap", marginBottom: 16 }}>
          {PRESETS.map((p) => (
            <button key={p.id} onClick={() => ask(p.q)} style={{ border: "1px solid var(--rule-hard)", background: "var(--bg)", color: "var(--ink-2)", borderRadius: "999px", padding: "6px 13px", cursor: "pointer", fontFamily: "var(--ui)", fontSize: "12px", fontWeight: 500 }}>{p.q}</button>
          ))}
        </div>

        <div ref={endRef} style={{ display: "flex", flexDirection: "column", gap: 16, maxHeight: "calc(100vh - 320px)", overflowY: "auto", paddingRight: 4, marginBottom: 16 }}>
          {thread.map((m, i) => (
            <div key={i} style={{ display: "flex", flexDirection: "column", gap: 9 }}>
              <div style={{ display: "flex", justifyContent: "flex-end" }}>
                <span style={{ background: "var(--bg-dark)", color: "#fff", borderRadius: "var(--r-3)", borderBottomRightRadius: 3, padding: "9px 14px", fontSize: "var(--fs-sm)", maxWidth: "70%", lineHeight: 1.5 }}>{m.q}</span>
              </div>
              <div style={{ display: "flex", alignItems: "flex-start", gap: 10 }}>
                <span style={{ width: 26, height: 26, borderRadius: 7, background: "var(--accent)", color: "var(--bg)", display: "grid", placeItems: "center", fontFamily: "var(--ui-display)", fontWeight: 700, fontSize: 13, flex: "0 0 auto", marginTop: 2 }}>C</span>
                <div style={{ flex: 1, minWidth: 0 }}><AdvisoryCard ans={m.a} D={D} /></div>
              </div>
            </div>
          ))}
        </div>

        <div style={{ display: "flex", gap: 8, alignItems: "center", border: "1px solid var(--rule-hard)", borderRadius: "var(--r-3)", background: "var(--bg)", padding: "7px 8px 7px 14px" }}>
          <input value={input} onChange={(e) => setInput(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") ask(input); }}
            placeholder="Ask about this deal — risks, gaps, upside, what changed…"
            style={{ flex: 1, border: "none", outline: "none", background: "transparent", fontFamily: "var(--ui)", fontSize: "13px", color: "var(--ink)" }} />
          <button onClick={() => ask(input)} style={{ border: "none", background: "var(--accent)", color: "var(--bg)", borderRadius: "var(--r-2)", padding: "8px 16px", cursor: "pointer", fontFamily: "var(--ui)", fontSize: "12.5px", fontWeight: 600 }}>Ask</button>
        </div>
        <p style={{ margin: "10px 0 0", fontFamily: "var(--mono)", fontSize: "9px", letterSpacing: "0.06em", color: "var(--ink-4)", lineHeight: 1.7 }}>
          Answers are composed from the project's report payload (RPT-v3) — the verdict, findings, risk &amp; opportunity registers, structural relations, evidence gaps and recommended actions. The Copilot never asserts beyond the Knowledge Base; unknowns surface as gaps.
        </p>
      </div>
    );
  }

  window.IntelCopilot = IntelCopilot;
})();
