const API_BASE = '/api'

async function request(path, options = {}) {
  const res = await fetch(`${API_BASE}${path}`, {
    ...options,
    headers: { 'Content-Type': 'application/json', ...(options.headers || {}) },
  })
  if (!res.ok) {
    const err = await res.json().catch(() => ({ error: res.statusText }))
    throw new Error(err.error || res.statusText)
  }
  return res.json()
}

const api = {
  getInfo: () => request('/info'),
  getSystem: () => request('/system'),
  getTools: () => request('/tools'),
  getConfig: () => request('/config'),
  getProviders: () => request('/providers'),
  getSkills: () => request('/skills'),
  getLSP: () => request('/lsp'),
  getMCP: () => request('/mcp'),
  getUpdates: () => request('/updates'),
  getEditors: () => request('/editors'),
  runScan: () => request('/scan', { method: 'POST' }),
  installTools: (tools) => request('/install', { method: 'POST', body: JSON.stringify({ tools }) }),
  configureMCP: () => request('/mcp/configure', { method: 'POST' }),
  configureMCPForEditor: (editor) => request('/mcp/configure', { method: 'POST', body: JSON.stringify({ editor }) }),
  getMCPStatus: () => request('/mcp/status'),
  getMCPRegistry: () => request('/mcp/registry'),
  getLSPHealth: () => request('/lsp/health'),
  autoInstallLSP: (projectDir) => request('/lsp/auto-install', { method: 'POST', body: JSON.stringify({ project_dir: projectDir || '' }) }),
  generateLSPConfig: (editor, names) => request('/lsp/editor-config', { method: 'POST', body: JSON.stringify({ editor, names }) }),
  validateSkill: (name) => request('/skills/validate', { method: 'POST', body: JSON.stringify({ name }) }),
  testSkill: (name, sampleTask) => request('/skills/test', { method: 'POST', body: JSON.stringify({ name, sample_task: sampleTask || '' }) }),
  exportSkill: (name) => request('/skills/export', { method: 'POST', body: JSON.stringify({ name }) }),
  importSkill: (path) => request('/skills/import', { method: 'POST', body: JSON.stringify({ import_path: path }) }),
  deploySkill: (name) => request('/skills/deploy', { method: 'POST', body: JSON.stringify({ name }) }),
  undeploySkill: (name) => request('/skills/undeploy', { method: 'POST', body: JSON.stringify({ name }) }),
  getDashboardStatus: () => request('/dashboard/status'),
  getProvidersQuota: () => request('/providers/quota'),
  getProvidersConsumption: () => request('/providers/consumption'),
  getRecentCommands: () => request('/recent-commands'),
  getRunningProcesses: () => request('/running-processes'),
  getSystemMetrics: () => request('/system/metrics'),
  getTestSnippet: () => request('/test/snippet'),
  getTestSessions: () => request('/test/sessions'),
  getTestConsole: (sessionId) => request(`/test/console/${encodeURIComponent(sessionId || '')}`),
  savePreferences: (prefs) => request('/preferences', { method: 'PUT', body: JSON.stringify(prefs) }),
  saveProfile: (profile) => request('/config/profile', { method: 'PUT', body: JSON.stringify(profile) }),
  saveProvider: (provider) => request('/config/provider', { method: 'PUT', body: JSON.stringify(provider) }),
  resetConfig: () => request('/config/reset', { method: 'POST' }),
  applyStarshipTheme: (theme) => request('/starship/apply-theme', { method: 'POST', body: JSON.stringify({ theme }) }),
  validateProvider: (provider) => request('/providers/validate', { method: 'POST', body: JSON.stringify(provider) }),
  runUpdate: (tool) => request('/update/run', { method: 'POST', body: JSON.stringify({ tool: tool || '' }) }),
  aiTask: (task, tool) => request('/ai/task', { method: 'POST', body: JSON.stringify({ task, tool: tool || '' }) }),
  runCommand: (command, cwd) => request('/terminal', { method: 'POST', body: JSON.stringify({ command, cwd }) }),
  getTerminalSessions: () => request('/terminal/sessions'),
  addSSHConnection: (conn) => request('/terminal/sessions', { method: 'POST', body: JSON.stringify(conn) }),
  deleteSSHConnection: (name) => request(`/terminal/sessions/${encodeURIComponent(name)}`, { method: 'DELETE' }),
  getTerminalThemes: () => request('/terminal/themes'),
  saveTerminalSettings: (settings) => request('/terminal/settings', { method: 'PUT', body: JSON.stringify(settings) }),
  getChatHistory: () => request('/chat/history'),
  clearChat: () => request('/chat/clear', { method: 'POST' }),
  summarizeChat: () => request('/chat/summarize', { method: 'POST' }),
  getShellChatHistory: () => request('/shell/chat/history'),
  clearShellChat: () => request('/shell/chat/clear', { method: 'POST' }),
  analyzeSystem: () => request('/shell/analyze', { method: 'POST' }),
  getShellAnalysis: () => request('/shell/analysis'),
  sendChat: (message, stream = true, onChunk, signal, images = [], advancedReflection = false) => {
    if (!stream) {
      return request('/chat', { method: 'POST', body: JSON.stringify({ message, stream: false, images, advanced_reflection: advancedReflection }) })
    }
    return new Promise((resolve, reject) => {
      fetch(`${API_BASE}/chat`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message, stream: true, images, advanced_reflection: advancedReflection }),
        signal,
      }).then(async (res) => {
        if (!res.ok) {
          const err = await res.json().catch(() => ({ error: res.statusText }))
          reject(new Error(err.error || res.statusText))
          return
        }
        const reader = res.body.getReader()
        const decoder = new TextDecoder()
        let full = ''
        while (true) {
          const { done, value } = await reader.read()
          if (done) break
          const text = decoder.decode(value, { stream: true })
          for (const line of text.split('\n')) {
            if (!line.startsWith('data: ')) continue
            try {
              const data = JSON.parse(line.slice(6))
              if (data.error) { reject(new Error(data.error)); return }
              if (data.done) { resolve(full); return }
              if (data.content) {
                full += data.content
                if (onChunk) onChunk(full, data)
              } else if (data.thinking !== undefined || data.thinking_end) {
                if (onChunk) onChunk(full, data)
              } else if (data.tool_call || data.tool_result) {
                if (onChunk) onChunk(full, data)
              }
            } catch {}
          }
        }
        resolve(full)
      }).catch(reject)
    })
  },
  sendShellChat: (message, context = {}, stream = true, onChunk, signal) => {
    const payload = {
      message,
      cwd: context.cwd || '',
      platform: context.platform || '',
      stream,
    }
    if (!stream) {
      return request('/shell/chat', { method: 'POST', body: JSON.stringify(payload) })
    }
    return new Promise((resolve, reject) => {
      fetch(`${API_BASE}/shell/chat`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
        signal,
      }).then(async (res) => {
        if (!res.ok) {
          const err = await res.json().catch(() => ({ error: res.statusText }))
          reject(new Error(err.error || res.statusText))
          return
        }
        const reader = res.body.getReader()
        const decoder = new TextDecoder()
        let full = ''
        while (true) {
          const { done, value } = await reader.read()
          if (done) break
          const text = decoder.decode(value, { stream: true })
          for (const line of text.split('\n')) {
            if (!line.startsWith('data: ')) continue
            try {
              const data = JSON.parse(line.slice(6))
              if (data.error) { reject(new Error(data.error)); return }
              if (data.done) { resolve({ content: full, tokens: data.tokens }); return }
              if (data.content) {
                full += data.content
                if (onChunk) onChunk(full, data)
              } else if (data.tool_call || data.tool_result) {
                if (onChunk) onChunk(full, data)
              } else if (data.thinking !== undefined || data.thinking_end) {
                if (onChunk) onChunk(full, data)
              }
            } catch {}
          }
        }
        resolve({ content: full })
      }).catch(reject)
    })
  },
  ragIndex: (text, name, type) => request('/rag/index', { method: 'POST', body: JSON.stringify({ text, name, type: type || 'text' }) }),
  ragIndexFile: (file) => {
    const formData = new FormData()
    formData.append('file', file)
    return fetch(`${API_BASE}/rag/index`, { method: 'POST', body: formData }).then(r => {
      if (!r.ok) return r.json().then(e => { throw new Error(e.error || r.statusText) })
      return r.json()
    })
  },
  ragSearch: (query, limit) => request('/rag/search', { method: 'POST', body: JSON.stringify({ query, limit: limit || 5 }) }),
  ragStatus: () => request('/rag/status'),
  ragDocuments: () => request('/rag/documents'),
  ragDelete: (id) => fetch(`${API_BASE}/rag/index/${id}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json' } }).then(r => r.json()),
  pipelineFilters: () => request('/pipeline/filters'),
  pipelineToggle: (name, enabled) => request(`/pipeline/filters/${name}`, { method: 'POST', body: JSON.stringify({ enabled }) }),
  generateImage: (prompt, size, style) => request('/images/generate', { method: 'POST', body: JSON.stringify({ prompt, size: size || '1024x1024', style: style || 'vivid' }) }),
  fileRead: (path) => request(`/files/content?path=${encodeURIComponent(path)}`),
  fileWrite: (path, content) => request('/files/content', { method: 'PUT', body: JSON.stringify({ path, content }) }),
  mcpServerStatus: () => request('/mcp-server/status'),
  mcpServerStart: () => request('/mcp-server/start', { method: 'POST' }),
  mcpServerStop: () => request('/mcp-server/stop', { method: 'POST' }),
  getAgentSessions: () => request('/agent-sessions'),
  getAgentSessionOutput: (id) => request(`/agent-sessions/${encodeURIComponent(id)}`),
  getWorkspaces: () => request('/workspaces'),
  saveWorkspace: (name, layout, tabs) => request('/workspace', { method: 'POST', body: JSON.stringify({ name, layout, tabs }) }),
  getWorkspace: (name) => request(`/workspace/${encodeURIComponent(name)}`),
  deleteWorkspace: (name) => request(`/workspace/${encodeURIComponent(name)}`, { method: 'DELETE' }),
}

export default api
