/* @jsxRuntime classic */
/* @jsx React.createElement */
// Orchestra — The Bench (Bench Phase-2, task 86banqh7q)
// Per-Wright operating memory surface. Read-only by default;
// Approve/Edit/Dismiss shown when the "advanced" toggle is on.
// Loaded by index.html as a separate text/babel script; exposes window.AgentContextPage.

(function () {
  const { useState, useEffect, useCallback } = React;

  // ── API helper (mirrors app.jsx's api()) ──────────────────────────────────
  function toCamel(s) { return s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()); }
  function deepCamel(obj) {
    if (Array.isArray(obj)) return obj.map(deepCamel);
    if (obj && typeof obj === 'object') {
      const out = {};
      for (const k of Object.keys(obj)) out[toCamel(k)] = deepCamel(obj[k]);
      return out;
    }
    return obj;
  }
  async function api(method, path, body) {
    const opts = { method, headers: { 'Content-Type': 'application/json' } };
    if (body !== undefined) opts.body = JSON.stringify(body);
    const res = await fetch(path, opts);
    if (!res.ok) { const t = await res.text().catch(() => ''); throw new Error(`${res.status}: ${t}`); }
    if (res.status === 204) return null;
    return deepCamel(await res.json());
  }

  // ── Lineage chip text for a learned item ──────────────────────────────────
  function lineageText(item) {
    if (item.provenance === 'kb-propagation') return 'Propagated from Knowledge Base';
    if (item.provenance === 'human') return 'Human-authored';
    const runPart = item.sourceRunId ? `Build #${item.sourceRunId}` : 'a Build';
    const stagePart = item.sourceStage ? ` · ${item.sourceStage}` : '';
    const reviewerPart = item.sourceReviewer ? ` → ${item.sourceReviewer} review gate` : '';
    return `Learned from ${runPart}${stagePart}${reviewerPart}`;
  }

  // ── Category label prettifier ─────────────────────────────────────────────
  function catLabel(slug) {
    return (slug || 'general').replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
  }

  // ── Confidence bar ────────────────────────────────────────────────────────
  function ConfBar({ value }) {
    const pct = Math.round((value || 0) * 100);
    const color = pct >= 70 ? '#4ade80' : pct >= 40 ? '#c8a84a' : '#e08080';
    return (
      <div className="ac-conf-bar" title={`Confidence: ${pct}%`}>
        <div className="ac-conf-fill" style={{ width: `${pct}%`, background: color }} />
      </div>
    );
  }

  // ── Single Bench item card ────────────────────────────────────────────────
  function ItemCard({ item, advanced, onApprove, onDismiss }) {
    const isPinned = item.itemType === 'pinned';
    return (
      <div className={`ac-item ${isPinned ? 'ac-item-pinned' : ''}`}>
        <div className="ac-item-head">
          <span className={`ac-type-badge ${isPinned ? 'pinned' : 'learned'}`}>
            {isPinned ? '📌 Pinned' : '💡 Learned'}
          </span>
          {item.category && (
            <span className="ac-cat-chip">{catLabel(item.category)}</span>
          )}
          {!isPinned && (
            <ConfBar value={item.confidence} />
          )}
        </div>
        <div className="ac-item-content">{item.content}</div>
        {!isPinned && (
          <div className="ac-lineage">{lineageText(item)}</div>
        )}
        {advanced && (
          <div className="ac-item-actions">
            {!isPinned && (
              <button className="btn btn-sm btn-outline ac-action-btn"
                onClick={() => onApprove(item.id)}>
                ✓ Approve
              </button>
            )}
            <button className="btn btn-sm btn-outline ac-action-btn ac-dismiss-btn"
              onClick={() => onDismiss(item.id)}>
              ✕ Dismiss
            </button>
          </div>
        )}
      </div>
    );
  }

  // ── Main page component ────────────────────────────────────────────────────
  function AgentContextPage({ agents }) {
    const [summaries, setSummaries]       = useState({});   // agent_id → summary
    const [selAgentId, setSelAgentId]     = useState(null);
    const [items, setItems]               = useState([]);
    const [loadingItems, setLoadingItems] = useState(false);
    const [advanced, setAdvanced]         = useState(false);
    const [reconcileResult, setReconcileResult] = useState(null);
    const [reconciling, setReconciling]   = useState(false);
    const [toast, setToast]               = useState(null);

    useEffect(() => { injectStyles(); }, []);

    // Fetch all bench summaries on mount
    useEffect(() => {
      api('GET', '/api/bench').then(data => {
        const map = {};
        (data.summaries || []).forEach(s => { map[s.agentId] = s; });
        setSummaries(map);
      }).catch(() => {});
    }, []);

    // Fetch items when a Wright is selected
    const selectAgent = useCallback((agentId) => {
      if (selAgentId === agentId) { setSelAgentId(null); setItems([]); return; }
      setSelAgentId(agentId);
      setItems([]);
      setLoadingItems(true);
      api('GET', `/api/bench/${agentId}`)
        .then(data => setItems(data.items || []))
        .catch(() => setItems([]))
        .finally(() => setLoadingItems(false));
    }, [selAgentId]);

    const showToast = (msg, ok = true) => {
      setToast({ msg, ok });
      setTimeout(() => setToast(null), 3500);
    };

    const handleReconcile = async () => {
      setReconciling(true);
      try {
        const r = await api('POST', '/api/bench/reconcile');
        setReconcileResult(r);
        showToast(`Reconciled: ${r.archived} items archived, ${r.estimatedTokensSaved} tokens saved`);
        // Refresh summaries
        const data = await api('GET', '/api/bench');
        const map = {};
        (data.summaries || []).forEach(s => { map[s.agentId] = s; });
        setSummaries(map);
      } catch (e) {
        showToast('Reconcile failed: ' + e.message, false);
      } finally {
        setReconciling(false);
      }
    };

    const handleApprove = async (itemId) => {
      try {
        const r = await api('PATCH', `/api/bench/items/${itemId}/approve`);
        if (r.ok) {
          setItems(prev => prev.map(i => i.id === itemId ? r.item : i));
          showToast('Item approved and pinned.');
        }
      } catch (e) { showToast('Approve failed: ' + e.message, false); }
    };

    const handleDismiss = async (itemId) => {
      try {
        const r = await api('DELETE', `/api/bench/items/${itemId}`);
        if (r.ok) {
          setItems(prev => prev.filter(i => i.id !== itemId));
          showToast('Item dismissed.');
        }
      } catch (e) { showToast('Dismiss failed: ' + e.message, false); }
    };

    const visibleAgents = (agents || []).filter(a => !a.meta);
    const metaAgents    = (agents || []).filter(a => a.meta);

    const pinnedItems  = items.filter(i => i.itemType === 'pinned');
    const learnedItems = items.filter(i => i.itemType === 'learned');

    const selAgent = selAgentId ? (agents || []).find(a => a.id === selAgentId) : null;

    return (
      <div className="ac-root">
        {/* Header */}
        <div className="ac-head">
          <div className="ac-head-row">
            <div>
              <div className="ac-title">The Bench</div>
              <div className="ac-sub">
                Per-Wright operating memory — <b>Pinned</b> (human-set) and <b>Learned</b> (auto-captured
                at review gates). Select a Wright to inspect its context.
              </div>
            </div>
            <div className="ac-head-actions">
              <label className="ac-toggle-wrap">
                <input type="checkbox" checked={advanced} onChange={e => setAdvanced(e.target.checked)} />
                <span className="ac-toggle-label">Advanced</span>
              </label>
              <button className="btn btn-outline btn-sm" onClick={handleReconcile} disabled={reconciling}>
                {reconciling ? '…' : '⟳ Reconcile all'}
              </button>
            </div>
          </div>
          {reconcileResult && (
            <div className="ac-reconcile-result">
              Last reconcile: <b>{reconcileResult.archived}</b> items archived ·{' '}
              <b>~{reconcileResult.estimatedTokensSaved}</b> tokens saved ·{' '}
              <b>{reconcileResult.remainingItems}</b> active items remaining
            </div>
          )}
        </div>

        <div className="ac-layout">
          {/* Left rail — Wright list */}
          <div className="ac-rail">
            <div className="ac-rail-section-title">Wrights</div>
            {visibleAgents.map(agent => {
              const s = summaries[agent.id];
              return (
                <div key={agent.id}
                  className={`ac-wright-row ${selAgentId === agent.id ? 'active' : ''}`}
                  onClick={() => selectAgent(agent.id)}>
                  <div className="ac-wright-avatar"
                    style={{ background: agent.color || '#273558' }}>
                    {agent.initials || (agent.role || '').slice(0, 2).toUpperCase()}
                  </div>
                  <div className="ac-wright-info">
                    <div className="ac-wright-name">{agent.role}</div>
                    {s ? (
                      <div className="ac-wright-counts">
                        📌 {s.pinnedCount} &nbsp;💡 {s.learnedCount}
                      </div>
                    ) : (
                      <div className="ac-wright-counts text-muted">No bench items</div>
                    )}
                  </div>
                </div>
              );
            })}
            {metaAgents.length > 0 && (
              <>
                <div className="ac-rail-section-title" style={{ marginTop: 14 }}>System</div>
                {metaAgents.map(agent => {
                  const s = summaries[agent.id];
                  return (
                    <div key={agent.id}
                      className={`ac-wright-row ac-wright-meta ${selAgentId === agent.id ? 'active' : ''}`}
                      onClick={() => selectAgent(agent.id)}>
                      <div className="ac-wright-avatar"
                        style={{ background: agent.color || '#1b2640' }}>
                        {agent.initials || (agent.role || '').slice(0, 2).toUpperCase()}
                      </div>
                      <div className="ac-wright-info">
                        <div className="ac-wright-name">{agent.role}</div>
                        {s ? (
                          <div className="ac-wright-counts">
                            📌 {s.pinnedCount} &nbsp;💡 {s.learnedCount}
                          </div>
                        ) : (
                          <div className="ac-wright-counts text-muted">No bench items</div>
                        )}
                      </div>
                    </div>
                  );
                })}
              </>
            )}
          </div>

          {/* Main panel */}
          <div className="ac-main">
            {!selAgentId ? (
              <div className="ac-empty-state">
                <div className="ac-empty-icon">🧠</div>
                <div className="ac-empty-title">Select a Wright</div>
                <div className="ac-empty-sub">
                  Choose a Wright from the left rail to inspect its Pinned and Learned context.
                </div>
              </div>
            ) : loadingItems ? (
              <div className="ac-empty-state">
                <div className="spin" />
                <div className="text-muted" style={{ marginTop: 12 }}>Loading bench…</div>
              </div>
            ) : (
              <div>
                <div className="ac-panel-head">
                  <div className="ac-panel-title">
                    {selAgent ? selAgent.role : selAgentId} — The Bench
                  </div>
                  <div className="ac-panel-counts">
                    <span className="ac-count-badge pinned">📌 {pinnedItems.length} Pinned</span>
                    <span className="ac-count-badge learned">💡 {learnedItems.length} Learned</span>
                  </div>
                </div>

                {items.length === 0 ? (
                  <div className="ac-empty-state" style={{ marginTop: 24 }}>
                    <div className="ac-empty-icon">📭</div>
                    <div className="ac-empty-title">No bench items yet</div>
                    <div className="ac-empty-sub">
                      Items appear here after Builds complete review gates, or when you
                      pin a note manually (Advanced mode).
                    </div>
                    {advanced && (
                      <div style={{ marginTop: 16 }}>
                        <PinForm agentId={selAgentId} onPinned={(item) => setItems(prev => [item, ...prev])} showToast={showToast} />
                      </div>
                    )}
                  </div>
                ) : (
                  <>
                    {pinnedItems.length > 0 && (
                      <div className="ac-section">
                        <div className="ac-section-title">📌 Pinned</div>
                        <div className="ac-section-sub">Human-authored context. Confidence stays at 100% and is never decayed.</div>
                        {pinnedItems.map(item => (
                          <ItemCard key={item.id} item={item} advanced={advanced}
                            onApprove={handleApprove} onDismiss={handleDismiss} />
                        ))}
                      </div>
                    )}
                    {learnedItems.length > 0 && (
                      <div className="ac-section">
                        <div className="ac-section-title">💡 Learned</div>
                        <div className="ac-section-sub">Auto-captured at review gates. Confidence decays over time; low-confidence items are archived on reconcile.</div>
                        {learnedItems.map(item => (
                          <ItemCard key={item.id} item={item} advanced={advanced}
                            onApprove={handleApprove} onDismiss={handleDismiss} />
                        ))}
                      </div>
                    )}
                    {advanced && (
                      <div className="ac-section">
                        <PinForm agentId={selAgentId} onPinned={(item) => setItems(prev => [item, ...prev])} showToast={showToast} />
                      </div>
                    )}
                  </>
                )}
              </div>
            )}
          </div>
        </div>

        {/* Toast */}
        {toast && (
          <div className={`ac-toast ${toast.ok ? 'ok' : 'err'}`}>{toast.msg}</div>
        )}
      </div>
    );
  }

  // ── Pin form (shown in advanced mode) ──────────────────────────────────────
  function PinForm({ agentId, onPinned, showToast }) {
    const [content, setContent]   = useState('');
    const [category, setCategory] = useState('');
    const [saving, setSaving]     = useState(false);

    const handlePin = async () => {
      if (!content.trim()) return;
      setSaving(true);
      try {
        const r = await (async () => {
          const opts = { method: 'POST', headers: { 'Content-Type': 'application/json' },
                         body: JSON.stringify({ content: content.trim(), category: category.trim() }) };
          const res = await fetch(`/api/bench/${agentId}/pin`, opts);
          if (!res.ok) throw new Error(await res.text().catch(() => ''));
          return await res.json();
        })();
        if (r.ok && r.item) {
          const item = r.item;
          // convert snake_case to camelCase manually for the pinned item
          function toCamel(s) { return s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()); }
          function dc(o) {
            if (Array.isArray(o)) return o.map(dc);
            if (o && typeof o === 'object') { const out = {}; for (const k of Object.keys(o)) out[toCamel(k)] = dc(o[k]); return out; }
            return o;
          }
          onPinned(dc(item));
          setContent('');
          setCategory('');
          showToast('Item pinned.');
        } else {
          showToast(r.message || 'Pin failed', false);
        }
      } catch (e) { showToast('Pin failed: ' + e.message, false); }
      finally { setSaving(false); }
    };

    return (
      <div className="ac-pin-form">
        <div className="ac-section-title">+ Pin a note</div>
        <textarea className="ac-pin-textarea" placeholder="Enter context to pin for this Wright…"
          value={content} onChange={e => setContent(e.target.value)} rows={3} />
        <div className="ac-pin-row">
          <input className="ac-pin-cat" placeholder="Category (optional)" value={category}
            onChange={e => setCategory(e.target.value)} />
          <button className="btn btn-sm" onClick={handlePin} disabled={saving || !content.trim()}>
            {saving ? 'Pinning…' : 'Pin'}
          </button>
        </div>
      </div>
    );
  }

  // ── Styles ────────────────────────────────────────────────────────────────
  function injectStyles() {
    if (document.getElementById('ac-styles')) return;
    const el = document.createElement('style');
    el.id = 'ac-styles';
    el.textContent = `
.ac-root { height:100%; overflow-y:auto; overflow-x:hidden; padding:24px; position:relative; }
.ac-head { margin-bottom:18px; }
.ac-head-row { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.ac-title { font-weight:600; font-size:1.05rem; }
.ac-sub { font-size:0.82rem; color:#748090; margin-top:4px; line-height:1.55; max-width:600px; }
.ac-sub b { color:#e8e6df; }
.ac-head-actions { display:flex; align-items:center; gap:12px; flex-shrink:0; flex-wrap:wrap; }
.ac-toggle-wrap { display:flex; align-items:center; gap:6px; cursor:pointer; font-size:0.82rem; color:#748090; }
.ac-toggle-wrap input { cursor:pointer; }
.ac-toggle-label { user-select:none; }
.ac-reconcile-result { margin-top:10px; font-size:0.8rem; color:#748090;
  background:#0f1525; border:1px solid #1b2640; border-radius:8px; padding:8px 12px; }
.ac-reconcile-result b { color:#e8e6df; }
.ac-layout { display:flex; gap:16px; align-items:flex-start; }
.ac-rail { width:260px; min-width:220px; flex-shrink:0; display:flex; flex-direction:column; gap:6px; }
.ac-rail-section-title { font-size:0.68rem; text-transform:uppercase; letter-spacing:0.09em;
  color:#344054; font-weight:600; padding:4px 2px; }
.ac-wright-row { display:flex; align-items:center; gap:10px; padding:10px 12px;
  background:#0f1525; border:1px solid #1b2640; border-radius:10px; cursor:pointer;
  transition:all 0.15s; }
.ac-wright-row:hover { border-color:#4a5568; }
.ac-wright-row.active { border-color:#c8a84a; }
.ac-wright-meta { opacity:0.7; }
.ac-wright-avatar { width:28px; height:28px; border-radius:6px; display:flex; align-items:center;
  justify-content:center; font-size:0.72rem; font-weight:700; color:#fff; flex-shrink:0; }
.ac-wright-info { min-width:0; }
.ac-wright-name { font-size:0.84rem; font-weight:600; }
.ac-wright-counts { font-size:0.72rem; color:#748090; margin-top:2px; }
.ac-main { flex:1; min-width:0; }
.ac-panel-head { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:16px; }
.ac-panel-title { font-weight:600; font-size:0.95rem; }
.ac-panel-counts { display:flex; gap:8px; }
.ac-count-badge { font-size:0.75rem; padding:3px 8px; border-radius:20px; border:1px solid; }
.ac-count-badge.pinned { border-color:#c8a84a; color:#c8a84a; background:rgba(200,168,74,0.08); }
.ac-count-badge.learned { border-color:#4c8ab5; color:#4c8ab5; background:rgba(76,138,181,0.08); }
.ac-section { margin-bottom:24px; }
.ac-section-title { font-size:0.85rem; font-weight:600; margin-bottom:4px; }
.ac-section-sub { font-size:0.75rem; color:#748090; margin-bottom:12px; line-height:1.5; }
.ac-item { background:#0f1525; border:1px solid #1b2640; border-radius:10px;
  padding:13px 15px; margin-bottom:10px; transition:border-color 0.15s; }
.ac-item-pinned { border-color:#c8a84a; background:rgba(200,168,74,0.04); }
.ac-item-head { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:8px; }
.ac-type-badge { font-size:0.72rem; font-weight:600; padding:2px 7px; border-radius:12px; }
.ac-type-badge.pinned { background:rgba(200,168,74,0.15); color:#c8a84a; }
.ac-type-badge.learned { background:rgba(76,138,181,0.15); color:#4c8ab5; }
.ac-cat-chip { font-size:0.7rem; background:#172038; border:1px solid #1b2640;
  border-radius:8px; padding:2px 7px; color:#748090; }
.ac-conf-bar { flex:1; max-width:80px; height:4px; background:#1b2640; border-radius:2px; overflow:hidden; }
.ac-conf-fill { height:100%; border-radius:2px; transition:width 0.3s; }
.ac-item-content { font-size:0.85rem; line-height:1.55; color:#e8e6df; }
.ac-lineage { font-size:0.72rem; color:#748090; margin-top:7px;
  background:#172038; border-radius:6px; padding:4px 8px; display:inline-block; }
.ac-item-actions { display:flex; gap:8px; margin-top:10px; }
.ac-action-btn { font-size:0.75rem; padding:3px 10px; }
.ac-dismiss-btn { color:#e08080; border-color:#e08080; }
.ac-dismiss-btn:hover { background:rgba(224,128,128,0.08); }
.ac-empty-state { text-align:center; padding:48px 24px; }
.ac-empty-icon { font-size:2.5rem; margin-bottom:12px; }
.ac-empty-title { font-weight:600; font-size:0.95rem; margin-bottom:6px; }
.ac-empty-sub { font-size:0.82rem; color:#748090; line-height:1.6; max-width:340px; margin:0 auto; }
.ac-pin-form { background:#0f1525; border:1px solid #1b2640; border-radius:10px; padding:14px 16px; }
.ac-pin-textarea { width:100%; background:#172038; border:1px solid #1b2640; border-radius:8px;
  color:#e8e6df; font-size:0.84rem; padding:9px 11px; resize:vertical; outline:none; font-family:inherit; }
.ac-pin-textarea:focus { border-color:#4a5568; }
.ac-pin-row { display:flex; gap:10px; margin-top:8px; align-items:center; }
.ac-pin-cat { flex:1; background:#172038; border:1px solid #1b2640; border-radius:8px;
  color:#e8e6df; font-size:0.82rem; padding:6px 10px; outline:none; font-family:inherit; }
.ac-pin-cat:focus { border-color:#4a5568; }
.ac-toast { position:fixed; bottom:28px; right:28px; padding:10px 18px; border-radius:10px;
  font-size:0.85rem; font-weight:500; z-index:9999; animation:ac-fadein 0.2s ease; }
.ac-toast.ok { background:#1a3d1a; border:1px solid #4ade80; color:#4ade80; }
.ac-toast.err { background:#3d1a1a; border:1px solid #e08080; color:#e08080; }
@keyframes ac-fadein { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
@media (max-width:900px) {
  .ac-root { padding:16px; }
  .ac-layout { flex-direction:column; }
  .ac-rail { width:100%; min-width:0; }
  .ac-main { width:100%; }
}
`;
    document.head.appendChild(el);
  }

  window.AgentContextPage = AgentContextPage;
})();
