import { request } from '../request.js';
import type {
  Agent,
  RegisterAgentRequest,
  UpdateAgentRequest,
  ListAgentsParams,
  PaginatedAgents,
} from '../types.js';

/**
 * Client for the Agent Registry service.
 * Covers all agent CRUD operations: register, list, get, update, decommission.
 */
export class AgentRegistryClient {
  constructor(
    private readonly baseUrl: string,
    private readonly getToken: () => Promise<string>,
  ) {}

  /**
   * Register a new AI agent.
   * Returns the created agent record including its agentId and agentSecret.
   */
  async registerAgent(params: RegisterAgentRequest): Promise<Agent> {
    const token = await this.getToken();
    return request<Agent>(this.baseUrl, {
      method: 'POST',
      path: '/api/v1/agents',
      token,
      body: params,
    });
  }

  /**
   * List all registered agents with optional filters and pagination.
   */
  async listAgents(params: ListAgentsParams = {}): Promise<PaginatedAgents> {
    const token = await this.getToken();
    return request<PaginatedAgents>(this.baseUrl, {
      method: 'GET',
      path: '/api/v1/agents',
      token,
      query: {
        status: params.status,
        agentType: params.agentType,
        page: params.page,
        limit: params.limit,
      },
    });
  }

  /**
   * Get a single agent by its agentId.
   */
  async getAgent(agentId: string): Promise<Agent> {
    const token = await this.getToken();
    return request<Agent>(this.baseUrl, {
      method: 'GET',
      path: `/api/v1/agents/${agentId}`,
      token,
    });
  }

  /**
   * Update mutable fields on an existing agent (name, description, capabilities, metadata).
   * Returns the updated agent record.
   */
  async updateAgent(agentId: string, params: UpdateAgentRequest): Promise<Agent> {
    const token = await this.getToken();
    return request<Agent>(this.baseUrl, {
      method: 'PATCH',
      path: `/api/v1/agents/${agentId}`,
      token,
      body: params,
    });
  }

  /**
   * Decommission an agent. This is irreversible — the agent can no longer
   * authenticate or obtain tokens after decommission.
   */
  async decommissionAgent(agentId: string): Promise<void> {
    const token = await this.getToken();
    return request<void>(this.baseUrl, {
      method: 'DELETE',
      path: `/api/v1/agents/${agentId}`,
      token,
    });
  }
}
