// Primenza Java SDK v1
package com.primenza.sdk;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class PrimenzaClient {
    private final String apiKey;
    private final String baseUrl;
    private final HttpClient client;

    public PrimenzaClient(String apiKey) {
        this(apiKey, "https://primenza.com/api/v1");
    }

    public PrimenzaClient(String apiKey, String baseUrl) {
        this.apiKey = apiKey;
        this.baseUrl = baseUrl.replaceAll("/$", "");
        this.client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
    }

    public String request(String method, String path, String body) throws Exception {
        HttpRequest.Builder builder = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + path))
            .header("Authorization", "Bearer " + apiKey)
            .header("X-API-Key", apiKey)
            .header("Content-Type", "application/json")
            .header("Accept", "application/json")
            .timeout(Duration.ofSeconds(30));

        if ("POST".equals(method)) {
            builder.POST(body != null ? HttpRequest.BodyPublishers.ofString(body) : HttpRequest.BodyPublishers.noBody());
        } else if ("PATCH".equals(method)) {
            builder.method("PATCH", body != null ? HttpRequest.BodyPublishers.ofString(body) : HttpRequest.BodyPublishers.noBody());
        } else if ("PUT".equals(method)) {
            builder.PUT(body != null ? HttpRequest.BodyPublishers.ofString(body) : HttpRequest.BodyPublishers.noBody());
        } else if ("DELETE".equals(method)) {
            builder.DELETE();
        } else {
            builder.GET();
        }

        HttpResponse<String> response = client.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    public String domains() throws Exception { return request("GET", "/domains", null); }
    public String domain(int domainId) throws Exception { return request("GET", "/domains/" + domainId, null); }
    public String crawl(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/crawl", null); }
    public String audit(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/audit", null); }
    public String seo(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/seo", null); }
    public String runSeo(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/seo/run", null); }
    public String geo(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/geo", null); }
    public String runGeo(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/geo/run", null); }
    public String aiVisibility(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/ai-visibility", null); }
    public String runAiVisibility(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/ai-visibility/run", null); }
    public String performance(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/performance", null); }
    public String runPerformance(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/performance/run", null); }
    public String links(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/links", null); }
    public String runLinks(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/links/run", null); }
    public String contentGaps(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/content-gaps", null); }
    public String discoverContentGaps(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/content-gaps/discover", null); }
    public String dashboard() throws Exception { return request("GET", "/dashboard", null); }
    public String dashboard(int domainId) throws Exception { return request("GET", "/dashboard?domain_id=" + domainId, null); }
    public String createDomain(String url, String name) throws Exception {
        String body = name != null
            ? "{\"url\":\"" + url + "\",\"name\":\"" + name.replace("\"", "\\\"") + "\"}"
            : "{\"url\":\"" + url + "\"}";
        return request("POST", "/domains", body);
    }
    public String updateDomain(int domainId, String jsonBody) throws Exception {
        return request("PATCH", "/domains/" + domainId, jsonBody);
    }
    public String deleteDomain(int domainId) throws Exception { return request("DELETE", "/domains/" + domainId, null); }
    public String verifyDomain(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/verify", null); }
    public String detectTech(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/detect-tech", null); }
    public String pages(int domainId, int page) throws Exception { return request("GET", "/domains/" + domainId + "/pages?page=" + page, null); }
    public String audits(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/audits", null); }
    public String schema(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/schema", null); }
    public String robots(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/robots", null); }
    public String deployRobots(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/robots/deploy", null); }
    public String deployLlms(int domainId, String type) throws Exception {
        String deployType = type != null ? type : "llms";
        return request("POST", "/domains/" + domainId + "/llms-txt/deploy", "{\"type\":\"" + deployType + "\"}");
    }
    public String competitors(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/competitors", null); }
    public String addCompetitor(int domainId, String url) throws Exception {
        return request("POST", "/domains/" + domainId + "/competitors", "{\"url\":\"" + url.replace("\"", "\\\"") + "\"}");
    }
    public String refreshCompetitor(int domainId, int competitorId) throws Exception {
        return request("POST", "/domains/" + domainId + "/competitors/" + competitorId + "/refresh", null);
    }
    public String removeCompetitor(int domainId, int competitorId) throws Exception {
        return request("DELETE", "/domains/" + domainId + "/competitors/" + competitorId, null);
    }
    public String tenant() throws Exception { return request("GET", "/tenant", null); }
    public String schedules() throws Exception { return request("GET", "/schedules", null); }
    public String knowledgeGraph(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/knowledge-graph", null); }
    public String buildKnowledgeGraph(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/knowledge-graph/build", null); }
    public String citation(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/citation", null); }
    public String deployPreview(int domainId, String artifact) throws Exception {
        String a = artifact != null ? artifact : "robots";
        return request("GET", "/domains/" + domainId + "/deploy/preview?artifact=" + a, null);
    }
    public String monitoring(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/monitoring", null); }
    public String reports(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/reports", null); }
    public String agents(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/agents", null); }
    public String registerAgent(int domainId, String name, String type) throws Exception {
        return request("POST", "/domains/" + domainId + "/agents",
            "{\"name\":\"" + name.replace("\"", "\\\"") + "\",\"type\":\"" + type.replace("\"", "\\\"") + "\"}");
    }
    public String testWebhook() throws Exception { return request("POST", "/webhooks/test", null); }
    public String graphql(String query) throws Exception {
        return request("POST", "/graphql", "{\"query\":\"" + query.replace("\"", "\\\"") + "\"}");
    }

    public String graphql(String query, String variablesJson) throws Exception {
        String vars = variablesJson != null ? variablesJson : "{}";
        return request("POST", "/graphql", "{\"query\":\"" + query.replace("\"", "\\\"") + "\",\"variables\":" + vars + "}");
    }

    public String createSchedule(String jsonBody) throws Exception { return request("POST", "/schedules", jsonBody); }
    public String updateSchedule(int id, String jsonBody) throws Exception { return request("PATCH", "/schedules/" + id, jsonBody); }
    public String deleteSchedule(int id) throws Exception { return request("DELETE", "/schedules/" + id, null); }
    public String workspaces() throws Exception { return request("GET", "/workspaces", null); }
    public String createWorkspace(String jsonBody) throws Exception { return request("POST", "/workspaces", jsonBody); }
    public String updateWorkspace(int id, String jsonBody) throws Exception { return request("PATCH", "/workspaces/" + id, jsonBody); }
    public String deleteWorkspace(int id) throws Exception { return request("DELETE", "/workspaces/" + id, null); }
    public String team() throws Exception { return request("GET", "/team", null); }
    public String inviteTeamMember(String jsonBody) throws Exception { return request("POST", "/team/invitations", jsonBody); }
    public String updateTeamRole(int userId, String role) throws Exception {
        return request("PATCH", "/team/" + userId, "{\"role\":\"" + role.replace("\"", "\\\"") + "\"}");
    }
    public String removeTeamMember(int userId) throws Exception { return request("DELETE", "/team/" + userId, null); }
    public String cancelInvitation(int invitationId) throws Exception { return request("DELETE", "/team/invitations/" + invitationId, null); }
    public String settings() throws Exception { return request("GET", "/settings", null); }
    public String updateSettings(String jsonBody) throws Exception { return request("PATCH", "/settings", jsonBody); }
    public String createApiKey(String jsonBody) throws Exception { return request("POST", "/api-keys", jsonBody); }
    public String deleteApiKey(int id) throws Exception { return request("DELETE", "/api-keys/" + id, null); }
    public String auditLogs() throws Exception { return request("GET", "/audit-logs", null); }
    public String auditLogs(String query) throws Exception {
        return request("GET", query != null && !query.isEmpty() ? "/audit-logs?" + query : "/audit-logs", null);
    }
    public String notifications() throws Exception { return request("GET", "/notifications", null); }
    public String markNotificationRead(int id) throws Exception { return request("POST", "/notifications/" + id + "/read", null); }
    public String markAllNotificationsRead() throws Exception { return request("POST", "/notifications/read-all", null); }
    public String regenerateVerification(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/verification/regenerate", null); }
    public String updateVerificationMethod(int domainId, String method) throws Exception {
        return request("PATCH", "/domains/" + domainId + "/verification-method", "{\"method\":\"" + method.replace("\"", "\\\"") + "\"}");
    }
    public String activateDomain(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/activate", null); }
    public String generateContentGapOutline(int domainId, int gapId) throws Exception {
        return request("POST", "/domains/" + domainId + "/content-gaps/" + gapId + "/outline", null);
    }
    public String generateContentGapArticle(int domainId, int gapId) throws Exception {
        return request("POST", "/domains/" + domainId + "/content-gaps/" + gapId + "/article", null);
    }
    public String dismissContentGap(int domainId, int gapId) throws Exception {
        return request("POST", "/domains/" + domainId + "/content-gaps/" + gapId + "/dismiss", null);
    }
    public String contentOptimizer(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/content-optimizer", null); }
    public String refreshContentOptimizer(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/content-optimizer/refresh", null); }
    public String simulateAiVisibility(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/ai-visibility/simulate", "{}"); }
    public String simulateAiVisibility(int domainId, String jsonBody) throws Exception {
        return request("POST", "/domains/" + domainId + "/ai-visibility/simulate", jsonBody);
    }
    public String installAgent(int domainId, String jsonBody) throws Exception { return request("POST", "/domains/" + domainId + "/agents/install", jsonBody); }
    public String generateSchema(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/schema/generate", "{}"); }
    public String generateSchema(int domainId, String jsonBody) throws Exception { return request("POST", "/domains/" + domainId + "/schema/generate", jsonBody); }
    public String deploySchema(int domainId) throws Exception { return request("POST", "/domains/" + domainId + "/schema/deploy", "{}"); }
    public String deploySchema(int domainId, String jsonBody) throws Exception { return request("POST", "/domains/" + domainId + "/schema/deploy", jsonBody); }
    public String updateRobots(int domainId, String content) throws Exception {
        return request("PUT", "/domains/" + domainId + "/robots", "{\"content\":\"" + content.replace("\"", "\\\"") + "\"}");
    }
    public String generateLlms(int domainId) throws Exception { return generateLlms(domainId, "llms"); }
    public String generateLlms(int domainId, String type) throws Exception {
        String deployType = type != null ? type : "llms";
        return request("POST", "/domains/" + domainId + "/llms-txt/generate", "{\"type\":\"" + deployType + "\"}");
    }
    public String storeSubdomain(int domainId, String jsonBody) throws Exception { return request("POST", "/domains/" + domainId + "/subdomains", jsonBody); }
    public String destroySubdomain(int domainId, int subdomainId) throws Exception {
        return request("DELETE", "/domains/" + domainId + "/subdomains/" + subdomainId, null);
    }
    public String downloadReport(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/reports/download", null); }
    public String downloadReportPdf(int domainId) throws Exception { return request("GET", "/domains/" + domainId + "/reports/download/pdf", null); }
    public String suggestCitation(int domainId, int pageId) throws Exception {
        return request("POST", "/domains/" + domainId + "/citation/" + pageId + "/suggest", "{}");
    }
    public String suggestCitation(int domainId, int pageId, String jsonBody) throws Exception {
        return request("POST", "/domains/" + domainId + "/citation/" + pageId + "/suggest", jsonBody);
    }
    public String approveAgentCommand(int domainId, int commandId) throws Exception {
        return request("POST", "/domains/" + domainId + "/agents/commands/" + commandId + "/approve", null);
    }
}

public class AgentClient {
    private final String agentToken;
    private final String baseUrl;
    private final HttpClient client;

    public AgentClient(String agentToken) {
        this(agentToken, "https://primenza.com/api/v1");
    }

    public AgentClient(String agentToken, String baseUrl) {
        this.agentToken = agentToken;
        this.baseUrl = baseUrl.replaceAll("/$", "");
        this.client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
    }

    public String request(String method, String path, String body) throws Exception {
        HttpRequest.Builder builder = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + path))
            .header("X-Agent-Token", agentToken)
            .header("Content-Type", "application/json")
            .header("Accept", "application/json")
            .timeout(Duration.ofSeconds(30));

        if ("POST".equals(method)) {
            builder.POST(body != null ? HttpRequest.BodyPublishers.ofString(body) : HttpRequest.BodyPublishers.noBody());
        } else {
            builder.GET();
        }

        HttpResponse<String> response = client.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    public String poll() throws Exception { return request("POST", "/agent/poll", null); }

    public String report(int commandId, String resultJson) throws Exception {
        return request("POST", "/agent/report", "{\"command_id\":" + commandId + ",\"result\":" + resultJson + "}");
    }
}
