// ============ KNOWLEDGE TAB ============
// Documents, sheets, exports your agents have read. Each doc is taught to
// specific agents — `taught[agentId] = ISO timestamp` records when. Adding
// a new agent later doesn't retroactively teach them; you decide who reads
// what. Data is persisted via the server (/knowledge API).

const KIND_ICON = { doc: "✎", pdf: "▤", sheet: "▦", csv: "▤" };

const SERVER_URL_KN = () =>
  (typeof window !== "undefined" && window.CITRUS_CONFIG && window.CITRUS_CONFIG.SERVER_URL) ||
  "http://localhost:3001";

async function kFetch(path, opts = {}) {
  const r = await fetch(SERVER_URL_KN() + path, {
    headers: { "content-type": "application/json" },
    ...opts,
  });
  if (!r.ok) {
    const t = await r.text().catch(() => "");
    throw new Error(`${r.status}: ${t.slice(0, 120)}`);
  }
  return r.json();
}

function KnowledgeTab({ agents = [], conflicts = [], globalLearnings = null }) {
  const [q, setQ]           = useState("");
  const [docs, setDocs]     = useState([]);
  const [genericLearnings, setGenericLearnings] = useState([]);
  const [teaching, setTeaching] = useState(null);
  const [previewing, setPreviewing] = useState(null); // docId with expanded preview
  const [dragging, setDragging] = useState(false);
  const fileRef             = useRef(null);
  const filt = q ? docs.filter(d => d.name.toLowerCase().includes(q.toLowerCase())) : docs;

  // Load docs and generic learnings from server on mount
  useEffect(() => {
    kFetch("/knowledge")
      .then(setDocs)
      .catch((e) => window.toast && window.toast("Couldn't load knowledge docs: " + e.message, "warn"));
    kFetch("/learnings")
      .then(setGenericLearnings)
      .catch(() => {});
  }, []);

  // Keep generic learnings in sync with real-time updates pushed from app.jsx
  // (e.g. when auto-teach disables a conflicting lesson in the background).
  useEffect(() => {
    if (globalLearnings !== null) setGenericLearnings(globalLearnings);
  }, [globalLearnings]);

  const addDocs = (fileList) => {
    if (!fileList || fileList.length === 0) return;

    const kindFor = (n) => {
      const ext = n.toLowerCase().split(".").pop();
      if (ext === "pdf") return "pdf";
      if (ext === "csv") return "csv";
      if (["xlsx", "xls", "numbers"].includes(ext)) return "sheet";
      if (["docx", "doc"].includes(ext)) return "doc";
      return "doc";
    };

    // Binary types that need server-side extraction — send as base64
    const BINARY_EXTS = new Set(["pdf", "docx", "doc", "xlsx", "xls"]);
    const isBinary = (f) => BINARY_EXTS.has(f.name.toLowerCase().split(".").pop());

    const fmt = (b) => b > 1e6 ? (b / 1e6).toFixed(1) + " MB" : Math.max(1, Math.round(b / 1024)) + " KB";
    const files = Array.from(fileList);

    Promise.all(files.map((f) =>
      new Promise((resolve, reject) => {
        const reader = new FileReader();
        if (isBinary(f)) {
          reader.onload = (e) => {
            // readAsDataURL returns "data:<type>;base64,<data>" — strip the prefix
            const b64 = e.target.result.split(",")[1];
            resolve({ file: f, content: b64, encoding: "base64" });
          };
          reader.readAsDataURL(f);
        } else {
          reader.onload = (e) => resolve({ file: f, content: e.target.result, encoding: "text" });
          reader.readAsText(f);
        }
        reader.onerror = reject;
      })
    )).then((results) => {
      return Promise.all(results.map(({ file, content, encoding }) =>
        kFetch("/knowledge", {
          method: "POST",
          body: JSON.stringify({
            name:        file.name,
            kind:        kindFor(file.name),
            size:        fmt(file.size || 0),
            content:     content,
            contentType: file.type || "text/plain",
            encoding:    encoding === "base64" ? "base64" : undefined,
          }),
        })
      ));
    }).then((newDocs) => {
      setDocs((prev) => [...newDocs, ...prev]);
      window.toast && window.toast(`Added ${newDocs.length} document${newDocs.length === 1 ? "" : "s"}. Click "Teach an agent" to make it readable.`, "good");
      if (newDocs[0]) setTeaching(newDocs[0].id);
    }).catch((e) => {
      window.toast && window.toast("Upload failed: " + e.message, "warn");
    });
  };

  const removeDoc = (id) => {
    if (!window.confirm("Remove this document from your agents' knowledge?")) return;
    kFetch("/knowledge/" + id, { method: "DELETE" })
      .then(() => {
        setDocs((prev) => prev.filter((d) => d.id !== id));
        window.toast && window.toast("Document removed", "warn");
      })
      .catch((e) => window.toast && window.toast("Couldn't remove: " + e.message, "warn"));
  };

  const teachAgents = (docId, agentIds) => {
    kFetch("/knowledge/" + docId + "/teach", {
      method: "POST",
      body: JSON.stringify({ agentIds }),
    })
      .then((updated) => {
        setDocs((prev) => prev.map((d) => d.id === docId ? updated : d));
        setTeaching(null);
        const named = agentIds
          .map((id) => agents.find((a) => a.id === id)?.name || id.toUpperCase())
          .join(", ");
        window.toast && window.toast(named ? `Taught to ${named}` : "Removed from all agents", "good");
      })
      .catch((e) => window.toast && window.toast("Couldn't update: " + e.message, "warn"));
  };

  return (
    <div
      className={`kn-page${dragging ? " kn-dragging" : ""}`}
      onDragOver={(e) => { e.preventDefault(); setDragging(true); }}
      onDragLeave={(e) => { if (!e.currentTarget.contains(e.relatedTarget)) setDragging(false); }}
      onDrop={(e) => {
        e.preventDefault();
        setDragging(false);
        addDocs(e.dataTransfer.files);
      }}
    >
      <div className="kn-head">
        <div>
          <h2 className="kn-h">Everything your agents have read.</h2>
          <p className="kn-s">Upload a doc, then choose which agent gets to read it. Adding a new agent later doesn't auto-share — you decide.</p>
        </div>
        <div className="kn-actions">
          <button className="btn btn-primary btn-sm" onClick={() => fileRef.current && fileRef.current.click()}>+ Add document</button>
          <input
            ref={fileRef}
            type="file"
            multiple
            accept=".txt,.md,.csv,.json,.html,.htm,.xml,.yaml,.yml,.js,.ts,.jsx,.tsx,.py,.rb,.java,.c,.cpp,.h,.cs,.go,.rs,.sh,.log,.pdf,.docx,.doc,.xlsx,.xls"
            style={{ display: "none" }}
            onChange={(e) => { addDocs(e.target.files); e.target.value = ""; }}
          />
        </div>
      </div>

      <div className="kn-search">
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><circle cx="6" cy="6" r="4.5"/><path d="m9.5 9.5 3 3"/></svg>
        <input className="kn-search-i" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search documents…" />
      </div>

      <div className="kn-list">
        {docs.length === 0 ? (
          <div className="kn-empty">
            No documents yet.
            {" "}<button className="kn-empty-link" onClick={() => fileRef.current && fileRef.current.click()}>Upload one</button>{" "}
            or drag & drop files here — then click "Teach an agent" so it can read it.
          </div>
        ) : filt.length === 0 ? (
          <div className="kn-empty">No documents match "{q}".</div>
        ) : filt.map(d => {
          const taughtIds = Object.keys(d.taught || {});
          const taughtAgents = agents.filter((a) => taughtIds.includes(a.id));
          const isTeaching = teaching === d.id;
          return (
            <div key={d.id} className="kn-row">
              {/* Top line: icon + name + actions */}
              <div className="kn-row-line">
                <div className="kn-row-icon">{KIND_ICON[d.kind] || "✎"}</div>
                <div className="kn-row-body">
                  <div className="kn-row-n">{d.name}</div>
                  <div className="kn-row-m">
                    {d.charCount ? `${(d.charCount / 1000).toFixed(1)}k chars` : d.size}
                    {" · "}added {timeAgo(d.addedAt)}
                    {d.global ? <span className="kn-row-global"> · global (every agent)</span> : null}
                  </div>
                </div>
                <div className="kn-row-actions">
                  {d.preview ? (
                    <button
                      className="btn btn-ghost btn-sm"
                      onClick={() => setPreviewing(previewing === d.id ? null : d.id)}
                    >{previewing === d.id ? "Hide" : "Preview"}</button>
                  ) : null}
                  <button className="btn btn-ghost btn-sm" onClick={() => setTeaching(isTeaching ? null : d.id)}>
                    {taughtAgents.length > 0 ? "Edit" : "Teach"}
                  </button>
                  <button className="kn-row-more" title="Remove" onClick={() => removeDoc(d.id)}>×</button>
                </div>
              </div>

              {/* Bottom line: taught-to chips, on their own row so they wrap cleanly */}
              {!d.global && (
                <div className="kn-row-tags">
                  {taughtAgents.length > 0 ? (
                    <>
                      <span className="kn-row-used-l">Taught to</span>
                      {taughtAgents.map((a) => (
                        <span key={a.id} className="kn-row-chip" style={{ background: a.palette?.skin, color: "#fff" }}>{a.name}</span>
                      ))}
                    </>
                  ) : (
                    <span className="kn-row-used-l kn-row-untaught">Not taught to any agent yet</span>
                  )}
                </div>
              )}

              {previewing === d.id && d.preview ? (
                <div className="kn-preview">{d.preview}{d.charCount > 300 ? "…" : ""}</div>
              ) : null}

              {isTeaching ? (
                <TeachPanel
                  doc={d}
                  agents={agents}
                  onCancel={() => setTeaching(null)}
                  onSave={(ids) => teachAgents(d.id, ids)}
                />
              ) : null}
            </div>
          );
        })}
      </div>

      <LearningsSection
        agents={agents}
        conflicts={conflicts}
        genericLearnings={genericLearnings}
        onGenericChange={setGenericLearnings}
      />

      <div className="kn-tip">
        <div className="kn-tip-mark">i</div>
        <div>
          <div className="kn-tip-t">How "teach" works</div>
          <div className="kn-tip-s">Upload any document — PDF, Word (.docx), Excel (.xlsx), CSV, or plain text. The server extracts the text automatically. Teach it to an agent and they'll use it to answer relevant questions. New agents you hire won't see the doc until you explicitly teach them.</div>
        </div>
      </div>

    </div>
  );
}

