package ai.sentryagent.idp.services;

import ai.sentryagent.idp.internal.HttpHelper;
import ai.sentryagent.idp.models.*;

import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

/**
 * Client for the Agent Registry API endpoints.
 * Provides both synchronous and asynchronous (CompletableFuture) methods.
 */
public final class AgentRegistryClient {

    private final String baseUrl;
    private final Supplier<String> tokenSupplier;
    private final HttpHelper http;

    public AgentRegistryClient(String baseUrl, Supplier<String> tokenSupplier, HttpHelper http) {
        this.baseUrl       = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
        this.tokenSupplier = tokenSupplier;
        this.http          = http;
    }

    // ─── Sync ─────────────────────────────────────────────────────────────────

    /** POST /api/v1/agents → 201 Agent */
    public Agent registerAgent(RegisterAgentRequest request) {
        return http.request("POST", baseUrl + "/api/v1/agents", request, tokenSupplier.get(), Agent.class);
    }

    /** GET /api/v1/agents → 200 PaginatedAgents */
    public PaginatedAgents listAgents(ListAgentsParams params) {
        return http.request("GET", buildListUrl(params), null, tokenSupplier.get(), PaginatedAgents.class);
    }

    /** GET /api/v1/agents/:id → 200 Agent */
    public Agent getAgent(String agentId) {
        return http.request("GET", baseUrl + "/api/v1/agents/" + agentId, null, tokenSupplier.get(), Agent.class);
    }

    /** PATCH /api/v1/agents/:id → 200 Agent */
    public Agent updateAgent(String agentId, UpdateAgentRequest request) {
        return http.request("PATCH", baseUrl + "/api/v1/agents/" + agentId, request, tokenSupplier.get(), Agent.class);
    }

    /** DELETE /api/v1/agents/:id → 204 No Content */
    public void decommissionAgent(String agentId) {
        http.request("DELETE", baseUrl + "/api/v1/agents/" + agentId, null, tokenSupplier.get(), Void.class);
    }

    // ─── Async ────────────────────────────────────────────────────────────────

    /** Async version of {@link #registerAgent}. */
    public CompletableFuture<Agent> registerAgentAsync(RegisterAgentRequest request) {
        return CompletableFuture.supplyAsync(tokenSupplier)
            .thenCompose(token -> http.requestAsync("POST", baseUrl + "/api/v1/agents", request, token, Agent.class));
    }

    /** Async version of {@link #listAgents}. */
    public CompletableFuture<PaginatedAgents> listAgentsAsync(ListAgentsParams params) {
        return CompletableFuture.supplyAsync(tokenSupplier)
            .thenCompose(token -> http.requestAsync("GET", buildListUrl(params), null, token, PaginatedAgents.class));
    }

    /** Async version of {@link #getAgent}. */
    public CompletableFuture<Agent> getAgentAsync(String agentId) {
        return CompletableFuture.supplyAsync(tokenSupplier)
            .thenCompose(token -> http.requestAsync("GET", baseUrl + "/api/v1/agents/" + agentId, null, token, Agent.class));
    }

    /** Async version of {@link #updateAgent}. */
    public CompletableFuture<Agent> updateAgentAsync(String agentId, UpdateAgentRequest request) {
        return CompletableFuture.supplyAsync(tokenSupplier)
            .thenCompose(token -> http.requestAsync("PATCH", baseUrl + "/api/v1/agents/" + agentId, request, token, Agent.class));
    }

    /** Async version of {@link #decommissionAgent}. */
    public CompletableFuture<Void> decommissionAgentAsync(String agentId) {
        return CompletableFuture.supplyAsync(tokenSupplier)
            .thenCompose(token -> http.requestAsync("DELETE", baseUrl + "/api/v1/agents/" + agentId, null, token, Void.class));
    }

    // ─── URL builder ──────────────────────────────────────────────────────────

    private String buildListUrl(ListAgentsParams params) {
        StringBuilder url = new StringBuilder(baseUrl + "/api/v1/agents");
        if (params != null) {
            StringBuilder query = new StringBuilder();
            appendParam(query, "status",        params.getStatus());
            appendParam(query, "agentType",     params.getAgentType());
            appendParam(query, "deploymentEnv", params.getDeploymentEnv());
            if (params.getPage()  != null) appendParam(query, "page",  params.getPage().toString());
            if (params.getLimit() != null) appendParam(query, "limit", params.getLimit().toString());
            if (query.length() > 0) url.append("?").append(query.substring(1)); // trim leading &
        }
        return url.toString();
    }

    private static void appendParam(StringBuilder sb, String key, String value) {
        if (value != null && !value.isEmpty()) {
            sb.append("&").append(key).append("=").append(value);
        }
    }
}
