// ============ AGENT DETAIL ============
// Drill-in view for a single agent. Mounts when AgentsTab calls onOpen(id).
// Pulls activity for this agent off the shared ACTIVITY dataset.

const _CharacterAvatar_detail = window.CharacterAvatar;

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

function adTimeAgo(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`;
  const d = Math.floor(hr / 24);
  return d === 1 ? "yesterday" : `${d}d ago`;
}

function AgentDetail({ agent, activity, threads, setThreads, agentLogs, conflicts = [], onRate, onUpdate }) {
  const a = agent;
  const feed = activity || ACTIVITY;
  const detailActivity = feed.filter(e => e.agent === a.id);

  // Real metrics derived from this agent's actual conversations.
  const stats = useMemo(() => computeAgentStats(a, threads || []), [a.id, threads]);

  const [brief, setBrief]         = useState(a.brief);
  const [editingBrief, setEditing]= useState(false);
  const [paused, setPaused]       = useState(false);
  const [note, setNote]           = useState("");
  const [thumbs, setThumbs]       = useState({}); // { [eventId]: "up" | "down" }
  const [learning, setLearning]   = useState(false);
  const [actTab, setActTab]       = useState("conversations"); // "conversations" | "activity" | "learnings" | "memory"
  const [statsRange, setStatsRange] = useState("alltime"); // "today" | "alltime"
  const [actPage, setActPage]     = useState(0);
  const ACT_PAGE_SIZE = 10;
  const logsEndRef = useRef(null);
  const [recentLogsLoading, setRecentLogsLoading] = useState(false);
  const [recentLogsLoaded, setRecentLogsLoaded]   = useState(false);
  const [fetchedLogs, setFetchedLogs]             = useState([]);

  // Auto-scroll live logs when new entries arrive.
  useEffect(() => {
    logsEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [(agentLogs || []).length]);

  // Load memory profiles on mount so learnings can show customer names.
  useEffect(() => {
    if (memoryProfiles === null) loadMemory();
  }, [a.id]);

  // Build a from → displayName lookup from loaded memory profiles.
  const profileNameMap = useMemo(() => {
    const map = {};
    for (const p of memoryProfiles || []) {
      map[p.from] = p.name || p.from.replace(/^[^:]+:/, "");
    }
    return map;
  }, [memoryProfiles]);

  // Reset local edits when navigating between agents.
  useEffect(() => {
    setBrief(a.brief);
    setEditing(false);
    setPaused(false);
    setNote("");
    setThumbs({});
    setActTab("conversations");
    setActPage(0);
    setMemoryProfiles(null);
    setEditingFact(null);
    setExpandedLesson(null);
    setExpandedConvId(null);
    setEditingBriefFrom(null);
    setEditBriefDraft("");
    setGeneratingBriefFrom(null);
    setRecentLogsLoaded(false);
    setFetchedLogs([]);
  }, [a.id]);

  const saveBrief = () => { setEditing(false); window.toast("Brief updated", "good"); };
  const cancelBrief = () => { setBrief(a.brief); setEditing(false); };
  const togglePause = () => {
    setPaused((p) => !p);
    window.toast(paused ? `${a.name} resumed` : `${a.name} paused`, paused ? "good" : "warn");
  };
  const saveFeedback = () => {
    window.toast(note.trim() ? "Feedback saved — thanks" : "Rating saved", "good");
    setNote("");
  };
  const setThumb = (id, kind) => {
    setThumbs((t) => ({ ...t, [id]: t[id] === kind ? null : kind }));
  };
  const [deletingLesson, setDeletingLesson] = useState(null);
  const [expandedLesson, setExpandedLesson] = useState(null);
  const [expandedConvId, setExpandedConvId] = useState(null);
  const [detectingConflicts, setDetectingConflicts] = useState(false);
  const agentConflicts = (conflicts || []).filter((c) => c.status === "open" && c.agentId === a.id);

  // Memory state — loaded when the "memory" tab is opened
  const [memoryProfiles, setMemoryProfiles]     = useState(null); // null = not loaded yet
  const [memoryLoading, setMemoryLoading]       = useState(false);
  const [deletingProfile, setDeletingProfile]   = useState(null);
  const [deletingFact, setDeletingFact]         = useState(null); // "from:idx"
  const [editingFact, setEditingFact]           = useState(null); // "from:idx"
  const [editFactDraft, setEditFactDraft]       = useState("");
  const [editingBriefFrom, setEditingBriefFrom] = useState(null); // customer `from` whose brief is being edited
  const [editBriefDraft, setEditBriefDraft]     = useState("");
  const [generatingBriefFrom, setGeneratingBriefFrom] = useState(null);

  const detectConflicts = () => {
    setDetectingConflicts(true);
    fetch(`${SERVER_URL_AD()}/conflicts/detect`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ agentId: a.id }),
    })
      .then((r) => r.json())
      .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(() => window.toast && window.toast("Detection failed", "warn"))
      .finally(() => setDetectingConflicts(false));
  };

  const resolveConflict = (conflictId, action, deleteLoser) => {
    fetch(`${SERVER_URL_AD()}/conflicts/${conflictId}/resolve`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ action, deleteLoser: !!deleteLoser }),
    })
      .then(() => window.toast && window.toast(action === "dismiss" ? "Conflict dismissed" : "Conflict resolved", "good"))
      .catch(() => window.toast && window.toast("Couldn't resolve", "warn"));
  };

  const unlearn = (lessonId) => {
    setDeletingLesson(lessonId);
    fetch(`${SERVER_URL_AD()}/agents/${a.id}/learnings/${lessonId}`, { method: "DELETE" })
      .then((r) => r.json())
      .then(() => {
        onUpdate && onUpdate({ learnings: (a.learnings || []).filter((l) => l.id !== lessonId) });
        window.toast && window.toast("Learning removed", "warn");
      })
      .catch(() => window.toast && window.toast("Couldn't remove", "warn"))
      .finally(() => setDeletingLesson(null));
  };

  const toggleLessonPriority = (lessonId, currentPriority) => {
    const next = currentPriority === "high" ? "low" : "high";
    fetch(`${SERVER_URL_AD()}/agents/${a.id}/learnings/${lessonId}`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ priority: next }),
    })
      .then((r) => r.json())
      .then((data) => {
        onUpdate && onUpdate({
          learnings: (a.learnings || []).map((l) => l.id === lessonId ? { ...l, priority: next } : l),
        });
        window.toast && window.toast(
          next === "high" ? "Marked high priority — memory conflicts will defer to this rule" : "Marked low priority — memory can override this rule",
          "good",
        );
      })
      .catch(() => window.toast && window.toast("Couldn't update priority", "warn"));
  };

  const reEnableLesson = (lessonId) => {
    fetch(`${SERVER_URL_AD()}/agents/${a.id}/learnings/${lessonId}`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ disabled: false }),
    })
      .then(() => {
        onUpdate && onUpdate({
          learnings: (a.learnings || []).map((l) => l.id === lessonId ? { ...l, disabled: false, disabledReason: undefined } : l),
        });
        window.toast && window.toast("Lesson re-enabled", "good");
      })
      .catch(() => window.toast && window.toast("Couldn't re-enable", "warn"));
  };

  const loadMemory = () => {
    setMemoryLoading(true);
    fetch(`${SERVER_URL_AD()}/customers/memory`)
      .then((r) => r.json())
      .then((data) => {
        // Filter by agentId — profiles carry it directly, no need to go through threads
        const filtered = (data.profiles || []).filter((p) => p.agentId === a.id);
        setMemoryProfiles(filtered);
      })
      .catch(() => { setMemoryProfiles([]); window.toast && window.toast("Couldn't load memory", "warn"); })
      .finally(() => setMemoryLoading(false));
  };

  const runExtraction = () => {
    setMemoryLoading(true);
    fetch(`${SERVER_URL_AD()}/customers/memory/run`, { method: "POST" })
      .then(() => setTimeout(loadMemory, 2000)) // give server a moment to finish
      .catch(() => { setMemoryLoading(false); window.toast && window.toast("Extraction failed", "warn"); });
  };

  const deleteProfile = (from) => {
    setDeletingProfile(from);
    fetch(`${SERVER_URL_AD()}/customers/${encodeURIComponent(from)}/memory`, { method: "DELETE" })
      .then(() => {
        setMemoryProfiles((prev) => (prev || []).filter((p) => p.from !== from));
        window.toast && window.toast("Customer memory cleared", "warn");
      })
      .catch(() => window.toast && window.toast("Couldn't clear memory", "warn"))
      .finally(() => setDeletingProfile(null));
  };

  const deleteFact = (from, idx) => {
    const key = `${from}:${idx}`;
    setDeletingFact(key);
    fetch(`${SERVER_URL_AD()}/customers/${encodeURIComponent(from)}/memory/${idx}`, { method: "DELETE" })
      .then((r) => r.json())
      .then((data) => {
        setMemoryProfiles((prev) => (prev || []).map((p) => p.from === from ? data.profile : p));
      })
      .catch(() => window.toast && window.toast("Couldn't remove fact", "warn"))
      .finally(() => setDeletingFact(null));
  };

  const saveFactEdit = (from, idx) => {
    if (!editFactDraft.trim()) return;
    fetch(`${SERVER_URL_AD()}/customers/${encodeURIComponent(from)}/memory/${idx}`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ what: editFactDraft.trim() }),
    })
      .then((r) => r.json())
      .then((data) => {
        setMemoryProfiles((prev) => (prev || []).map((p) => p.from === from ? data.profile : p));
        setEditingFact(null);
        window.toast && window.toast("Fact updated", "good");
      })
      .catch(() => window.toast && window.toast("Couldn't update fact", "warn"));
  };

  // Dismiss a conflict flag — keeps the fact but clears possibleConflict so
  // it will start being injected into the system prompt.
  const dismissConflict = (from, idx) => {
    fetch(`${SERVER_URL_AD()}/customers/${encodeURIComponent(from)}/memory/${idx}`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ dismissConflict: true }),
    })
      .then((r) => r.json())
      .then((data) => {
        setMemoryProfiles((prev) => (prev || []).map((p) => p.from === from ? data.profile : p));
        window.toast && window.toast("Conflict dismissed — fact will now be used", "good");
      })
      .catch(() => window.toast && window.toast("Couldn't dismiss conflict", "warn"));
  };

  const generateBrief = (from) => {
    setGeneratingBriefFrom(from);
    fetch(`${SERVER_URL_AD()}/customers/${encodeURIComponent(from)}/brief/generate`, { method: "POST" })
      .then((r) => r.json())
      .then(() => {
        window.toast && window.toast("Generating brief — refresh in a moment", "good");
        setTimeout(() => {
          loadMemory();
          setGeneratingBriefFrom(null);
        }, 4000);
      })
      .catch(() => {
        window.toast && window.toast("Brief generation failed", "warn");
        setGeneratingBriefFrom(null);
      });
  };

  const saveBriefEdit = (from) => {
    if (!editBriefDraft.trim()) return;
    fetch(`${SERVER_URL_AD()}/customers/${encodeURIComponent(from)}/brief`, {
      method: "PATCH",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ brief: editBriefDraft.trim() }),
    })
      .then((r) => r.json())
      .then((data) => {
        setMemoryProfiles((prev) => (prev || []).map((p) => p.from === from ? data.profile : p));
        setEditingBriefFrom(null);
        window.toast && window.toast("Brief updated", "good");
      })
      .catch(() => window.toast && window.toast("Couldn't update brief", "warn"));
  };

  const deleteBrief = (from) => {
    fetch(`${SERVER_URL_AD()}/customers/${encodeURIComponent(from)}/brief`, { method: "DELETE" })
      .then(() => {
        setMemoryProfiles((prev) => (prev || []).map((p) =>
          p.from === from ? { ...p, vipBrief: undefined, vipBriefAt: undefined, vipBriefFactCount: undefined } : p
        ));
        window.toast && window.toast("Brief removed", "warn");
      })
      .catch(() => window.toast && window.toast("Couldn't remove brief", "warn"));
  };

  const triggerLearn = () => {
    setLearning(true);
    fetch(`${SERVER_URL_AD()}/agents/${a.id}/learn`, { method: "POST" })
      .then((r) => r.json())
      .then((data) => {
        if (data.lessons && data.lessons.length > 0) {
          window.toast && window.toast(`${a.name} learned ${data.lessons.length} new lesson${data.lessons.length === 1 ? "" : "s"}`, "good");
        } else {
          window.toast && window.toast("Nothing new to learn right now — try after more conversations", "warn");
        }
      })
      .catch(() => window.toast && window.toast("Learning cycle failed", "warn"))
      .finally(() => setLearning(false));
  };

  return (
    <div className="ad-page">
      <div className="ad-hero">
        <div
          className="ad-avatar"
          style={{ background: `radial-gradient(circle at 30% 30%, ${a.palette.accent}, ${a.palette.skin} 60%, ${a.palette.skinDark})` }}
        >
          <_CharacterAvatar_detail palette={a.palette} glyph={a.glyph} size="lg" />
        </div>
        <div className="ad-hero-meta">
          <div className="ad-hero-row">
            <span className={`ag-pill ag-pill-${paused ? "training" : a.status}`}>
              <span className="ag-pill-dot" />
              {paused ? "paused" : (a.status === "live" ? "on shift" : "training")}
            </span>
            <span className="ad-version-badge" title="Knowledge rev · Learning generation">
              K{a.knowledgeRev || 0} · G{a.learningGen || 0}
            </span>
            <RatingStars value={a.rating} onChange={onRate} size="lg" />
          </div>
          <h2 className="ad-hero-name">{a.name}</h2>
          <p className="ad-hero-role">{a.role}</p>
          {editingBrief ? (
            <div className="ad-brief-edit">
              <textarea
                className="ad-rate-note"
                value={brief}
                onChange={(e) => setBrief(e.target.value)}
                rows={3}
                autoFocus
              />
              <div className="ad-brief-edit-cta">
                <button className="btn btn-primary btn-sm" onClick={saveBrief}>Save brief</button>
                <button className="btn btn-ghost btn-sm" onClick={cancelBrief}>Cancel</button>
              </div>
            </div>
          ) : (
            <blockquote className="ad-brief">"{brief}"</blockquote>
          )}
          <div className="ad-tools">
            {a.tools.map((t) => <span key={t} className="ad-tool">{t}</span>)}
          </div>
        </div>
        <div className="ad-hero-actions">
          <button className="btn btn-ghost btn-sm" onClick={() => setEditing(true)} disabled={editingBrief}>Edit brief</button>
          <button className="btn btn-ghost btn-sm" onClick={togglePause}>{paused ? "Resume" : "Pause"}</button>
          <button className="btn btn-ghost btn-sm ad-learn-btn" onClick={triggerLearn} disabled={learning}>
            {learning ? "Learning…" : "Improve now"}
          </button>
        </div>
      </div>

      <div className="ad-stats">
        <div className="ad-stat">
          <div className="ad-stat-v">{stats.tasksDone}</div>
          <div className="ad-stat-l">Tasks done</div>
        </div>
        <div className="ad-stat">
          <div className="ad-stat-v">{stats.avgReplyLabel}</div>
          <div className="ad-stat-l">Avg reply</div>
        </div>
        <div className="ad-stat">
          <div className="ad-stat-v">{stats.hoursSavedLabel}</div>
          <div className="ad-stat-l">Hours saved</div>
        </div>
        <div className="ad-stat">
          <div className="ad-stat-v">{stats.accuracyLabel}</div>
          <div className="ad-stat-l">Accuracy <span className="ad-stat-h">based on wrap-ups</span></div>
        </div>
      </div>

      <div className="ad-cols">
        <div className="ad-col-main">
          <div className="ad-section-h">This week</div>
          <div className="ad-perf">
            <Sparkline data={stats.spark} label="Tasks / day" color={a.palette.skin} />
            <div className="ad-perf-grid" style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 8 }}>
              {stats.last7.map((d, i) => {
                const isToday = i === stats.todayIndex;
                return (
                  <MiniBar
                    key={d.date}
                    label={isToday ? `${d.label} · today` : d.label}
                    v={d.count}
                    max={Math.max(1, ...stats.last7.map((x) => x.count))}
                    c={a.palette.skin}
                  />
                );
              })}
            </div>
          </div>

          <div className="ad-section-h" style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
            <span>Live logs</span>
            {!recentLogsLoaded && (
              <button
                className="btn btn-ghost btn-sm"
                disabled={recentLogsLoading}
                onClick={() => {
                  setRecentLogsLoading(true);
                  fetch(`${SERVER_URL_AD()}/agents/${a.id}/logs`)
                    .then((r) => r.json())
                    .then((logs) => {
                      setFetchedLogs(logs);
                      setRecentLogsLoaded(true);
                    })
                    .catch(() => window.toast && window.toast("Couldn't load logs", "warn"))
                    .finally(() => setRecentLogsLoading(false));
                }}
              >
                {recentLogsLoading ? "Loading…" : "Load recent"}
              </button>
            )}
          </div>
          <div className="ad-logs">
            {(() => {
              const liveLogs   = agentLogs || [];
              const liveTs     = new Set(liveLogs.map((l) => l.ts));
              const historical = (fetchedLogs || []).filter((l) => !liveTs.has(l.ts));
              const allLogs    = [...historical, ...liveLogs];
              if (allLogs.length === 0) {
                return <div className="ad-logs-empty">No activity yet — waiting for messages… or press "Load recent"</div>;
              }
              return allLogs.map((l, i) => (
                <div key={i} className={`ad-log-row ad-log-${l.level}`}>
                  <span className="ad-log-ts">{new Date(l.ts).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" })}</span>
                  <span className="ad-log-text">{l.text}</span>
                </div>
              ));
            })()}
            <div ref={logsEndRef} />
          </div>

          <div className="tl-tabs" style={{ marginBottom: 12 }}>
            <button
              className={`tl-tab ${actTab === "conversations" ? "is-on" : ""}`}
              onClick={() => setActTab("conversations")}
            >
              Messages
              {(() => {
                const unread = (threads || []).filter((t) => t.agent === a.id && t.unread).length;
                return unread > 0 ? <span className="cd-tab-badge" style={{ marginLeft: 6 }}>{unread}</span> : null;
              })()}
            </button>
            <button
              className={`tl-tab ${actTab === "activity" ? "is-on" : ""}`}
              onClick={() => { setActTab("activity"); setActPage(0); }}
            >Recent activity</button>
            <button
              className={`tl-tab ${actTab === "learnings" ? "is-on" : ""}`}
              onClick={() => setActTab("learnings")}
            >
              Learnings
              {(a.learnings || []).length > 0 && (
                <span className="cd-tab-badge" style={{ marginLeft: 6 }}>{(a.learnings || []).length}</span>
              )}
            </button>
            <button
              className={`tl-tab ${actTab === "memory" ? "is-on" : ""}`}
              onClick={() => { setActTab("memory"); if (!memoryProfiles) loadMemory(); }}
            >Memory</button>
          </div>

          {actTab === "conversations" && (() => {
            const agentThreads = [...(threads || []).filter((t) => t.agent === a.id)]
              .sort((x, y) => new Date(y.time || 0) - new Date(x.time || 0));
            const sendToThread = (threadId, text) => {
              if (!setThreads) return;
              const now = new Date();
              const tLabel = `${(now.getHours() % 12 || 12)}:${String(now.getMinutes()).padStart(2, "0")}`;
              setThreads((xs) => xs.map((x) =>
                x.id !== threadId ? x : {
                  ...x,
                  last: text,
                  time: "now",
                  unread: false,
                  status: x.status === "needs-you" ? "handled" : x.status,
                  transcript: [...(x.transcript || []), { from: a.id, text, t: tLabel, iso: now.toISOString() }],
                }
              ));
            };
            if (agentThreads.length === 0) {
              return <div className="ad-learnings-empty">No conversations yet for this agent.</div>;
            }
            return (
              <div className="ad-convs">
                {agentThreads.map((t) => (
                  <AdConvRow
                    key={t.id}
                    thread={t}
                    agentId={a.id}
                    expanded={expandedConvId === t.id}
                    onToggle={() => setExpandedConvId((id) => id === t.id ? null : t.id)}
                    onSend={(text) => sendToThread(t.id, text)}
                  />
                ))}
              </div>
            );
          })()}

          {actTab === "activity" && (() => {
            const totalPages = Math.max(1, Math.ceil(detailActivity.length / ACT_PAGE_SIZE));
            const page = Math.min(actPage, totalPages - 1);
            const pageItems = detailActivity.slice(page * ACT_PAGE_SIZE, (page + 1) * ACT_PAGE_SIZE);
            return (
              <>
                <div className="act-feed ad-feed">
                  {detailActivity.length === 0 ? (
                    <div className="ad-learnings-empty">No activity yet.</div>
                  ) : pageItems.map((e) => {
                    const v = thumbs[e.id];
                    return (
                      <div key={e.id} className="act-row">
                        <div className="act-time">{e.t}</div>
                        <div className={`act-dot act-dot-${e.k}`} />
                        <div className="act-body">
                          <div className="act-text">{e.text}</div>
                          {e.why && <div className="act-why">{e.why}</div>}
                        </div>
                        <div className="act-actions">
                          {e.lessonId && (
                            <button
                              className="act-thumb act-thumb-down"
                              onClick={() => unlearn(e.lessonId)}
                              disabled={deletingLesson === e.lessonId}
                              aria-label="Remove learning"
                              title="Remove this learning"
                            >✕</button>
                          )}
                          <button
                            className={`act-thumb ${v === "up" ? "is-on" : ""}`}
                            onClick={() => { setThumb(e.id, "up");   window.toast("Thanks — noted as good", "good"); }}
                            aria-label="Good"
                          >↑</button>
                          <button
                            className={`act-thumb act-thumb-down ${v === "down" ? "is-on" : ""}`}
                            onClick={() => { setThumb(e.id, "down"); window.toast(`${a.name} will adjust`, "warn"); }}
                            aria-label="Needs work"
                          >↓</button>
                        </div>
                      </div>
                    );
                  })}
                </div>
                {totalPages > 1 && (
                  <div className="ad-pagination">
                    <button
                      className="ad-page-btn"
                      onClick={() => setActPage((p) => Math.max(0, p - 1))}
                      disabled={page === 0}
                    >← Prev</button>
                    <span className="ad-page-info">{page + 1} / {totalPages}</span>
                    <button
                      className="ad-page-btn"
                      onClick={() => setActPage((p) => Math.min(totalPages - 1, p + 1))}
                      disabled={page === totalPages - 1}
                    >Next →</button>
                  </div>
                )}
              </>
            );
          })()}

          {actTab === "learnings" && (
            <div className="ad-learnings">
              <div className="ad-learnings-toolbar">
                <button className="btn btn-ghost btn-sm" disabled={detectingConflicts} onClick={detectConflicts}>
                  {detectingConflicts ? "Checking…" : "Check conflicts"}
                </button>
              </div>
              {agentConflicts.length > 0 && (
                <div className="cf-list" style={{ marginBottom: 12 }}>
                  {agentConflicts.map((c) => (
                    <AgentConflictCard key={c.id} conflict={c} onResolve={resolveConflict} />
                  ))}
                </div>
              )}
              {(a.learnings || []).length === 0 ? (
                <div className="ad-learnings-empty">No learnings yet — {a.name} will start learning automatically after a few conversations.</div>
              ) : (
                [...(a.learnings || [])].reverse().map((l, idx) => {
                  const cardKey = l.id || idx;
                  const isExpanded = expandedLesson === cardKey;
                  const uniqueConvos = l.sourceConvos
                    ? [...new Map(l.sourceConvos.map((c) => [c.from || c.channel || "?", c])).values()]
                    : [];
                  return (
                    <div
                      key={cardKey}
                      className={`ad-learning-row${l.disabled ? " ad-learning-row--disabled" : ""}`}
                      onClick={() => setExpandedLesson(isExpanded ? null : cardKey)}
                    >
                      {/* Always-visible header row */}
                      <div style={{ display: "flex", alignItems: "flex-start", gap: 8 }}>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div className="ad-learning-what" style={{ display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap" }}>
                            <span>{l.what}</span>
                            <span
                              className={`ls-priority-badge ls-priority-${l.priority || "low"}`}
                              title={l.priority === "high"
                                ? "High priority — memory conflicts drop the memory fact"
                                : "Low priority — memory conflicts disable this rule"}
                            >{l.priority === "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>
                          <div className="ad-learning-at" style={{ marginTop: 3 }}>
                            {l.disabled ? (
                              <>
                                <span className="cf-disabled-label">disabled</span>
                                {l.id && <button className="ls-reenable-btn" onClick={(e) => { e.stopPropagation(); reEnableLesson(l.id); }}>Re-enable</button>}
                              </>
                            ) : (
                              <>
                                {l.at && adTimeAgo(l.at) && `Learned ${adTimeAgo(l.at)}`}
                                {uniqueConvos.length > 0 && (
                                  <span> · From {uniqueConvos.length} conversation{uniqueConvos.length !== 1 ? "s" : ""}</span>
                                )}
                              </>
                            )}
                          </div>
                        </div>
                        <div style={{ display: "flex", gap: 4, alignItems: "center", flexShrink: 0 }}>
                          <span className="ad-learning-expand-icon">{isExpanded ? "▲" : "▼"}</span>
                          {l.id && (
                            <button
                              className={`ls-priority-toggle ls-priority-toggle-${l.priority || "low"}`}
                              title={`Switch to ${l.priority === "high" ? "low" : "high"} priority`}
                              onClick={(e) => { e.stopPropagation(); toggleLessonPriority(l.id, l.priority || "low"); }}
                            >{l.priority === "high" ? "↓ Low" : "↑ High"}</button>
                          )}
                          {l.id && (
                            <button
                              className="kn-learn-del"
                              title="Remove this learning"
                              disabled={deletingLesson === l.id}
                              onClick={(e) => { e.stopPropagation(); unlearn(l.id); }}
                            >{deletingLesson === l.id ? "…" : "×"}</button>
                          )}
                        </div>
                      </div>

                      {/* Expanded detail section */}
                      {isExpanded && (
                        <div className="ad-learning-body">
                          {l.why && (
                            <div>
                              <div className="ad-learning-body-label">Why</div>
                              <div className="ad-learning-why">{l.why}</div>
                              {l.disabledReason && (
                                <div className="ad-learning-why" style={{ color: "#D17C2A", marginTop: 2 }}>Disabled: {l.disabledReason}</div>
                              )}
                            </div>
                          )}
                          {l.sourceQuote && (
                            <div>
                              <div className="ad-learning-body-label">Triggered by</div>
                              <div className="ad-learning-quote">"{l.sourceQuote}"</div>
                            </div>
                          )}
                          {uniqueConvos.length > 0 && (
                            <div>
                              <div className="ad-learning-body-label">Source conversations</div>
                              <div className="ad-learning-src-pills">
                                {uniqueConvos.map((c, i) => {
                                  const key = c.from || c.channel || "?";
                                  const name = profileNameMap[key] || key.replace(/^[^:]+:/, "") || key;
                                  const matchThread = (threads || []).find((t) =>
                                    t.agent === a.id && (t.from === c.from || t.id === c.from)
                                  );
                                  return (
                                    <span
                                      key={i}
                                      className={`ad-learning-src-pill${matchThread ? " ad-learning-src-pill--link" : ""}`}
                                      title={matchThread ? "Jump to this conversation" : undefined}
                                      onClick={matchThread ? (e) => {
                                        e.stopPropagation();
                                        setActTab("conversations");
                                        setExpandedConvId(matchThread.id);
                                      } : undefined}
                                    >
                                      {name}
                                      {c.channel && <span className="ad-learning-src-channel">{c.channel}</span>}
                                      {matchThread && <span className="ad-learning-src-goto">↗</span>}
                                    </span>
                                  );
                                })}
                              </div>
                            </div>
                          )}
                          {!l.why && l.disabledReason && (
                            <div className="ad-learning-why" style={{ color: "#D17C2A" }}>Disabled: {l.disabledReason}</div>
                          )}
                        </div>
                      )}
                    </div>
                  );
                })
              )}
            </div>
          )}

          {actTab === "memory" && (
            <div className="ad-memory">
              <div className="ad-learnings-toolbar">
                <button className="btn btn-ghost btn-sm" onClick={loadMemory} disabled={memoryLoading}>
                  {memoryLoading ? "Loading…" : "Refresh"}
                </button>
                <button className="btn btn-ghost btn-sm" onClick={runExtraction} disabled={memoryLoading} title="Extract memory from all wrapped conversations now">
                  Run extraction
                </button>
              </div>
              {memoryLoading && !memoryProfiles ? (
                <div className="ad-learnings-empty">Loading customer memory…</div>
              ) : !memoryProfiles || memoryProfiles.length === 0 ? (
                <div className="ad-learnings-empty">
                  No customer memory yet. Memory is extracted from conversations after they wrap up.
                </div>
              ) : (
                memoryProfiles.map((profile) => {
                  const hasBrief = !!(profile.vipBrief && profile.vipBriefAt);
                  const deltaCount = hasBrief
                    ? (profile.facts || []).filter((f) => f.ts > new Date(profile.vipBriefAt).getTime()).length
                    : 0;
                  const isEditingBrief = editingBriefFrom === profile.from;
                  const isGenerating   = generatingBriefFrom === profile.from;
                  return (
                    <div key={profile.from} className="ad-mem-profile">
                      <div className="ad-mem-profile-header">
                        <div className="ad-mem-profile-name">
                          {profile.name || profile.from}
                          {profile.name && <span className="ad-mem-profile-from">{profile.from}</span>}
                        </div>
                        <div className="ad-mem-profile-meta">
                          {(profile.facts || []).length} fact{(profile.facts || []).length !== 1 ? "s" : ""}
                          {profile.lastSeen ? ` · Last seen ${adTimeAgo(new Date(profile.lastSeen).toISOString())}` : ""}
                        </div>
                        <button
                          className="btn btn-ghost btn-sm ad-mem-forget"
                          onClick={() => deleteProfile(profile.from)}
                          disabled={deletingProfile === profile.from}
                          title="Forget this customer"
                        >
                          {deletingProfile === profile.from ? "…" : "Forget"}
                        </button>
                      </div>

                      {/* VIP Brief section */}
                      <div className="ad-mem-brief-wrap">
                        <div className="ad-mem-brief-header">
                          <span className={`ad-mem-brief-label${hasBrief ? " has-brief" : ""}`}>
                            {hasBrief ? "Customer brief" : "No brief yet"}
                          </span>
                          {hasBrief && deltaCount > 0 && (
                            <span className="ad-mem-brief-delta" title="Facts added after brief was generated">
                              {deltaCount} new fact{deltaCount !== 1 ? "s" : ""}
                            </span>
                          )}
                          <div className="ad-mem-brief-actions">
                            {hasBrief && !isEditingBrief && (
                              <>
                                <button
                                  className="ad-mem-fact-btn"
                                  onClick={() => { setEditingBriefFrom(profile.from); setEditBriefDraft(profile.vipBrief); }}
                                  title="Edit brief"
                                >&#9998;</button>
                                <button
                                  className="ad-mem-fact-btn"
                                  onClick={() => generateBrief(profile.from)}
                                  disabled={isGenerating}
                                  title="Regenerate brief from current facts"
                                >{isGenerating ? "…" : "↺"}</button>
                                <button
                                  className="ad-mem-fact-btn ad-mem-fact-del"
                                  onClick={() => deleteBrief(profile.from)}
                                  title="Remove brief"
                                >×</button>
                              </>
                            )}
                            {!hasBrief && (
                              <button
                                className="btn btn-ghost btn-sm"
                                onClick={() => generateBrief(profile.from)}
                                disabled={isGenerating || (profile.facts || []).length === 0}
                                title="Generate a brief from stored facts"
                              >{isGenerating ? "Generating…" : "Generate brief"}</button>
                            )}
                          </div>
                        </div>
                        {hasBrief && !isEditingBrief && (
                          <div className="ad-mem-brief-text">{profile.vipBrief}</div>
                        )}
                        {hasBrief && isEditingBrief && (
                          <div className="ad-mem-brief-edit-wrap">
                            <textarea
                              className="ad-mem-brief-textarea"
                              value={editBriefDraft}
                              onChange={(e) => setEditBriefDraft(e.target.value)}
                              rows={4}
                              autoFocus
                            />
                            <div className="ad-mem-brief-edit-cta">
                              <button className="btn btn-primary btn-sm" onClick={() => saveBriefEdit(profile.from)}>Save</button>
                              <button className="btn btn-ghost btn-sm" onClick={() => setEditingBriefFrom(null)}>Cancel</button>
                            </div>
                          </div>
                        )}
                      </div>

                      <div className="ad-mem-facts">
                        {(!profile.facts || profile.facts.length === 0) ? (
                          <div className="ad-mem-fact-empty">No facts stored.</div>
                        ) : profile.facts.map((fact, idx) => {
                          const editKey = `${profile.from}:${idx}`;
                          const isEditing = editingFact === editKey;
                          const isNew = hasBrief && fact.ts > new Date(profile.vipBriefAt).getTime();
                          return (
                            <div key={idx} className={`ad-mem-fact-row${isNew ? " ad-mem-fact-row--new" : ""}`}>
                              {isEditing ? (
                                <div className="ad-mem-fact-edit">
                                  <input
                                    className="set-input"
                                    value={editFactDraft}
                                    onChange={(e) => setEditFactDraft(e.target.value)}
                                    onKeyDown={(e) => {
                                      if (e.key === "Enter") saveFactEdit(profile.from, idx);
                                      if (e.key === "Escape") setEditingFact(null);
                                    }}
                                    autoFocus
                                  />
                                  <button className="btn btn-primary btn-sm" onClick={() => saveFactEdit(profile.from, idx)}>Save</button>
                                  <button className="btn btn-ghost btn-sm" onClick={() => setEditingFact(null)}>Cancel</button>
                                </div>
                              ) : (
                                <>
                                  <div className="ad-mem-fact-what">
                                    {isNew && <span className="ad-mem-fact-new-badge" title="Added after brief was generated">new</span>}
                                    {fact.what}
                                  </div>
                                  {fact.quote && <div className="ad-mem-fact-quote">"{fact.quote}"</div>}
                                  <div className="ad-mem-fact-actions">
                                    <button
                                      className="ad-mem-fact-btn"
                                      onClick={() => { setEditingFact(editKey); setEditFactDraft(fact.what); }}
                                      title="Edit"
                                    >&#9998;</button>
                                    <button
                                      className="ad-mem-fact-btn ad-mem-fact-del"
                                      onClick={() => deleteFact(profile.from, idx)}
                                      disabled={deletingFact === editKey}
                                      title="Remove"
                                    >{deletingFact === editKey ? "…" : "×"}</button>
                                  </div>
                                </>
                              )}
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  );
                })
              )}
            </div>
          )}
        </div>

        <aside className="ad-col-side">
          <div className="ad-section-h">Rate it</div>
          <div className="ad-rate-card">
            <div className="ad-rate-label">How is {a.name} doing?</div>
            <RatingStars value={a.rating} onChange={onRate} size="lg" />
            <div className="ad-rate-help">Your rating teaches it what good looks like. Be honest.</div>
            <textarea
              className="ad-rate-note"
              placeholder="Optional — what should it do differently?"
              rows={3}
              value={note}
              onChange={(e) => setNote(e.target.value)}
            />
            <button className="btn btn-primary btn-sm ad-rate-submit" onClick={saveFeedback}>Save feedback</button>
          </div>

          <div className="ad-lstats-header">
            <div className="ad-section-h" style={{ marginBottom: 0 }}>Learnings</div>
            <div className="ad-lstats-toggle">
              <button
                className={`ad-lstats-btn${statsRange === "today" ? " is-on" : ""}`}
                onClick={() => setStatsRange("today")}
              >Today</button>
              <button
                className={`ad-lstats-btn${statsRange === "alltime" ? " is-on" : ""}`}
                onClick={() => setStatsRange("alltime")}
              >All time</button>
            </div>
          </div>
          <div className="ad-lstats-card">
            {(() => {
              const todayStr = new Date().toLocaleDateString();
              const all = a.learnings || [];
              const scoped = statsRange === "today"
                ? all.filter((l) => l.at && new Date(l.at).toLocaleDateString() === todayStr)
                : all;
              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 = agentConflicts.length;
              return [
                ["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="ad-lstats-row">
                  <span className="ad-lstats-label">{label}</span>
                  <span className={`ad-lstats-val${warn ? " ad-lstats-val--warn" : ""}`}>{val}</span>
                </div>
              ));
            })()}
          </div>

          <div className="ad-section-h">Channels</div>
          <ChannelsPanel agent={a} onUpdate={onUpdate} />

          <div className="ad-section-h">Settings</div>
          <div className="ad-settings">
            <SettingRow l="Approval gate" v={a.approvalGate || ""} placeholder="e.g. Loop you in over $10k"
              onSave={(val) => onUpdate && onUpdate({ approvalGate: val })} />
            <SettingRow l="Quiet hours"   v={a.quietHours || ""}   placeholder="e.g. 9pm — 7am Cairo time"
              onSave={(val) => onUpdate && onUpdate({ quietHours: val })} />
            <SettingRow l="Escalate to"   v={a.escalateTo || ""}   placeholder="e.g. you@example.com"
              onSave={(val) => onUpdate && onUpdate({ escalateTo: val })} />
            <SettingRow l="Tools"         v={(a.tools || []).join(", ")} placeholder="e.g. search, calendar"
              onSave={(val) => onUpdate && onUpdate({ tools: val.split(",").map((s) => s.trim()).filter(Boolean) })} />
          </div>
        </aside>
      </div>
    </div>
  );
}

// Per-agent channel routing — which WhatsApp number this agent handles.
function ChannelsPanel({ agent, onUpdate }) {
  const channels = agent.channels || {};
  const [waNum, setWaNum] = useState(channels.whatsappNumber || "");
  const [savedAt, setSavedAt] = useState(null);

  useEffect(() => { setWaNum(channels.whatsappNumber || ""); }, [agent.id]);

  const flash = () => { setSavedAt(Date.now()); setTimeout(() => setSavedAt(null), 1400); };

  const saveWaNum = () => {
    if (!onUpdate) return;
    const trimmed = waNum.trim();
    onUpdate({ channels: { ...channels, whatsappNumber: trimmed } });
    flash();
    window.toast && window.toast(
      trimmed
        ? `${agent.name} now handles WhatsApp ${trimmed}`
        : `${agent.name} no longer handles a specific WhatsApp number`,
      "good"
    );
  };

  return (
    <div className="ad-channels">
      <div className="ad-chan-row">
        <div className="ad-chan-meta">
          <div className="ad-chan-l">WhatsApp number</div>
          <div className="ad-chan-h">Inbound to this Meta WhatsApp number routes here. Use E.164 format (e.g. +201001234567). Leave blank if your business has only one number.</div>
        </div>
        <div className="ad-chan-input-row">
          <input
            className="set-input"
            placeholder="+14155551234"
            value={waNum}
            onChange={(e) => setWaNum(e.target.value)}
            onKeyDown={(e) => { if (e.key === "Enter") saveWaNum(); }}
            onBlur={saveWaNum}
          />
        </div>
      </div>
      {savedAt ? <div className="ad-chan-saved">Saved · synced to runtime server</div> : null}
    </div>
  );
}

function MiniBar({ label, v, max, c }) {
  const pct = Math.round((v / max) * 100);
  return (
    <div className="mb">
      <div className="mb-bar"><div className="mb-fill" style={{ height: pct + "%", background: c }} /></div>
      <div className="mb-l">{label}</div>
    </div>
  );
}

function SettingRow({ l, v, placeholder, onSave }) {
  const [val, setVal] = useState(v);
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState(v);
  // Sync when agent switches
  useEffect(() => { setVal(v); setDraft(v); }, [v]);
  const start = () => { setDraft(val); setEditing(true); };
  const save  = () => {
    setVal(draft);
    setEditing(false);
    onSave && onSave(draft);
    window.toast(`${l} updated`, "good");
  };
  const cancel = () => setEditing(false);
  if (editing) {
    return (
      <div className="set-row set-row-editing">
        <div className="set-l">{l}</div>
        <input
          className="set-input"
          value={draft}
          placeholder={placeholder}
          onChange={(e) => setDraft(e.target.value)}
          onKeyDown={(e) => { if (e.key === "Enter") save(); if (e.key === "Escape") cancel(); }}
          autoFocus
        />
        <button className="set-edit" onClick={save}>Save</button>
        <button className="set-edit" onClick={cancel}>Cancel</button>
      </div>
    );
  }
  return (
    <div className="set-row">
      <div className="set-l">{l}</div>
      <div className={`set-v${!val ? " set-v--empty" : ""}`}>{val || placeholder || "—"}</div>
      <button className="set-edit" onClick={start}>Edit</button>
    </div>
  );
}

// Compute per-agent metrics from this agent's conversations:
//   tasksDone:   total agent messages (real run count)
//   avgReplySec: avg seconds between a customer message and the agent's reply
//   hoursSaved:  tasksDone × 4 min heuristic (a real human would spend ~4 min/reply)
//   accuracy:    % of wrapped-up convos with a positive outcome (lead/booked)
//   last7:       array of { date, label, count } for the 7 days ending today,
//                using the user's local calendar — every day counts, not just weekdays.
//   spark:       12 daily counts ending today, for the trend line
function computeAgentStats(agent, threads) {
  const myThreads = threads.filter((t) => t.agent === agent.id);

  // Walk transcripts, count agent messages + measure reply latency.
  let tasksDone = 0;
  let replyMs = 0;
  let replySamples = 0;
  const dailyCounts = {};
  for (const t of myThreads) {
    let lastCustomerIso = null;
    for (const m of t.transcript || []) {
      if (m.from === "customer") {
        lastCustomerIso = m.iso || null;
      } else if (m.from === "agent") {
        tasksDone++;
        if (m.iso) {
          const day = isoLocalDay(m.iso);
          dailyCounts[day] = (dailyCounts[day] || 0) + 1;
        }
        if (lastCustomerIso && m.iso) {
          const ms = new Date(m.iso) - new Date(lastCustomerIso);
          if (ms > 0 && ms < 3600 * 1000) {
            replyMs += ms;
            replySamples++;
          }
          lastCustomerIso = null;
        }
      }
    }
  }

  // Wrap-up outcome accuracy: positive = lead/booked, neutral = closed.
  const wrapped = myThreads.filter((t) => t.status === "handled");
  const positive = wrapped.filter((t) => t.tag && /lead|book/i.test(t.tag)).length;
  const accuracy = wrapped.length === 0 ? null : Math.round((positive / wrapped.length) * 100);

  // This calendar week, starting Sunday (Egypt convention) → Saturday.
  // Days that haven't happened yet show 0; today is highlighted by index.
  const today = new Date();
  const sunday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - today.getDay());
  const last7 = [];
  for (let i = 0; i < 7; i++) {
    const d = new Date(sunday.getFullYear(), sunday.getMonth(), sunday.getDate() + i);
    const key = isoLocalDay(d.toISOString());
    last7.push({
      date: key,
      label: d.toLocaleDateString(undefined, { weekday: "short" }),
      count: dailyCounts[key] || 0,
    });
  }
  const todayIndex = today.getDay();

  // 12-point sparkline = last 12 days for a wider trend visual.
  const spark = [];
  for (let i = 11; i >= 0; i--) {
    const d = new Date(today.getFullYear(), today.getMonth(), today.getDate() - i);
    spark.push(dailyCounts[isoLocalDay(d.toISOString())] || 0);
  }

  const avgReplySec = replySamples === 0 ? null : Math.round(replyMs / replySamples / 1000);
  const hoursSaved = Math.round((tasksDone * 4) / 60 * 10) / 10;

  return {
    tasksDone,
    avgReplyLabel: avgReplySec === null ? "—" : avgReplySec < 60 ? `${avgReplySec}s` : `${Math.round(avgReplySec / 60)}m`,
    hoursSavedLabel: tasksDone === 0 ? "0" : (hoursSaved < 1 ? `${Math.round(hoursSaved * 60)}m` : `${hoursSaved}h`),
    accuracyLabel: accuracy === null ? "—" : `${accuracy}%`,
    last7,
    todayIndex,
    spark,
  };
}

// Date → local-calendar "YYYY-MM-DD" so days bucket per the user's timezone.
function isoLocalDay(iso) {
  const d = new Date(iso);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

// Expandable row for a single conversation thread in the Messages tab.
function AdConvRow({ thread: t, agentId, expanded: open, onToggle, onSend }) {
  const [reply, setReply] = useState("");
  useEffect(() => { if (!open) setReply(""); }, [open]);
  const statusLabel = t.status === "needs-you" ? "needs you" : t.status === "handled" ? "handled" : "open";
  const statusCls   = t.status === "needs-you" ? "warn" : t.status === "handled" ? "ok" : "info";
  const channelIcon = t.channel === "whatsapp" ? "WA" : (t.channel || "?").toUpperCase().slice(0, 2);

  const handleSend = () => {
    const text = reply.trim();
    if (!text) return;
    onSend && onSend(text);
    setReply("");
  };

  return (
    <div className="ad-conv-row">
      <div className="ad-conv-header" onClick={onToggle} style={{ cursor: "pointer" }}>
        <span className="ad-conv-channel">{channelIcon}</span>
        <span className="ad-conv-name">{t.customer || t.from || "Unknown"}</span>
        {t.unread ? <span className="ad-conv-unread" /> : null}
        <span className={`ad-conv-status ad-conv-status--${statusCls}`}>{statusLabel}</span>
        <span className="ad-conv-time">{t.time ? adTimeAgo(t.time) : ""}</span>
        <span className="ad-conv-chev">{open ? "▲" : "▼"}</span>
      </div>
      {t.last && !open && <div className="ad-conv-last">{t.last}</div>}
      {open && (
        <>
          <div className="ad-conv-transcript">
            {(t.transcript || []).length === 0 ? (
              <div className="ad-conv-empty">No messages yet.</div>
            ) : (t.transcript || []).map((m, i) => {
              const isAgent = m.from === agentId || m.from === "agent";
              return (
                <div key={i} className={`ad-conv-msg ad-conv-msg--${isAgent ? "agent" : "customer"}`}>
                  <span className="ad-conv-msg-who">{isAgent ? "Agent" : "Customer"}</span>
                  <span className="ad-conv-msg-text">{m.text}</span>
                  {m.iso && <span className="ad-conv-msg-ts">{new Date(m.iso).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</span>}
                </div>
              );
            })}
          </div>
          <div className="ad-conv-composer">
            <textarea
              className="ad-conv-input"
              placeholder="Reply as agent…"
              value={reply}
              rows={2}
              onChange={(e) => setReply(e.target.value)}
              onKeyDown={(e) => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); handleSend(); } }}
            />
            <div className="ad-conv-composer-row">
              <span className="ad-conv-composer-hint">⌘↵ to send</span>
              <button className="btn btn-primary btn-sm" onClick={handleSend} disabled={!reply.trim()}>Send</button>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

function AgentConflictCard({ conflict, onResolve }) {
  const [busy, setBusy]         = useState(false);
  const [deleteLoser, setDelete] = useState(false);

  const resolve = (action) => {
    setBusy(true);
    onResolve && onResolve(conflict.id, action, deleteLoser);
    setTimeout(() => setBusy(false), 800);
  };

  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>
  );
}

window.AgentDetail = AgentDetail;
