"use client";

import { useState, useEffect, useCallback } from "react";
import type { McpServerDefinition } from "@/lib/types";

interface UseMcpServersReturn {
  servers: McpServerDefinition[];
  loading: boolean;
  error: string | null;
  selectedServer: McpServerDefinition | null;
  selectServer: (name: string) => void;
  clearSelection: () => void;
  addServer: (server: { name: string; description: string; command: string; args: string[]; env: Record<string, string> }) => Promise<void>;
  updateServer: (name: string, updates: { description?: string; command?: string; args?: string[]; env?: Record<string, string> }) => Promise<void>;
  deleteServer: (name: string) => Promise<void>;
  updateAgents: (name: string, agents: string[]) => Promise<void>;
  refresh: () => void;
}

export function useMcpServers(): UseMcpServersReturn {
  const [servers, setServers] = useState<McpServerDefinition[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedServer, setSelectedServer] = useState<McpServerDefinition | null>(null);
  const [refreshKey, setRefreshKey] = useState(0);

  const refresh = useCallback(() => setRefreshKey((k) => k + 1), []);

  useEffect(() => {
    setLoading(true);
    fetch("/api/mcp")
      .then((r) => r.json())
      .then((data: { servers: McpServerDefinition[] }) => {
        setServers(data.servers);
        setError(null);
      })
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false));
  }, [refreshKey]);

  const selectServer = useCallback((name: string) => {
    fetch(`/api/mcp/${encodeURIComponent(name)}`)
      .then((r) => r.json())
      .then((data: { server: McpServerDefinition }) => setSelectedServer(data.server))
      .catch((err) => setError(err.message));
  }, []);

  const clearSelection = useCallback(() => setSelectedServer(null), []);

  const addServer = useCallback(async (server: { name: string; description: string; command: string; args: string[]; env: Record<string, string> }) => {
    const resp = await fetch("/api/mcp", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(server),
    });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to add MCP server");
    }
    refresh();
  }, [refresh]);

  const updateServerFn = useCallback(async (name: string, updates: { description?: string; command?: string; args?: string[]; env?: Record<string, string> }) => {
    const resp = await fetch(`/api/mcp/${encodeURIComponent(name)}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(updates),
    });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to update server");
    }
    const data = await resp.json();
    setSelectedServer(data.server);
    refresh();
  }, [refresh]);

  const deleteServerFn = useCallback(async (name: string) => {
    const resp = await fetch(`/api/mcp/${encodeURIComponent(name)}`, { method: "DELETE" });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to delete server");
    }
    setSelectedServer(null);
    refresh();
  }, [refresh]);

  const updateAgents = useCallback(async (name: string, agents: string[]) => {
    const resp = await fetch(`/api/mcp/${encodeURIComponent(name)}/agents`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ agents }),
    });
    if (!resp.ok) {
      const data = await resp.json();
      throw new Error(data.error || "Failed to update agents");
    }
    const data = await resp.json();
    setSelectedServer(data.server);
    refresh();
  }, [refresh]);

  return {
    servers,
    loading,
    error,
    selectedServer,
    selectServer,
    clearSelection,
    addServer,
    updateServer: updateServerFn,
    deleteServer: deleteServerFn,
    updateAgents,
    refresh,
  };
}
