// panes/inbox.js — sweep & route CxAI/_inbox via MCP tools with slider, history, presets.
import { registerPane } from '../app.js';
import { mcp, escapeHtml } from '../lib/api.js';
import { ok, err, fmtJSON, meterRow, historyStore, copyToClipboard } from '../lib/ui.js';

const sweepHist = historyStore('cx_inbox_sweeps', 15);
const routeHist = historyStore('cx_inbox_routes', 15);

const TPL = `
  <div class="pane-head">
    <div><div class="title">Inbox</div><div class="sub">Route artifacts through the CxAI inbox classifier.</div></div>
    <div class="grow"></div>
    <button class="btn btn-secondary" id="inbox-refresh">Sweep now</button>
  </div>

  <div class="grid cols-3 mb-3" id="inbox-kpis"></div>

  <div class="grid cols-2 mb-3">
    <div class="card">
      <div class="card-title"><h2>Sweep</h2><span class="muted mono xsmall" id="inbox-sweep-meta">idle</span></div>
      <form id="inbox-sweep-form" class="grid cols-2 gap-3">
        <label class="field">
          <span class="lbl">Mode</span>
          <select class="input" id="inbox-mode">
            <option value="all">all (inbox + needs-review)</option>
            <option value="inbox">inbox only</option>
            <option value="needs_review">needs-review only</option>
          </select>
        </label>
        <label class="field">
          <span class="lbl">Limit</span>
          <input class="input" id="inbox-limit" type="number" min="0" value="0" placeholder="0 = no limit"/>
        </label>
        <div style="grid-column: span 2">
          <label class="lbl">Confidence threshold <span class="mono" id="inbox-thr-val">0.70</span></label>
          <input type="range" class="slider" id="inbox-threshold" min="0" max="1" step="0.05" value="0.7" style="width:100%"/>
          <div id="inbox-thr-meter"></div>
        </div>
        <label class="check"><input type="checkbox" id="inbox-dry" checked/> dry-run</label>
        <label class="check"><input type="checkbox" id="inbox-verbose"/> verbose</label>
        <div class="btn-row" style="grid-column: span 2">
          <button class="btn btn-primary" type="submit">Run sweep</button>
          <button type="button" class="btn btn-secondary" data-preset="strict">Strict (0.9)</button>
          <button type="button" class="btn btn-secondary" data-preset="normal">Normal (0.7)</button>
          <button type="button" class="btn btn-secondary" data-preset="loose">Loose (0.4)</button>
        </div>
      </form>
    </div>

    <div class="card">
      <div class="card-title"><h2>Route a single file</h2><span class="muted xsmall" id="inbox-route-meta"></span></div>
      <form id="inbox-route-form" class="grid gap-2 mb-2">
        <input class="input" id="inbox-route-path" placeholder="/absolute/path/to/file.md"/>
        <div class="btn-row">
          <button class="btn btn-primary" type="submit">Route</button>
          <label class="check"><input type="checkbox" id="inbox-route-dry" checked/> dry-run</label>
        </div>
      </form>
      <details class="card-d"><summary>Recent routes</summary>
        <div id="inbox-route-history" class="body"></div>
      </details>
    </div>
  </div>

  <div class="grid cols-2">
    <div class="card">
      <div class="card-title"><h2>Last sweep</h2><button class="btn btn-ghost" id="inbox-copy">Copy</button></div>
      <pre id="inbox-result" class="code muted" style="max-height:36vh">no sweep yet</pre>
    </div>
    <div class="card">
      <div class="card-title"><h2>Route result</h2></div>
      <pre id="inbox-route-result" class="code muted" style="max-height:36vh">no route yet</pre>

      <div class="divider"></div>
      <div class="card-title"><h2 style="font-size:14px">Sweep history</h2></div>
      <div id="inbox-sweep-history"></div>
    </div>
  </div>
`;

function kpi(label, value, sub) {
  return `<div class="kpi"><div class="label">${escapeHtml(label)}</div><div class="value">${escapeHtml(String(value))}</div><div class="sub">${escapeHtml(sub || '')}</div></div>`;
}

function updateThr(host) {
  const v = +host.querySelector('#inbox-threshold').value;
  host.querySelector('#inbox-thr-val').textContent = v.toFixed(2);
  const state = v >= 0.8 ? 'ok' : v >= 0.5 ? 'warn' : 'err';
  host.querySelector('#inbox-thr-meter').innerHTML = meterRow('confidence', v * 100, `${(v * 100).toFixed(0)}%`, state);
}

function renderHist(host) {
  const sw = sweepHist.list();
  host.querySelector('#inbox-sweep-history').innerHTML = sw.length
    ? sw.map((r, i) => `<button class="nav-item" data-hi="${i}">
        <span class="muted xsmall mono">${new Date(r._ts).toLocaleTimeString()}</span>
        <span>${escapeHtml(r.mode)} · thr=${r.threshold}</span>
        <span class="pill ${r.ok ? 'ok' : 'err'}">${r.ok ? `${r.routed ?? 0} routed` : 'error'}</span>
      </button>`).join('')
    : '<div class="muted xsmall p-2">no sweeps yet</div>';
  host.querySelectorAll('#inbox-sweep-history [data-hi]').forEach(b => b.addEventListener('click', () => {
    host.querySelector('#inbox-result').textContent = fmtJSON(sweepHist.list()[+b.dataset.hi]);
  }));

  const ro = routeHist.list();
  host.querySelector('#inbox-route-history').innerHTML = ro.length
    ? ro.map((r, i) => `<button class="nav-item" data-rhi="${i}">
        <span class="muted xsmall mono">${new Date(r._ts).toLocaleTimeString()}</span>
        <span class="truncate">${escapeHtml(r.path)}</span>
        <span class="pill ${r.ok ? 'ok' : 'err'}">${r.target || (r.ok ? 'ok' : 'err')}</span>
      </button>`).join('')
    : '<div class="muted xsmall p-2">no routes yet</div>';
  host.querySelectorAll('#inbox-route-history [data-rhi]').forEach(b => b.addEventListener('click', () => {
    const r = routeHist.list()[+b.dataset.rhi];
    host.querySelector('#inbox-route-path').value = r.path;
    host.querySelector('#inbox-route-result').textContent = fmtJSON(r);
  }));
}

