// ═══════════════════════════════════════════════════════
//  CVC Dashboard — REST API Client
//  (Compiled from ts/api.ts — edit TypeScript source)
// ═══════════════════════════════════════════════════════
"use strict";

/** @type {string} */
const API_BASE = '';

/**
 * @template T
 * @param {string} path
 * @param {RequestInit} [init]
 * @returns {Promise<T>}
 */
async function apiRequest(path, init) {
  const res = await fetch(`${API_BASE}${path}`, {
    headers: { 'Content-Type': 'application/json', ...(init?.headers || {}) },
    ...init,
  });
  if (!res.ok) {
    const body = await res.text();
    throw new Error(`API ${res.status}: ${body}`);
  }
  return res.json();
}

/** @param {string} path */
function apiGet(path) { return apiRequest(path); }

/** @param {string} path @param {*} [body] */
function apiPost(path, body) {
  return apiRequest(path, { method: 'POST', body: body != null ? JSON.stringify(body) : undefined });
}

/** @param {string} path */
function apiDel(path) { return apiRequest(path, { method: 'DELETE' }); }

/** @param {string} path @param {*} [body] */
function apiPut(path, body) {
  return apiRequest(path, { method: 'PUT', body: body != null ? JSON.stringify(body) : undefined });
}

// ── Typed API namespace ─────────────────────────
const CvcApi = {
  // Gateway / Services
  getServices()          { return apiGet('/api/gateway/services'); },
  serviceAction(svc, action) { return apiPost(`/api/gateway/services/${encodeURIComponent(svc)}/${encodeURIComponent(action)}`); },
  getAnalytics()         { return apiGet('/api/gateway/analytics'); },
  getCommits(limit = 50) { return apiGet(`/api/gateway/commits?limit=${limit}`); },
  getConfig()            { return apiGet('/api/gateway/config'); },

  // Operations
  opsCommit(req)         { return apiPost('/api/ops/commit', req); },
  opsBranch(req)         { return apiPost('/api/ops/branch', req); },
  opsMerge(req)          { return apiPost('/api/ops/merge', req); },
  opsRestore(req)        { return apiPost('/api/ops/restore', req); },
  opsRecall(query, limit = 10) { return apiGet(`/api/ops/recall?query=${encodeURIComponent(query)}&limit=${limit}`); },
  opsDiff(h1, h2)        { return apiGet(`/api/ops/diff?hash1=${encodeURIComponent(h1)}&hash2=${encodeURIComponent(h2)}`); },
  opsTimeline(limit = 50) { return apiGet(`/api/ops/timeline?limit=${limit}`); },
  opsBranches()          { return apiGet('/api/ops/branches'); },
  opsStatus()            { return apiGet('/api/ops/status'); },

  // Memory
  getMemoryContext()     { return apiGet('/api/memory/context'); },
  getMemoryBlobs()       { return apiGet('/api/memory/blobs'); },
  getMemoryStats()       { return apiGet('/api/memory/stats'); },

  // Models
  getModelCatalog()      { return apiGet('/api/models/catalog'); },
  getCurrentModel()      { return apiGet('/api/models/current'); },
  switchModel(provider, model) { return apiPost('/api/models/switch', { provider, model }); },

  // Chat — yields structured event objects:
  //   { type: "text",        content: "..." }
  //   { type: "tool_start",  name: "...", args: {...} }
  //   { type: "tool_result", name: "...", output: "..." }
  //   { type: "status",      message: "..." }
  async *chatStream(req) {
    const res = await fetch(`${API_BASE}/api/chat`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ...req, stream: true }),
    });
    if (!res.ok) throw new Error(`Chat ${res.status}`);
    const reader = res.body?.getReader();
    if (!reader) return;
    const decoder = new TextDecoder();
    let buffer = '';
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      buffer += decoder.decode(value, { stream: true });
      const lines = buffer.split('\n');
      buffer = lines.pop();
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const data = line.slice(6);
          if (data === '[DONE]') return;
          try {
            const parsed = JSON.parse(data);
            // New structured events from agentic loop
            if (parsed.type) {
              yield parsed;
            }
            // Legacy fallback: OpenAI-style delta
            else if (parsed.choices?.[0]?.delta?.content) {
              yield { type: 'text', content: parsed.choices[0].delta.content };
            }
          } catch { /* skip malformed SSE */ }
        }
      }
    }
  },

  getChatModels()        { return apiGet('/api/chat/models'); },

  // Chat — tool permissions & control
  confirmTool(decision)  { return apiPost('/api/chat/confirm', { decision }); },
  abortChat()            { return apiPost('/api/chat/abort'); },
  getAutopilot()         { return apiGet('/api/chat/autopilot'); },
  setAutopilot(on)       { return apiPost('/api/chat/autopilot', { autopilot: on }); },

  // MCP
  getMCPTools()          { return apiGet('/api/mcp/tools'); },
  getMCPStatus()         { return apiGet('/api/mcp/status'); },

  // VCS
  getVCSStatus()         { return apiGet('/api/vcs/status'); },

  // Audit
  getAudit()             { return apiGet('/api/audit'); },

  // Sessions
  getSessions()          { return apiGet('/api/sessions'); },

  // Connections
  getConnections()       { return apiGet('/api/connections'); },

  // Hive Mind
  getHiveMindAgents()    { return apiGet('/api/hivemind/agents'); },
  registerHiveMindAgent(req) { return apiPost('/api/hivemind/register', req); },
  removeHiveMindAgent(id) { return apiDel(`/api/hivemind/agents/${encodeURIComponent(id)}`); },

  // Stats
  getStats()             { return apiGet('/api/stats'); },

  // Settings
  getSettings()          { return apiGet('/api/settings'); },
  updateGlobalSettings(data) { return apiPut('/api/settings/global', data); },
  updateProjectSettings(data) { return apiPut('/api/settings/project', data); },
  updateLocalSettings(data) { return apiPut('/api/settings/local', data); },
  getSettingsSchema()    { return apiGet('/api/settings/schema'); },
  resetSettings(level)   { return apiPost('/api/settings/reset', { level }); },
  getApiKeys()           { return apiGet('/api/settings/keys'); },
  setApiKey(provider, key) { return apiPut(`/api/settings/keys/${encodeURIComponent(provider)}`, { api_key: key }); },
  removeApiKey(provider) { return apiDel(`/api/settings/keys/${encodeURIComponent(provider)}`); },
  testApiKey(provider)   { return apiPost(`/api/settings/keys/${encodeURIComponent(provider)}/test`); },
  getHooks()             { return apiGet('/api/settings/hooks'); },
  addHook(event, command) { return apiPost('/api/settings/hooks', { event, command }); },
  removeHook(event, idx) { return apiDel(`/api/settings/hooks/${encodeURIComponent(event)}/${idx}`); },
  getEnvVars()           { return apiGet('/api/settings/env'); },

  // Agent Templates
  listAgents()           { return apiGet('/api/agents'); },
  getBuiltinAgents()     { return apiGet('/api/agents/builtin'); },
  createAgent(template)  { return apiPost('/api/agents', template); },
  createAgentFromPrompt(prompt) { return apiPost('/api/agents/from-prompt', { prompt }); },
  getAgentDetail(id)     { return apiGet(`/api/agents/${encodeURIComponent(id)}`); },
  updateAgent(id, data)  { return apiPut(`/api/agents/${encodeURIComponent(id)}`, data); },
  deleteAgent(id)        { return apiDel(`/api/agents/${encodeURIComponent(id)}`); },
  getAgentHistory(id)    { return apiGet(`/api/agents/${encodeURIComponent(id)}/history`); },
  createSquad(name, agents) { return apiPost('/api/agents/squad', { name, agents }); },
  listSquads()           { return apiGet('/api/agents/squads').then(r => r.squads || []); },

  // Hive Memory
  getHiveMemory(query, category, agentId, limit = 50) {
    const p = new URLSearchParams();
    if (query) p.set('query', query);
    if (category) p.set('category', category);
    if (agentId) p.set('agent_id', agentId);
    p.set('limit', String(limit));
    return apiGet(`/api/hivemind/memory?${p}`);
  },
  writeHiveMemory(agentId, content, category = 'general', tags = []) {
    return apiPost('/api/hivemind/memory', { agent_id: agentId, content, category, tags });
  },
  getHiveMemoryStats()   { return apiGet('/api/hivemind/memory/stats'); },
  getHiveMemorySummary(limit = 10) { return apiGet(`/api/hivemind/memory/summary?limit=${limit}`); },
  compactHiveMemory()    { return apiPost('/api/hivemind/memory/compact'); },
};
