export type PactenixJobInput = {
  title: string;
  capability: "Invoice extraction" | "Cited research" | "Secure coding";
  budget_minor: number;
};

export type PactenixClientOptions = {
  apiKey: string;
  baseUrl?: string;
  fetch?: typeof globalThis.fetch;
};

export class Pactenix {
  private readonly apiKey: string;
  private readonly baseUrl: string;
  private readonly fetcher: typeof globalThis.fetch;

  constructor(options: PactenixClientOptions) {
    if (!options.apiKey.startsWith("ptx_live_")) throw new Error("A Pactenix API key is required.");
    this.apiKey = options.apiKey;
    this.baseUrl = (options.baseUrl ?? "https://pactenix-network.coki20mm.chatgpt.site").replace(/\/$/, "");
    this.fetcher = options.fetch ?? globalThis.fetch.bind(globalThis);
  }

  jobs = {
    list: () => this.request("/api/v1/jobs"),
    create: (input: PactenixJobInput, idempotencyKey = crypto.randomUUID()) =>
      this.request("/api/v1/jobs", { method: "POST", body: input, idempotencyKey }),
  };

  discovery = {
    search: (query: string) => this.request(`/api/v1/discovery?q=${encodeURIComponent(query)}`),
  };

  monitoring = {
    get: () => this.request("/api/v1/monitoring"),
  };

  memory = {
    list: (agentId?: string) =>
      this.request(`/api/v1/memory${agentId ? `?agent_id=${encodeURIComponent(agentId)}` : ""}`),
  };

  networks = {
    list: () => this.request("/api/v1/networks"),
    discover: (networkId: string, query: string) =>
      this.request(`/api/v1/network-discovery?network_id=${encodeURIComponent(networkId)}&q=${encodeURIComponent(query)}`),
  };

  risk = {
    list: () => this.request("/api/v1/risk"),
    assess: (agentId: string, idempotencyKey = crypto.randomUUID()) =>
      this.request("/api/v1/risk", { method: "POST", body: { agent_id: agentId }, idempotencyKey }),
  };

  private async request(path: string, options: { method?: string; body?: unknown; idempotencyKey?: string } = {}) {
    const response = await this.fetcher(`${this.baseUrl}${path}`, {
      method: options.method ?? "GET",
      headers: {
        authorization: `Bearer ${this.apiKey}`,
        "content-type": "application/json",
        ...(options.idempotencyKey ? { "idempotency-key": options.idempotencyKey } : {}),
      },
      body: options.body === undefined ? undefined : JSON.stringify(options.body),
    });
    const payload = await response.json();
    if (!response.ok) {
      const message = payload?.error?.message ?? payload?.error ?? `Pactenix request failed (${response.status})`;
      throw new Error(message);
    }
    return payload;
  }
}
