// panes/lang.js — language pipelines with cards, examples, run history.
import { registerPane } from '../app.js';
import { jget, jpost, escapeHtml } from '../lib/api.js';
import { fmtJSON, err, ok, copyToClipboard, historyStore } from '../lib/ui.js';

const runHist = historyStore('cx_lang_runs', 20);

const TPL = `
  <div class="pane-head">
    <div><div class="title">Lang</div><div class="sub">Run language pipelines via the sidecar.</div></div>
    <div class="grow"></div>
    <span class="pill" id="lang-pill"><span class="dot"></span><span id="lang-pill-text">—</span></span>
    <button class="btn btn-secondary" id="lang-refresh">Refresh</button>
  </div>

  <div class="grid" style="grid-template-columns: 320px 1fr; gap: 16px;">
    <div class="card no-pad scroll" style="max-height:74vh">
      <div class="p-2"><input class="input" id="lang-search" placeholder="filter pipelines…"/></div>
      <div id="lang-pipelines">loading…</div>
    </div>

    <div class="card">
      <div class="card-title">
        <h2 id="lang-name">Select a pipeline</h2>
        <span class="muted xsmall" id="lang-status">—</span>
      </div>
      <p class="muted small" id="lang-desc">Pick a pipeline on the left.</p>

      <div id="lang-body" hidden>
        <div class="card-title"><h2 style="font-size:14px">Examples</h2></div>
        <div class="chips mb-3" id="lang-examples"></div>

        <label class="field"><span class="lbl">Input (JSON)</span>
          <textarea class="input mono" id="lang-input" rows="8">{}</textarea>
        </label>
        <div class="btn-row mt-3">
          <button class="btn btn-primary" id="lang-run">Run</button>
          <button class="btn btn-secondary" id="lang-format">Format JSON</button>
          <button class="btn btn-secondary" id="lang-copy-input">Copy input</button>
          <button class="btn btn-ghost" id="lang-health">Health</button>
        </div>

        <div class="divider"></div>
        <div class="card-title"><h2 style="font-size:14px">Result</h2>
          <div class="flex gap-2">
            <span class="muted xsmall" id="lang-meta"></span>
            <button class="btn btn-ghost" id="lang-copy-out">Copy</button>
          </div>
        </div>
        <pre id="lang-result" class="code muted" style="max-height:32vh">—</pre>

        <details class="card-d mt-3"><summary>Recent runs</summary>
          <div id="lang-history" class="body"></div>
        </details>
      </div>
    </div>
  </div>
`;

let pipelines = [];
let current = null;

function renderList(host) {
  const q = host.querySelector('#lang-search').value.trim().toLowerCase();
  const items = pipelines.filter(p => !q || (p.name + ' ' + (p.description || '')).toLowerCase().includes(q));
  host.querySelector('#lang-pipelines').innerHTML = items.length
    ? items.map(p => `<button class="nav-item" data-p="${escapeHtml(p.name)}">
        <span class="grow">
          <div class="mono">${escapeHtml(p.name)}</div>
          <div class="muted xsmall truncate">${escapeHtml(p.description || '')}</div>
        </span>
      </button>`).join('')
    : '<div class="muted xsmall p-2">no pipelines</div>';
  host.querySelectorAll('[data-p]').forEach(b => b.addEventListener('click', () => select(host, b.dataset.p)));
}

function renderHistory(host) {
  const list = runHist.list().filter(r => !current || r.name === current.name);
  host.querySelector('#lang-history').innerHTML = list.length
    ? list.map((r, i) => `<button class="nav-item" data-hi="${i}">
        <span class="muted xsmall mono">${new Date(r._ts).toLocaleTimeString()}</span>
        <span class="grow truncate">${escapeHtml(r.name)}</span>
        <span class="pill ${r.ok ? 'ok' : 'err'}">${r.ok ? `${r.ms || '?'}ms` : 'err'}</span>
      </button>`).join('')
    : '<div class="muted xsmall p-2">no runs</div>';
  host.querySelectorAll('#lang-history [data-hi]').forEach(b => b.addEventListener('click', () => {
    const r = list[+b.dataset.hi];
    if (r) { host.querySelector('#lang-input').value = fmtJSON(r.input); host.querySelector('#lang-result').textContent = fmtJSON(r.output); }
  }));
}

