// panes/tools.js — live MCP tool registry browser + ad-hoc invoke.
import { registerPane } from '../app.js';
import { mcp, escapeHtml } from '../lib/api.js';
import { ok, err, fmtJSON } from '../lib/ui.js';

const TPL = `
  <div class="pane-head">
    <div>
      <div class="title">Tools</div>
      <div class="sub">Every MCP tool exposed by the CxAI agent.</div>
    </div>
    <div class="grow"></div>
    <input class="input" id="tools-filter" placeholder="filter…" style="max-width:240px" />
    <button class="btn btn-secondary" id="tools-refresh">Refresh</button>
  </div>

  <div class="grid cols-2">
    <div class="card">
      <div class="card-title"><h2>Registry</h2><span class="muted mono" id="tools-meta">loading…</span></div>
      <div id="tools-list" class="scroll" style="max-height:60vh">loading…</div>
    </div>
    <div class="card">
      <div class="card-title"><h2>Invoke</h2><span class="muted mono" id="tools-invoke-meta"></span></div>
      <div class="mb-2"><span class="mono" id="tools-selected">(select a tool)</span></div>
      <label class="field mb-2">
        <span class="lbl">Arguments (JSON)</span>
        <textarea class="input" id="tools-args" rows="8">{}</textarea>
      </label>
      <button class="btn btn-primary" id="tools-call" disabled>Call</button>
      <h3 class="mt-3 mb-2">Response</h3>
      <pre id="tools-out" class="muted">no calls yet</pre>
    </div>
  </div>
`;

let allTools = [];
let selected = null;

function render(host) {
  const filter = host.querySelector('#tools-filter').value.toLowerCase();
  const list = allTools.filter(t =>
    !filter || (t.name + ' ' + (t.description || '')).toLowerCase().includes(filter)
  );
  host.querySelector('#tools-meta').textContent = `${list.length} / ${allTools.length}`;
  host.querySelector('#tools-list').innerHTML = list.map(t => `
    <div class="tool-card" data-name="${escapeHtml(t.name)}">
      <h4>${escapeHtml(t.name)}</h4>
      <p>${escapeHtml(t.description || '(no description)')}</p>
    </div>
  `).join('') || '<div class="muted">no tools</div>';
  host.querySelectorAll('.tool-card').forEach(el => {
    el.addEventListener('click', () => select(host, el.dataset.name));
  });
}

function select(host, name) {
  selected = allTools.find(t => t.name === name) || null;
  host.querySelector('#tools-selected').textContent = name;
  host.querySelector('#tools-call').disabled = !selected;
  // try to seed with example args from schema
  const schema = selected?.inputSchema || selected?.input_schema || selected?.schema;
  if (schema?.properties) {
    const example = {};
    for (const [k, v] of Object.entries(schema.properties)) {
      if (v.default !== undefined) example[k] = v.default;
      else if (v.type === 'string') example[k] = '';
      else if (v.type === 'number' || v.type === 'integer') example[k] = 0;
      else if (v.type === 'boolean') example[k] = false;
    }
    host.querySelector('#tools-args').value = JSON.stringify(example, null, 2);
  } else {
    host.querySelector('#tools-args').value = '{}';
  }
  host.querySelector('#tools-invoke-meta').textContent = selected ? 'ready' : '';
}

async function call(host) {
  if (!selected) return;
  let args;
  try { args = JSON.parse(host.querySelector('#tools-args').value || '{}'); }
  catch (e) { err(`Invalid JSON: ${e.message}`); return; }
  host.querySelector('#tools-invoke-meta').textContent = 'calling…';
  host.querySelector('#tools-out').textContent = 'calling…';
  const t0 = performance.now();
  try {
    const r = await mcp.call(selected.name, args);
    host.querySelector('#tools-out').textContent = fmtJSON(r);
    host.querySelector('#tools-invoke-meta').textContent = `ok · ${Math.round(performance.now() - t0)}ms`;
    ok(`${selected.name} ok`);
  } catch (e) {
    host.querySelector('#tools-out').textContent = fmtJSON(e.body ?? { error: e.message });
    host.querySelector('#tools-invoke-meta').textContent = `error ${e.status ?? ''}`;
    err(`${selected.name}: ${e.message}`);
  }
}

async function refresh(host) {
  host.querySelector('#tools-list').textContent = 'loading…';
  try {
    const r = await mcp.tools();
    allTools = Array.isArray(r) ? r : (r.tools || r.result || []);
    render(host);
  } catch (e) {
    host.querySelector('#tools-list').innerHTML = `<div class="muted">${escapeHtml(e.message)}</div>`;
    host.querySelector('#tools-meta').textContent = 'error';
  }
}

registerPane('tools', {
  label: 'Tools',
  init(host) {
    host.innerHTML = TPL;
    host.querySelector('#tools-refresh').addEventListener('click', () => refresh(host));
    host.querySelector('#tools-filter').addEventListener('input', () => render(host));
    host.querySelector('#tools-call').addEventListener('click', () => call(host));
    refresh(host);
  },
  refresh,
});
