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 Credential Management API endpoints.
 * Provides both synchronous and asynchronous (CompletableFuture) methods.
 */
public final class CredentialClient {

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

    public CredentialClient(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/:id/credentials → 201 CredentialWithSecret */
    public CredentialWithSecret generateCredential(String agentId) {
        return http.request("POST", baseUrl + "/api/v1/agents/" + agentId + "/credentials",
            null, tokenSupplier.get(), CredentialWithSecret.class);
    }

    /** GET /api/v1/agents/:id/credentials → 200 PaginatedCredentials */
    public PaginatedCredentials listCredentials(String agentId, Integer page, Integer limit) {
        return http.request("GET", buildListUrl(agentId, page, limit),
            null, tokenSupplier.get(), PaginatedCredentials.class);
    }

    /** POST /api/v1/agents/:id/credentials/:credId/rotate → 200 CredentialWithSecret */
    public CredentialWithSecret rotateCredential(String agentId, String credentialId) {
        return http.request("POST",
            baseUrl + "/api/v1/agents/" + agentId + "/credentials/" + credentialId + "/rotate",
            null, tokenSupplier.get(), CredentialWithSecret.class);
    }

    /** DELETE /api/v1/agents/:id/credentials/:credId → 200 Credential */
    public Credential revokeCredential(String agentId, String credentialId) {
        return http.request("DELETE",
            baseUrl + "/api/v1/agents/" + agentId + "/credentials/" + credentialId,
            null, tokenSupplier.get(), Credential.class);
    }

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

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

    /** Async version of {@link #listCredentials}. */
    public CompletableFuture<PaginatedCredentials> listCredentialsAsync(String agentId, Integer page, Integer limit) {
        return CompletableFuture.supplyAsync(tokenSupplier)
            .thenCompose(token -> http.requestAsync("GET", buildListUrl(agentId, page, limit),
                null, token, PaginatedCredentials.class));
    }

    /** Async version of {@link #rotateCredential}. */
    public CompletableFuture<CredentialWithSecret> rotateCredentialAsync(String agentId, String credentialId) {
        return CompletableFuture.supplyAsync(tokenSupplier)
            .thenCompose(token -> http.requestAsync("POST",
                baseUrl + "/api/v1/agents/" + agentId + "/credentials/" + credentialId + "/rotate",
                null, token, CredentialWithSecret.class));
    }

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

    private String buildListUrl(String agentId, Integer page, Integer limit) {
        StringBuilder url = new StringBuilder(baseUrl + "/api/v1/agents/" + agentId + "/credentials");
        StringBuilder query = new StringBuilder();
        if (page  != null) { query.append("&page=").append(page); }
        if (limit != null) { query.append("&limit=").append(limit); }
        if (query.length() > 0) url.append("?").append(query.substring(1));
        return url.toString();
    }
}