// ---- CONFLICT CARD ----
function ConflictCard({ conflict, onResolve }) {
  const [busy, setBusy]         = useState(false);
  const [deleteLoser, setDelete] = useState(false);

  const resolve = (action) => {
    setBusy(true);
    kFetch(`/conflicts/${conflict.id}/resolve`, {
      method: "POST",
      body: JSON.stringify({ action, deleteLoser }),
    })
      .then(() => {
        window.toast && window.toast(action === "dismiss" ? "Conflict dismissed" : "Conflict resolved", "good");
        onResolve && onResolve(conflict.id);
      })
      .catch((e) => window.toast && window.toast("Couldn't resolve: " + e.message, "warn"))
      .finally(() => setBusy(false));
  };

  return (
    <div className="cf-card">
      <div className="cf-header">
        <span className="cf-badge">Conflict</span>
        <span className="cf-reason">{conflict.reason}</span>
      </div>
      <div className="cf-pair">
        <div className="cf-learning">
          <div className="cf-learning-what">{conflict.aWhat}</div>
          {conflict.aWhy && <div className="cf-learning-why">Why: {conflict.aWhy}</div>}
          {conflict.aQuote && <div className="cf-learning-quote">"{conflict.aQuote}"</div>}
        </div>
        <div className="cf-vs">vs</div>
        <div className="cf-learning">
          <div className="cf-learning-what">{conflict.bWhat}</div>
          {conflict.bWhy && <div className="cf-learning-why">Why: {conflict.bWhy}</div>}
          {conflict.bQuote && <div className="cf-learning-quote">"{conflict.bQuote}"</div>}
        </div>
      </div>
      <div className="cf-actions">
        <label className="cf-delete-toggle">
          <input type="checkbox" checked={deleteLoser} onChange={(e) => setDelete(e.target.checked)} />
          Delete loser
        </label>
        <button className="cf-btn cf-btn-a" disabled={busy} onClick={() => resolve("keep_a")}>Keep first</button>
        <button className="cf-btn cf-btn-b" disabled={busy} onClick={() => resolve("keep_b")}>Keep second</button>
        <button className="cf-btn cf-btn-dismiss" disabled={busy} onClick={() => resolve("dismiss")}>Dismiss</button>
      </div>
    </div>
  );
}

