import { API_BASE_URL } from "@/lib/config";

const BASE_URL = API_BASE_URL;

// --- Types ---

export type MCPServerStatus = "connecting" | "connected" | "disconnected" | "error";

export type MCPServerConfig = {
  transport: "stdio" | "sse" | "streamable-http";
  command?: string;
  args?: string[];
  env?: Record<string, string>;
  url?: string;
  headers?: Record<string, string>;
  enabled: boolean;
};

export type MCPToolInfo = {
  name: string;
  description: string | null;
  input_schema: Record<string, unknown>;
  server_name: string;
};

export type MCPServerInfo = {
  name: string;
  config: MCPServerConfig;
  status: MCPServerStatus;
  tools: MCPToolInfo[];
  error: string | null;
  connected_at: string | null;
};

// --- API Functions ---

export async function fetchMCPServers(): Promise<MCPServerInfo[]> {
  const res = await fetch(`${BASE_URL}/api/mcp/servers`);
  if (!res.ok) throw new Error("Failed to fetch servers");
  return res.json();
}

export async function addMCPServer(name: string, config: MCPServerConfig): Promise<MCPServerInfo> {
  const res = await fetch(`${BASE_URL}/api/mcp/servers`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name, config }),
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.detail || "Failed to add server");
  }
  return res.json();
}

export async function updateMCPServer(name: string, config: Partial<MCPServerConfig>): Promise<MCPServerInfo> {
  const res = await fetch(`${BASE_URL}/api/mcp/servers/${encodeURIComponent(name)}`, {
    method: "PATCH",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(config),
  });
  if (!res.ok) throw new Error("Failed to update server");
  return res.json();
}

export async function deleteMCPServer(name: string): Promise<void> {
  const res = await fetch(`${BASE_URL}/api/mcp/servers/${encodeURIComponent(name)}`, {
    method: "DELETE",
  });
  if (!res.ok) throw new Error("Failed to delete server");
}

export async function connectServer(name: string): Promise<MCPServerInfo> {
  const res = await fetch(`${BASE_URL}/api/mcp/servers/${encodeURIComponent(name)}/connect`, {
    method: "POST",
  });
  if (!res.ok) throw new Error("Failed to connect server");
  return res.json();
}

export async function disconnectServer(name: string): Promise<MCPServerInfo> {
  const res = await fetch(`${BASE_URL}/api/mcp/servers/${encodeURIComponent(name)}/disconnect`, {
    method: "POST",
  });
  if (!res.ok) throw new Error("Failed to disconnect server");
  return res.json();
}

export async function restartServer(name: string): Promise<MCPServerInfo> {
  const res = await fetch(`${BASE_URL}/api/mcp/servers/${encodeURIComponent(name)}/restart`, {
    method: "POST",
  });
  if (!res.ok) throw new Error("Failed to restart server");
  return res.json();
}

export async function fetchMCPTools(serverName?: string): Promise<MCPToolInfo[]> {
  const url = serverName
    ? `${BASE_URL}/api/mcp/tools/${encodeURIComponent(serverName)}`
    : `${BASE_URL}/api/mcp/tools`;
  const res = await fetch(url);
  if (!res.ok) throw new Error("Failed to fetch tools");
  return res.json();
}

export async function fetchMCPConfig(): Promise<Record<string, unknown>> {
  const res = await fetch(`${BASE_URL}/api/mcp/config`);
  if (!res.ok) throw new Error("Failed to fetch config");
  return res.json();
}

export async function updateMCPConfig(config: Record<string, unknown>): Promise<Record<string, unknown>> {
  const res = await fetch(`${BASE_URL}/api/mcp/config`, {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(config),
  });
  if (!res.ok) throw new Error("Failed to update config");
  return res.json();
}

export async function reloadMCPConfig(): Promise<void> {
  const res = await fetch(`${BASE_URL}/api/mcp/reload`, { method: "POST" });
  if (!res.ok) throw new Error("Failed to reload config");
}
