/**
 * API klientas ir bendri tipai (atspindi backend `types.ts`).
 * Typed fetch helpers for the A.R.K.A. node API.
 */
export type Bilingual = { lt: string; en: string }
export type TcpLayer = 'perimeter' | 'system' | 'human'
export type ModuleStatus = 'online' | 'degraded' | 'offline' | 'not_installed'
export type KnowledgeCategory =
  | 'medicine'
  | 'survival'
  | 'security'
  | 'engineering'
  | 'comms'

export interface ArkaModule {
  id: string
  name: Bilingual
  description: Bilingual
  layer: TcpLayer
  icon: string
  status: ModuleStatus
  tcpStep: Bilingual
}

export interface LayerSummary {
  layer: TcpLayer
  online: number
  total: number
}

export interface NodeStatus {
  status: 'operational' | 'degraded' | 'critical'
  modules: ArkaModule[]
  layers: LayerSummary[]
  readiness: number
  node: {
    name: string
    version: string
    hostname: string
    mode: 'local-only'
    uptimeSeconds: number
    processUptimeSeconds: number
    memory: { totalBytes: number; freeBytes: number; usedPercent: number }
    storage: { path: string; totalBytes: number; freeBytes: number; usedPercent: number }
    updatedAt: string
  }
  summary: Record<ModuleStatus, number>
}

export interface KnowledgeEntry {
  id: string
  title: Bilingual
  category: KnowledgeCategory
  tags: string[]
  body: Bilingual
}

export interface KnowledgeHit {
  entry: KnowledgeEntry
  score: number
}

export type ResourceType = 'wiki' | 'map'

export interface DownloadResource {
  id: string
  type: ResourceType
  name: Bilingual
  description: Bilingual
  url: string
  filename: string
  sizeBytes: number
  custom?: boolean
}

export interface CustomResourceInput {
  type: ResourceType
  name: string
  description?: string
  url: string
}

export type DownloadStatus =
  | 'queued'
  | 'downloading'
  | 'completed'
  | 'failed'
  | 'canceled'

export interface DownloadTask {
  id: string
  resourceId: string
  type: ResourceType
  filename: string
  status: DownloadStatus
  totalBytes: number
  receivedBytes: number
  startedAt: number
  finishedAt?: number
  error?: string
  percent: number
}

export interface CatalogItem {
  resource: DownloadResource
  downloaded: boolean
  task: DownloadTask | null
}

export interface ChatMessage {
  role: 'system' | 'user' | 'assistant'
  content: string
}

export interface AssistantReply {
  content: string
  sources: { id: string; title: string }[]
  mode: 'llm' | 'fallback'
}

async function getJson<T>(url: string): Promise<T> {
  const res = await fetch(url)
  if (!res.ok) throw new Error(`API ${res.status}: ${url}`)
  return res.json() as Promise<T>
}

export const api = {
  getStatus: () => getJson<NodeStatus>('/api/system/status'),
  listKnowledge: (category?: string) =>
    getJson<{ entries: KnowledgeEntry[] }>(
      `/api/knowledge${category ? `?category=${category}` : ''}`
    ),
  searchKnowledge: (q: string) =>
    getJson<{ query: string; results: KnowledgeHit[] }>(
      `/api/knowledge?q=${encodeURIComponent(q)}`
    ),
  chat: async (messages: ChatMessage[]): Promise<AssistantReply> => {
    const res = await fetch('/api/ai/chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ messages }),
    })
    if (!res.ok) throw new Error(`AI API ${res.status}`)
    return res.json() as Promise<AssistantReply>
  },

  // ── Atsisiunčiamas turinys (wiki ZIM, žemėlapiai) ──
  getCatalog: (type?: ResourceType) =>
    getJson<{ items: CatalogItem[] }>(`/api/catalog${type ? `?type=${type}` : ''}`),
  listDownloads: () => getJson<{ downloads: DownloadTask[] }>('/api/downloads'),
  startDownload: async (resourceId: string): Promise<DownloadTask> => {
    const res = await fetch('/api/downloads', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ resourceId }),
    })
    if (!res.ok) throw new Error(`Download API ${res.status}`)
    return res.json() as Promise<DownloadTask>
  },
  cancelDownload: async (id: string): Promise<{ canceled: boolean }> => {
    const res = await fetch(`/api/downloads/${id}`, { method: 'DELETE' })
    return res.json() as Promise<{ canceled: boolean }>
  },
  addResource: async (input: CustomResourceInput): Promise<DownloadResource> => {
    const res = await fetch('/api/catalog', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(input),
    })
    if (!res.ok) {
      const err = (await res.json().catch(() => ({}))) as { error?: string }
      throw new Error(err.error ?? `HTTP ${res.status}`)
    }
    return res.json() as Promise<DownloadResource>
  },
  removeResource: async (id: string): Promise<{ removed: boolean }> => {
    const res = await fetch(`/api/catalog/${id}`, { method: 'DELETE' })
    return res.json() as Promise<{ removed: boolean }>
  },

  // ── ZIM (wiki) skaitytuvas ──
  getZimInfo: (id: string) =>
    getJson<{ articleCount: number; mainPath: string; mainTitle: string }>(
      `/api/zim/${id}/info`
    ),
  searchZim: (id: string, q: string) =>
    getJson<{ results: { path: string; title: string }[] }>(
      `/api/zim/${id}/search?q=${encodeURIComponent(q)}`
    ),
  fullTextZim: (id: string, q: string) =>
    getJson<{
      results: { path: string; title: string; snippet: string }[]
      truncated: boolean
    }>(`/api/zim/${id}/fulltext?q=${encodeURIComponent(q)}`),
  /** URL straipsnio/ištekliaus turiniui (naudojama iframe src). */
  zimContentUrl: (id: string, path: string) =>
    `/api/zim/${id}/content/${path.split('/').map(encodeURIComponent).join('/')}`,
}

/** Žmogui skaitomas baitų formatas. */
export function formatBytes(bytes: number): string {
  if (bytes >= 1024 ** 3) return `${(bytes / 1024 ** 3).toFixed(1)} GB`
  if (bytes >= 1024 ** 2) return `${Math.round(bytes / 1024 ** 2)} MB`
  if (bytes >= 1024) return `${Math.round(bytes / 1024)} KB`
  return `${bytes} B`
}
