/**
 * Rig Service Client for QwenClaw
 * 
 * TypeScript client for communicating with the Rig AI agent service
 */

export interface RigConfig {
  host: string;
  port: number;
}

export interface AgentConfig {
  name: string;
  preamble: string;
  model?: string;
  provider?: string;
  temperature?: number;
}

export interface Tool {
  name: string;
  description: string;
  parameters: Record<string, unknown>;
  category: string;
}

export interface Document {
  id: string;
  content: string;
  metadata: Record<string, unknown>;
}

export class RigClient {
  private baseUrl: string;

  constructor(config: RigConfig) {
    this.baseUrl = `http://${config.host}:${config.port}`;
  }

  // Health check
  async health(): Promise<boolean> {
    try {
      const res = await fetch(`${this.baseUrl}/health`);
      const data = await res.json();
      return data.status === "ok";
    } catch {
      return false;
    }
  }

  // ========== Agent Methods ==========

  async createAgent(config: AgentConfig): Promise<string> {
    const res = await fetch(`${this.baseUrl}/api/agents`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(config),
    });

    if (!res.ok) {
      throw new Error(`Failed to create agent: ${res.statusText}`);
    }

    const data = await res.json();
    return data.session_id;
  }

  async listAgents(): Promise<Array<{ id: string; name: string; model: string }>> {
    const res = await fetch(`${this.baseUrl}/api/agents`);
    if (!res.ok) {
      throw new Error(`Failed to list agents: ${res.statusText}`);
    }

    const data = await res.json();
    return data.agents;
  }

  async executePrompt(sessionId: string, prompt: string): Promise<string> {
    const res = await fetch(`${this.baseUrl}/api/agents/${sessionId}/prompt`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ prompt }),
    });

    if (!res.ok) {
      throw new Error(`Failed to execute prompt: ${res.statusText}`);
    }

    const data = await res.json();
    return data.response;
  }

  async getAgent(sessionId: string): Promise<AgentConfig & { id: string }> {
    const res = await fetch(`${this.baseUrl}/api/agents/${sessionId}`);
    if (!res.ok) {
      throw new Error(`Failed to get agent: ${res.statusText}`);
    }

    const data = await res.json();
    return data.agent;
  }

  async deleteAgent(sessionId: string): Promise<void> {
    const res = await fetch(`${this.baseUrl}/api/agents/${sessionId}`, {
      method: "DELETE",
    });

    if (!res.ok) {
      throw new Error(`Failed to delete agent: ${res.statusText}`);
    }
  }

  // ========== Council Methods ==========

  async createCouncil(
    name: string,
    agents: AgentConfig[]
  ): Promise<string> {
    const res = await fetch(`${this.baseUrl}/api/councils`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name, agents }),
    });

    if (!res.ok) {
      throw new Error(`Failed to create council: ${res.statusText}`);
    }

    const data = await res.json();
    return data.council_id;
  }

  async listCouncils(): Promise<Array<{ id: string; name: string; agents: Array<{ id: string; name: string }> }>> {
    const res = await fetch(`${this.baseUrl}/api/councils`);
    if (!res.ok) {
      throw new Error(`Failed to list councils: ${res.statusText}`);
    }

    const data = await res.json();
    return data.councils;
  }

  async executeCouncil(councilId: string, task: string): Promise<string> {
    const res = await fetch(`${this.baseUrl}/api/councils/${councilId}/execute`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ task }),
    });

    if (!res.ok) {
      throw new Error(`Failed to execute council: ${res.statusText}`);
    }

    const data = await res.json();
    return data.response;
  }

  // ========== Tool Methods ==========

  async listTools(): Promise<Tool[]> {
    const res = await fetch(`${this.baseUrl}/api/tools`);
    if (!res.ok) {
      throw new Error(`Failed to list tools: ${res.statusText}`);
    }

    const data = await res.json();
    return data.tools;
  }

  async searchTools(query: string, limit = 10): Promise<Tool[]> {
    const res = await fetch(`${this.baseUrl}/api/tools/search`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ query, limit }),
    });

    if (!res.ok) {
      throw new Error(`Failed to search tools: ${res.statusText}`);
    }

    const data = await res.json();
    return data.tools;
  }

  // ========== Document Methods ==========

  async addDocument(content: string, metadata?: Record<string, unknown>): Promise<string> {
    const res = await fetch(`${this.baseUrl}/api/documents`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ content, metadata }),
    });

    if (!res.ok) {
      throw new Error(`Failed to add document: ${res.statusText}`);
    }

    const data = await res.json();
    return data.id;
  }

  async searchDocuments(query: string, limit = 10): Promise<Document[]> {
    const res = await fetch(`${this.baseUrl}/api/documents/search`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ query, limit }),
    });

    if (!res.ok) {
      throw new Error(`Failed to search documents: ${res.statusText}`);
    }

    const data = await res.json();
    return data.documents;
  }

  async getDocument(id: string): Promise<Document> {
    const res = await fetch(`${this.baseUrl}/api/documents/${id}`);
    if (!res.ok) {
      throw new Error(`Failed to get document: ${res.statusText}`);
    }

    const data = await res.json();
    return data.document;
  }

  async deleteDocument(id: string): Promise<void> {
    const res = await fetch(`${this.baseUrl}/api/documents/${id}`, {
      method: "DELETE",
    });

    if (!res.ok) {
      throw new Error(`Failed to delete document: ${res.statusText}`);
    }
  }
}

// Export default client instance
export default RigClient;