async function runSweep(host) {
  const mode = host.querySelector('#inbox-mode').value;
  const threshold = parseFloat(host.querySelector('#inbox-threshold').value);
  const limit = +host.querySelector('#inbox-limit').value || 0;
  const dry_run = host.querySelector('#inbox-dry').checked;
  const verbose = host.querySelector('#inbox-verbose').checked;
  host.querySelector('#inbox-sweep-meta').textContent = 'running…';
  host.querySelector('#inbox-result').textContent = 'running…';
  const args = { mode, threshold, dry_run };
  if (limit > 0) args.limit = limit;
  if (verbose) args.verbose = true;
  try {
    const r = await mcp.call('inbox_sweep_tool', args);
    host.querySelector('#inbox-result').textContent = fmtJSON(r);
    const total = (Array.isArray(r?.routed) ? r.routed.length : r?.routed) ?? r?.summary?.routed ?? 0;
    host.querySelector('#inbox-sweep-meta').textContent = dry_run ? `dry-run · ${total} candidates` : `routed ${total}`;
    const pill = document.getElementById('nav-inbox-pill');
    if (pill && !dry_run) pill.textContent = String(total || '');
    sweepHist.push({ mode, threshold, dry_run, routed: total, ok: true, response: r });
    renderHist(host); updateKpis(host, r);
    ok(`Sweep complete${dry_run ? ' (dry)' : ''}`);
  } catch (e) {
    host.querySelector('#inbox-result').textContent = fmtJSON(e.body ?? { error: e.message });
    host.querySelector('#inbox-sweep-meta').textContent = `error ${e.status ?? ''}`;
    sweepHist.push({ mode, threshold, dry_run, ok: false, error: e.message });
    renderHist(host);
    err(`sweep: ${e.message}`);
  }
}

async function routeOne(host) {
  const path = host.querySelector('#inbox-route-path').value.trim();
  if (!path) return;
  const dry_run = host.querySelector('#inbox-route-dry').checked;
  host.querySelector('#inbox-route-meta').textContent = 'routing…';
  host.querySelector('#inbox-route-result').textContent = 'routing…';
  try {
    const r = await mcp.call('route_file_tool', { path, dry_run });
    host.querySelector('#inbox-route-result').textContent = fmtJSON(r);
    const target = r?.target || r?.destination || 'ok';
    host.querySelector('#inbox-route-meta').textContent = target;
    routeHist.push({ path, dry_run, target, ok: true });
    renderHist(host);
    ok(`Routed ${path.split('/').pop()}`);
  } catch (e) {
    host.querySelector('#inbox-route-result').textContent = fmtJSON(e.body ?? { error: e.message });
    host.querySelector('#inbox-route-meta').textContent = `error ${e.status ?? ''}`;
    routeHist.push({ path, dry_run, ok: false, error: e.message });
    renderHist(host);
    err(`route: ${e.message}`);
  }
}

function updateKpis(host, r) {
  const routed = (Array.isArray(r?.routed) ? r.routed.length : r?.routed) ?? r?.summary?.routed ?? 0;
  const skipped = (Array.isArray(r?.skipped) ? r.skipped.length : r?.skipped) ?? r?.summary?.skipped ?? 0;
  const queued  = r?.summary?.queued ?? r?.queued ?? '—';
  host.querySelector('#inbox-kpis').innerHTML = [
    kpi('Routed (last)',  routed,  'files moved'),
    kpi('Skipped (last)', skipped, 'low-confidence'),
    kpi('Queue',          queued,  'remaining'),
  ].join('');
}

registerPane('inbox', {
  label: 'Inbox',
  init(host) {
    host.innerHTML = TPL;
    updateThr(host); updateKpis(host, {});
    host.querySelector('#inbox-threshold').addEventListener('input', () => updateThr(host));
    host.querySelectorAll('[data-preset]').forEach(b => b.addEventListener('click', () => {
      const v = { strict: 0.9, normal: 0.7, loose: 0.4 }[b.dataset.preset];
      host.querySelector('#inbox-threshold').value = v; updateThr(host);
    }));
    host.querySelector('#inbox-sweep-form').addEventListener('submit', (e) => { e.preventDefault(); runSweep(host); });
    host.querySelector('#inbox-route-form').addEventListener('submit', (e) => { e.preventDefault(); routeOne(host); });
    host.querySelector('#inbox-refresh').addEventListener('click', () => runSweep(host));
    host.querySelector('#inbox-copy').addEventListener('click', () => copyToClipboard(host.querySelector('#inbox-result').textContent));
    renderHist(host);
  },
});