// ---- LEARNINGS SECTION ----
//  1. Generic lessons — manually added by the owner, apply to every agent.
//  2. Per-agent lessons — auto-extracted from conversations, per agent.
function LearningsSection({ agents = [], conflicts = [], genericLearnings = [], onGenericChange }) {
  const [addingGeneric, setAddingGeneric] = useState(false);
  const [draft, setDraft] = useState({ what: "", why: "" });
  const [saving, setSaving] = useState(false);
  const [removing, setRemoving] = useState(null);
  const [agentCollapsed, setAgentCollapsed] = useState({});
  const [detecting, setDetecting] = useState(false);
  const [customerNameMap, setCustomerNameMap] = useState({});

  // Fetch customer profiles once on mount to resolve raw IDs to names
  useEffect(() => {
    kFetch("/customers/memory")
      .then((profiles) => {
        const map = {};
        (profiles || []).forEach((p) => { if (p.from) map[p.from] = p.name; });
        setCustomerNameMap(map);
      })
      .catch(() => {}); // silently ignore — fallback to raw IDs
  }, []);

  const agentConflictsFor = (id) => conflicts.filter((c) => c.status === "open" && c.scope === "agent" && c.agentId === id);

  const detectConflicts = (agentId) => {
    setDetecting(true);
    kFetch("/conflicts/detect", {
      method: "POST",
      body: JSON.stringify(agentId ? { agentId } : {}),
    })
      .then((data) => {
        if (data.autoResolved > 0) {
          window.toast && window.toast(`Auto-resolved ${data.autoResolved} conflict${data.autoResolved === 1 ? "" : "s"}`, "good");
        } else if (data.found > 0) {
          window.toast && window.toast(`Found ${data.found} conflict${data.found === 1 ? "" : "s"} — review below`, "warn");
        } else {
          window.toast && window.toast("No conflicts found", "good");
        }
      })
      .catch((e) => window.toast && window.toast("Detection failed: " + e.message, "warn"))
      .finally(() => setDetecting(false));
  };

  const agentsWithLearnings = agents.filter((a) => (a.learnings || []).length > 0);
  const toggleAgent = (id) => setAgentCollapsed((p) => ({ ...p, [id]: !p[id] }));

  const addGeneric = () => {
    if (!draft.what.trim()) { window.toast && window.toast("Describe the lesson first", "warn"); return; }
    setSaving(true);
    kFetch("/learnings", {
      method: "POST",
      body: JSON.stringify({ what: draft.what.trim(), why: draft.why.trim() || null }),
    })
      .then((l) => {
        onGenericChange && onGenericChange([...genericLearnings, l]);
        setDraft({ what: "", why: "" });
        setAddingGeneric(false);
        window.toast && window.toast("Generic lesson added — all agents will use it", "good");
      })
      .catch((e) => window.toast && window.toast("Couldn't add: " + e.message, "warn"))
      .finally(() => setSaving(false));
  };

  const removeGeneric = (id) => {
    if (!window.confirm("Remove this lesson? All agents will stop using it.")) return;
    setRemoving(id);
    kFetch("/learnings/" + id, { method: "DELETE" })
      .then(() => {
        onGenericChange && onGenericChange(genericLearnings.filter((l) => l.id !== id));
        window.toast && window.toast("Lesson removed", "warn");
      })
      .catch((e) => window.toast && window.toast("Couldn't remove: " + e.message, "warn"))
      .finally(() => setRemoving(null));
  };

  const toggleGenericPriority = (id, current) => {
    const next = current === "high" ? "low" : "high";
    kFetch("/learnings/" + id, {
      method: "PATCH",
      body: JSON.stringify({ priority: next }),
    })
      .then((data) => {
        onGenericChange && onGenericChange(genericLearnings.map((l) => l.id === id ? { ...l, priority: next } : l));
        window.toast && window.toast(
          next === "high" ? "Marked high priority" : "Marked low priority",
          "good",
        );
      })
      .catch(() => window.toast && window.toast("Couldn't update priority", "warn"));
  };

  const unlearnAgent = (agentId, learningId) => {
    if (!window.confirm("Remove this learning? The agent will stop using it.")) return;
    setRemoving(learningId);
    kFetch(`/agents/${agentId}/learnings/${learningId}`, { method: "DELETE" })
      .then(() => window.toast && window.toast("Learning removed", "warn"))
      .catch((e) => window.toast && window.toast("Couldn't remove: " + e.message, "warn"))
      .finally(() => setRemoving(null));
  };

  const totalAgentLearnings = agentsWithLearnings.reduce((n, a) => n + (a.learnings || []).length, 0);

  const [knStatsRange, setKnStatsRange] = useState("alltime");

  const renderKnStats = () => {
    const allLearnings = agents.flatMap((a) => a.learnings || []);
    const todayStr = new Date().toLocaleDateString();
    const scoped = knStatsRange === "today"
      ? allLearnings.filter((l) => l.at && new Date(l.at).toLocaleDateString() === todayStr)
      : allLearnings;
    const disabled   = scoped.filter((l) => l.disabled).length;
    const active     = scoped.length - disabled;
    const high       = scoped.filter((l) => l.priority === "high").length;
    const low        = scoped.filter((l) => l.priority !== "high" && !l.disabled).length;
    const openConfs  = (conflicts || []).filter((c) => c.status === "open").length;
    return (
      <div className="kn-lstats-wrap">
        <div className="kn-lstats-header">
          <span className="kn-lstats-title">Learning stats</span>
          <div className="kn-lstats-toggle">
            <button className={`ad-lstats-btn${knStatsRange === "today" ? " is-on" : ""}`} onClick={() => setKnStatsRange("today")}>Today</button>
            <button className={`ad-lstats-btn${knStatsRange === "alltime" ? " is-on" : ""}`} onClick={() => setKnStatsRange("alltime")}>All time</button>
          </div>
        </div>
        <div className="kn-lstats-grid">
          {[
            ["Total lessons",   scoped.length, false],
            ["Active",          active,        false],
            ["Disabled",        disabled,      disabled > 0],
            ["High priority",   high,          false],
            ["Low priority",    low,           false],
            ["Contradictions",  openConfs,     openConfs > 0],
          ].map(([label, val, warn]) => (
            <div key={label} className="kn-lstats-cell">
              <div className={`kn-lstats-val${warn ? " kn-lstats-val--warn" : ""}`}>{val}</div>
              <div className="kn-lstats-label">{label}</div>
            </div>
          ))}
        </div>
      </div>
    );
  };

  return (
    <div className="kn-learn-wrap">
      {renderKnStats()}

      {/* ── Generic lessons ── */}
      <div className="kn-learn-section-hd">
        <div>
          <div className="kn-learn-title">Generic lessons</div>
          <div className="kn-learn-sub">Apply to every agent. Add lessons you want all agents to follow regardless of which conversations they've had.</div>
        </div>
        <button className="btn btn-ghost btn-sm" onClick={() => setAddingGeneric(!addingGeneric)}>
          {addingGeneric ? "Cancel" : "+ Add lesson"}
        </button>
      </div>

      {addingGeneric && (
        <div className="kn-learn-add">
          <input
            className="kn-learn-add-input"
            placeholder="The lesson (e.g. Always mention the 30-day return policy)"
            value={draft.what}
            onChange={(e) => setDraft((d) => ({ ...d, what: e.target.value }))}
            onKeyDown={(e) => { if (e.key === "Enter") addGeneric(); if (e.key === "Escape") setAddingGeneric(false); }}
            autoFocus
          />
          <input
            className="kn-learn-add-input"
            placeholder="Why (optional — e.g. Customers often ask about returns)"
            value={draft.why}
            onChange={(e) => setDraft((d) => ({ ...d, why: e.target.value }))}
            onKeyDown={(e) => { if (e.key === "Enter") addGeneric(); if (e.key === "Escape") setAddingGeneric(false); }}
          />
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn btn-primary btn-sm" onClick={addGeneric} disabled={saving}>{saving ? "Saving…" : "Add"}</button>
            <button className="btn btn-ghost btn-sm" onClick={() => { setAddingGeneric(false); setDraft({ what: "", why: "" }); }}>Cancel</button>
          </div>
        </div>
      )}

      {genericLearnings.length === 0 ? (
        <div className="kn-learn-empty">No generic lessons yet. Add one above and every agent will follow it.</div>
      ) : (
        <div className="kn-learn-list kn-learn-list-generic">
          {[...genericLearnings].reverse().map((l) => (
            <div key={l.id} className="kn-learn-row">
              <div className="kn-learn-bullet kn-learn-bullet-generic" />
              <div className="kn-learn-body">
                <div className="kn-learn-what" style={{ display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" }}>
                  <span>{l.what}</span>
                  <span
                    className={`ls-priority-badge ls-priority-${l.priority || "high"}`}
                    title={l.priority === "low"
                      ? "Low priority — memory can override this rule"
                      : "High priority — memory conflicts drop the memory fact"}
                  >{(l.priority || "high") === "high" ? "HIGH" : "LOW"}</span>
                  {(l.conflictCount || 0) > 0 && (
                    <span className="ls-conflict-count" title={`${l.conflictCount} customer memory fact${l.conflictCount === 1 ? "" : "s"} dropped to protect this rule`}>
                      {l.conflictCount} {l.conflictCount === 1 ? "customer" : "customers"}
                    </span>
                  )}
                </div>
                {l.why && <div className="kn-learn-why">Why: {l.why}</div>}
                <div className="kn-learn-meta">{l.at ? `Added ${timeAgo(l.at)}` : ""}<span className="kn-learn-badge">all agents</span></div>
              </div>
              <div style={{ display: "flex", gap: 4, alignItems: "center", flexShrink: 0 }}>
                {l.adminLocked ? (
                  <span className="kn-learn-badge" title="Set by your administrator — cannot be edited">admin</span>
                ) : (
                  <>
                    <button
                      className={`ls-priority-toggle ls-priority-toggle-${l.priority || "high"}`}
                      title={`Switch to ${(l.priority || "high") === "high" ? "low" : "high"} priority`}
                      onClick={() => toggleGenericPriority(l.id, l.priority || "high")}
                    >{(l.priority || "high") === "high" ? "↓ Low" : "↑ High"}</button>
                    <button
                      className="kn-learn-del"
                      title="Remove this lesson"
                      disabled={removing === l.id}
                      onClick={() => removeGeneric(l.id)}
                    >{removing === l.id ? "…" : "×"}</button>
                  </>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      {/* ── Per-agent lessons ── */}
      <div className="kn-learn-section-hd" style={{ marginTop: 24 }}>
        <div>
          <div className="kn-learn-title">Agent learnings</div>
          <div className="kn-learn-sub">
            Auto-extracted from each agent's conversations every 30 min.
            {totalAgentLearnings > 0 && ` ${totalAgentLearnings} lesson${totalAgentLearnings !== 1 ? "s" : ""} across ${agentsWithLearnings.length} agent${agentsWithLearnings.length !== 1 ? "s" : ""}.`}
            {" "}Remove any that seem wrong.
          </div>
        </div>
        <button className="btn btn-ghost btn-sm" disabled={detecting} onClick={() => detectConflicts(null)}>
          {detecting ? "Checking…" : "Check conflicts"}
        </button>
      </div>

      {agentsWithLearnings.length === 0 ? (
        <div className="kn-learn-empty">No learnings yet — agents start learning automatically once they've handled a few conversations.</div>
      ) : (
        <div className="kn-learn-agents">
          {agentsWithLearnings.map((a) => {
            const isOpen = !agentCollapsed[a.id];
            const learnings = [...(a.learnings || [])].reverse();
            const aConflicts = agentConflictsFor(a.id);
            const conflictBadge = aConflicts.length > 0 ? ` · ${aConflicts.length} conflict${aConflicts.length !== 1 ? "s" : ""}` : "";
            return (
              <div key={a.id} className="kn-learn-agent">
                <button className="kn-learn-agent-hd" onClick={() => toggleAgent(a.id)}>
                  <span className="kn-learn-agent-dot" style={{ background: a.palette?.skin || "#999" }} />
                  <span className="kn-learn-agent-name">{a.name}</span>
                  <span className="kn-learn-agent-ct">{learnings.length} lesson{learnings.length !== 1 ? "s" : ""}{conflictBadge && <span className="cf-agent-badge">{conflictBadge}</span>}</span>
                  <span className="kn-learn-agent-chev">{isOpen ? "▲" : "▼"}</span>
                </button>

                {isOpen && (
                  <div style={{ padding: "0 14px 14px" }}>
                    {aConflicts.length > 0 && (
                      <div className="cf-list" style={{ marginTop: 10 }}>
                        {aConflicts.map((c) => <ConflictCard key={c.id} conflict={c} />)}
                      </div>
                    )}
                    <div className="kn-learn-list" style={{ marginTop: aConflicts.length > 0 ? 10 : 0 }}>
                      {learnings.map((l, idx) => (
                        <div key={l.id || idx} className={`kn-learn-row${l.disabled ? " kn-learn-row--disabled" : ""}`}>
                          <div className="kn-learn-bullet" style={{ background: a.palette?.skin || "#999" }} />
                          <div className="kn-learn-body">
                            <div className="kn-learn-what">{l.what}</div>
                            {l.why && <div className="kn-learn-why">Why: {l.why}</div>}
                            {l.sourceQuote && <div className="kn-learn-quote">"{l.sourceQuote}"</div>}
                            <div className="kn-learn-meta">
                              {l.disabled ? <span className="cf-disabled-label">disabled</span> : (l.at ? `Learned ${timeAgo(l.at)}` : "")}
                              {l.sourceConvos && l.sourceConvos.length > 0 && (
                                <span className="kn-learn-src">
                                  {" · "}
                                  {l.sourceConvos.length} conversation{l.sourceConvos.length !== 1 ? "s" : ""}
                                  {" ("}
                                  {l.sourceConvos
                                    .filter((c, i, arr) => arr.findIndex((x) => x.from === c.from) === i)
                                    .map((c) => customerNameMap[c.from] || (c.from ? c.from.replace(/^[^:]+:/, "") : null) || c.channel || "?")
                                    .join(", ")}
                                  {")"}
                                </span>
                              )}
                            </div>
                          </div>
                          {l.id ? (
                            <button
                              className="kn-learn-del"
                              title="Remove this learning"
                              disabled={removing === l.id}
                              onClick={() => unlearnAgent(a.id, l.id)}
                            >{removing === l.id ? "…" : "×"}</button>
                          ) : null}
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// Inline picker — checkboxes for each agent + "Teach him" button.
function TeachPanel({ doc, agents, onCancel, onSave }) {
  const initial = Object.keys(doc.taught || {});
  const [picked, setPicked] = useState(new Set(initial));
  const toggle = (id) => {
    const next = new Set(picked);
    if (next.has(id)) next.delete(id); else next.add(id);
    setPicked(next);
  };
  const save = () => onSave(Array.from(picked));

  if (agents.length === 0) {
    return (
      <div style={{ padding: "12px 16px 16px 56px", borderTop: "1px solid var(--ink-line, rgba(0,0,0,.06))", color: "var(--ink-soft, #6b6660)" }}>
        Hire an agent first — then you can teach them this document.
        <div style={{ marginTop: 12 }}>
          <button className="btn btn-ghost btn-sm" onClick={onCancel}>Close</button>
        </div>
      </div>
    );
  }

  return (
    <div style={{ padding: "12px 16px 16px 56px", borderTop: "1px solid var(--ink-line, rgba(0,0,0,.06))" }}>
      <div style={{ marginBottom: 8, fontSize: 13, color: "var(--ink-soft, #6b6660)" }}>
        Pick which agents should read <strong>{doc.name}</strong>. They'll learn it once you click Teach. Unchecking an agent makes them forget it.
      </div>
      <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 12 }}>
        {agents.map((a) => {
          const on = picked.has(a.id);
          const learnedAt = doc.taught?.[a.id];
          return (
            <button
              key={a.id}
              type="button"
              onClick={() => toggle(a.id)}
              style={{
                display: "flex", alignItems: "center", gap: 8,
                padding: "8px 12px",
                border: on ? `2px solid ${a.palette?.skin || "#000"}` : "1px solid rgba(0,0,0,.12)",
                borderRadius: 999,
                background: on ? `${a.palette?.skin || "#000"}1A` : "transparent",
                cursor: "pointer",
                fontSize: 13,
                fontWeight: on ? 600 : 400,
              }}
            >
              <span style={{ display: "inline-block", width: 8, height: 8, borderRadius: 999, background: a.palette?.skin || "#999" }} />
              {a.name}
              {learnedAt ? <span style={{ fontSize: 11, opacity: 0.65 }}>· learned {timeAgo(learnedAt)}</span> : null}
            </button>
          );
        })}
      </div>
      <div style={{ display: "flex", gap: 8 }}>
        <button className="btn btn-primary btn-sm" onClick={save}>Save</button>
        <button className="btn btn-ghost btn-sm" onClick={onCancel}>Cancel</button>
      </div>
    </div>
  );
}

function timeAgo(iso) {
  if (!iso) return "—";
  const ms = Date.now() - new Date(iso).getTime();
  const min = Math.floor(ms / 60000);
  if (min < 1) return "just now";
  if (min < 60) return `${min}m ago`;
  const hr = Math.floor(min / 60);
  if (hr < 24) return `${hr}h ago`;
  return `${Math.floor(hr / 24)}d ago`;
}

window.KnowledgeTab = KnowledgeTab;