function select(host, name) {
  current = pipelines.find(p => p.name === name);
  if (!current) return;
  host.querySelector('#lang-name').textContent = current.name;
  host.querySelector('#lang-desc').textContent = current.description || '—';
  host.querySelector('#lang-body').hidden = false;

  const ex = current.examples || current.sample_inputs || [];
  host.querySelector('#lang-examples').innerHTML = ex.length
    ? ex.map((e, i) => `<button class="chip" data-ex="${i}">${escapeHtml(e.label || e.name || `example ${i + 1}`)}</button>`).join('')
    : '<span class="muted xsmall">no examples</span>';
  host.querySelectorAll('#lang-examples .chip').forEach(b => b.addEventListener('click', () => {
    const e = ex[+b.dataset.ex];
    host.querySelector('#lang-input').value = fmtJSON(e.input ?? e.value ?? e);
  }));

  host.querySelector('#lang-input').value = fmtJSON(current.default_input || {});
  renderHistory(host);
}

async function refresh(host) {
  try {
    const r = await jget('/api/lang/pipelines');
    pipelines = r.pipelines || [];
    renderList(host);
    host.querySelector('#lang-pill').classList.remove('err', 'warn'); host.querySelector('#lang-pill').classList.add('ok');
    host.querySelector('#lang-pill-text').textContent = `${pipelines.length} pipelines`;
  } catch (e) {
    host.querySelector('#lang-pipelines').innerHTML = `<div class="muted xsmall p-2">${escapeHtml(e.message)}</div>`;
    host.querySelector('#lang-pill').classList.add('err'); host.querySelector('#lang-pill-text').textContent = 'down';
  }
}

registerPane('lang', {
  label: 'Lang',
  init(host) {
    host.innerHTML = TPL;
    host.querySelector('#lang-refresh').addEventListener('click', () => refresh(host));
    host.querySelector('#lang-search').addEventListener('input', () => renderList(host));

    host.querySelector('#lang-run').addEventListener('click', async () => {
      if (!current) return err('select a pipeline');
      let input;
      try { input = JSON.parse(host.querySelector('#lang-input').value || '{}'); }
      catch (e) { return err(`bad JSON: ${e.message}`); }
      host.querySelector('#lang-status').textContent = 'running…';
      const t0 = performance.now();
      try {
        const r = await jpost(`/api/lang/pipelines/${encodeURIComponent(current.name)}`, { input });
        const ms = +r.duration_ms || (performance.now() - t0).toFixed(0);
        host.querySelector('#lang-result').textContent = fmtJSON(r);
        host.querySelector('#lang-status').textContent = `ok · ${ms}ms`;
        host.querySelector('#lang-meta').textContent = `${ms}ms`;
        runHist.push({ name: current.name, input, output: r, ms, ok: true });
        renderHistory(host); ok('done');
      } catch (e) {
        host.querySelector('#lang-result').textContent = fmtJSON(e.body ?? { error: e.message });
        host.querySelector('#lang-status').textContent = `error ${e.status ?? ''}`;
        runHist.push({ name: current.name, input, error: e.message, ok: false });
        renderHistory(host); err(e.message);
      }
    });
    host.querySelector('#lang-format').addEventListener('click', () => {
      const ta = host.querySelector('#lang-input');
      try { ta.value = fmtJSON(JSON.parse(ta.value || '{}')); } catch (e) { err('bad JSON: ' + e.message); }
    });
    host.querySelector('#lang-copy-input').addEventListener('click', () => copyToClipboard(host.querySelector('#lang-input').value));
    host.querySelector('#lang-copy-out').addEventListener('click', () => copyToClipboard(host.querySelector('#lang-result').textContent));
    host.querySelector('#lang-health').addEventListener('click', async () => {
      try { host.querySelector('#lang-result').textContent = fmtJSON(await jget('/api/lang/healthz')); }
      catch (e) { host.querySelector('#lang-result').textContent = e.message; }
    });

    refresh(host);
  },
  refresh,
});
