/**
 * api/agentpacks.ts — client for AgentPack endpoints (M2 Phase H).
 *
 * Endpoints:
 *   GET    /api/v1/agentpacks               → list installed packs
 *   GET    /api/v1/agentpacks/{id}          → pack detail
 *   POST   /api/v1/agentpacks/install       → install from local zip path (loopback)
 *   POST   /api/v1/agentpacks/install-upload→ install from file upload (loopback)
 *   DELETE /api/v1/agentpacks/{id}          → uninstall
 *   POST   /api/v1/agentpacks/{id}/create-agent → create agent from pack
 */
import { useAppStore } from '../store/app'
import { api } from './client'

export interface PackPermissions {
  network: boolean
  shell: boolean
  file_write: string
}

export interface AgentPack {
  id: string
  version: string
  name: string
  domain: string
  path: string
  description: string | null
  audience: string[]
  permissions: PackPermissions
  permission_summary: string
  model_recommended: string[]
  entrypoint: string
  /** Only present on GET /agentpacks/{id} (detail), not in list. */
  entrypoint_config?: Record<string, unknown>
}

export interface ListPacksResponse {
  agentpacks: AgentPack[]
  count: number
}

export interface InstallResponse {
  ok: boolean
  installed: AgentPack
}

export interface CreateAgentResponse {
  ok: boolean
  agent_id: string
  name: string
  pack: { id: string; version: string; name: string }
}

export interface UninstallResponse {
  ok: boolean
  removed_versions: number
}

export interface UpdatePackResponse {
  ok: boolean
  installed: AgentPack
  previous_version: string
  /** 被同步刷新到新配置的智能体（各自生成了新 agent_version） */
  refreshed_agents: { agent_id: string; name: string; version: number }[]
}

export const agentpacksApi = {
  list: (): Promise<ListPacksResponse> =>
    api.get('/agentpacks'),

  get: (packId: string, version?: string): Promise<AgentPack> =>
    api.get(`/agentpacks/${packId}${version ? `?version=${version}` : ''}`),

  install: (zipPath: string, allowShell = false): Promise<InstallResponse> =>
    api.post('/agentpacks/install', { zip_path: zipPath, allow_shell: allowShell }),

  /** Upload a .zip File object (from <input type="file">). Uses multipart/form-data. */
  installUpload: async (file: File, allowShell = false): Promise<InstallResponse> => {
    const apiKey = useAppStore.getState().apiKey
    const form = new FormData()
    form.append('file', file)
    if (allowShell) form.append('allow_shell', 'true')
    const res = await fetch(`/api/v1/agentpacks/install-upload`, {
      method: 'POST',
      headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
      body: form,
    })
    if (!res.ok) {
      let msg = res.statusText
      try { msg = (await res.json())?.detail ?? msg } catch { /* ignore */ }
      throw new Error(msg)
    }
    return res.json()
  },

  /** 上传 .zip 更新已安装的包，并把新配置传播到由它创建的所有智能体
   *  （每个智能体生成新 agent_version，可回滚）。Loopback-only。 */
  updateUpload: async (
    packId: string, file: File, allowShell = false,
  ): Promise<UpdatePackResponse> => {
    const apiKey = useAppStore.getState().apiKey
    const form = new FormData()
    form.append('file', file)
    if (allowShell) form.append('allow_shell', 'true')
    const res = await fetch(`/api/v1/agentpacks/${packId}/update-upload`, {
      method: 'POST',
      headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : {},
      body: form,
    })
    if (!res.ok) {
      let msg = res.statusText
      try { msg = (await res.json())?.detail ?? msg } catch { /* ignore */ }
      throw new Error(typeof msg === 'string' ? msg : JSON.stringify(msg))
    }
    return res.json()
  },

  uninstall: (packId: string, version?: string): Promise<UninstallResponse> =>
    api.delete(`/agentpacks/${packId}${version ? `?version=${version}` : ''}`),

  createAgent: (
    packId: string,
    payload: {
      name: string
      description?: string
      version?: string
      kb_ids?: string[]
      tags?: string[]
      /** Override the pack's model (provider + name). */
      model_override?: { provider?: string; name?: string }
      /** Replace the pack's systemPrompt entirely. Empty string = use pack default. */
      system_prompt_override?: string
      /** 3-directory config */
      work_dir?: string
      source_dir?: string
      run_dir?: string
    },
  ): Promise<CreateAgentResponse> =>
    api.post(`/agentpacks/${packId}/create-agent`, payload),
}
