// Types for @passkey-x/sdk 1.0.0. Response bodies follow https://passkey-x.com/openapi.yaml; the common
// shapes are typed here, everything else is `Json` (see the OpenAPI file for each route's fields).

export declare const SDK_VERSION: "1.0.0";
export declare const DEFAULT_BASE_URL: string;

export type Json = null | boolean | number | string | Json[] | { [key: string]: Json };
export type CredentialKind = "personal" | "personal-test" | "organization" | "agent" | "session";
export declare function credentialKind(token: string): CredentialKind | null;

/** A list page: `{ data, has_more, next_cursor }` (Organization API and newer Customer API lists). */
export interface Page<T = Json> { data: T[]; has_more?: boolean; next_cursor?: string | null; [key: string]: unknown }
/** The rows of one page: data, items (Customer API vault items) or data.rows (documents, incidents). */
export function pageRows<T = Json>(page: unknown): T[];
export type ListParams = Record<string, string | number | boolean | Date | null | undefined | Array<string | number>> & { limit?: number; cursor?: string };

export interface RequestInit {
  body?: unknown;
  query?: ListParams;
  headers?: Record<string, string>;
  /** Writes get one automatically; pass your own to make a retried call a no-op across processes. */
  idempotencyKey?: string;
  /** Revision for optimistic concurrency (If-Match). */
  ifMatch?: number | string;
  signal?: AbortSignal;
  timeoutMs?: number;
  maxRetries?: number;
  /** Return the raw Response instead of parsed JSON. */
  raw?: boolean;
}
export type WriteOptions = Pick<RequestInit, "idempotencyKey" | "signal" | "timeoutMs" | "maxRetries" | "headers">;

export interface PasskeyXOptions {
  /** pxu_ personal key, pxk_ organization key, pxa1. agent token, or a session access token. */
  apiKey?: string;
  accessToken?: string;
  /** Default https://passkey-x.com/api (self-hosted servers: your own /api). */
  baseUrl?: string;
  /** Sessions only: the project's public publishable key (sent as `apikey`). */
  publishableKey?: string;
  /** Per attempt, default 30 000. 0 turns it off. */
  timeoutMs?: number;
  /** Retries for 408/425/429/5xx and network errors, with backoff and Retry-After. Default 2. */
  maxRetries?: number;
  fetch?: typeof fetch;
  headers?: Record<string, string>;
  onRequest?: (event: { method: string; url: string; attempt: number }) => void | Promise<void>;
  onResponse?: (event: { method: string; url: string; attempt: number; status: number; requestId: string | null }) => void | Promise<void>;
}

export declare class PasskeyXError extends Error {
  readonly status: number;
  /** The API's error code, e.g. insufficient_scope, ip_not_allowed, rate_limited, validation_failed, network_error, timeout. */
  readonly code: string;
  /** Quote this to support. */
  readonly requestId: string | null;
  readonly field: string | null;
  /** Milliseconds the API asked you to wait (429). */
  readonly retryAfter: number | null;
  readonly details: Json | null;
  readonly retryable: boolean;
}

interface Listable<T = Json> {
  list(params?: ListParams): Promise<Page<T> | T[]>;
  /** Every row, following next_cursor. */
  iterate(params?: ListParams): AsyncGenerator<T, void, unknown>;
}

export interface Me { identity_id?: string; email?: string | null; scopes?: string[]; test?: boolean; [key: string]: Json | undefined }
/** A vault item as ciphertext: the SDK never handles plaintext secrets. */
export interface VaultItemEnvelope { workspace_id: string; content_type: string; schema_version: number; nonce: string; ciphertext: string; aad_hash: string; [key: string]: Json }
export interface Webhook { id: string; name: string; url: string; enabled: boolean; events: string[]; secret?: string | null; [key: string]: Json | undefined }
export interface SignatureRequest { id: string; label: string; status: string; verify_code?: string; progress?: Json; [key: string]: Json | undefined }

export declare class PasskeyX {
  constructor(options: PasskeyXOptions);
  readonly kind: CredentialKind | null;
  readonly baseUrl: string;
  /** From the last answer's X-RateLimit headers. */
  rateLimit: { limit: number; remaining: number } | null;

  request<T = Json>(method: string, path: string, init?: RequestInit): Promise<T>;
  paginate<T = Json>(fetchPage: (cursor: string | undefined) => Promise<Page<T> | T[]>): AsyncGenerator<T, void, unknown>;

  // Customer API (pxu_ key or session)
  health(): Promise<Json>;
  me(): Promise<Me>;
  itemTypes(): Promise<Json>;
  apiKeys: {
    list(): Promise<Json>;
    create(body: { name: string; scopes: string[]; expires_in_days?: number; test?: boolean; allowed_ips?: string[] }, options?: WriteOptions): Promise<Json>;
    update(keyId: string, body: { name?: string; allowed_ips?: string[] }, options?: WriteOptions): Promise<Json>;
    revoke(keyId: string, options?: WriteOptions): Promise<Json>;
    activity(keyId: string, params?: ListParams): Promise<Json>;
  };
  workspaces: { list(): Promise<Json>; members(workspaceId: string): Promise<Json> };
  vaultItems: Listable<VaultItemEnvelope> & {
    get(itemId: string): Promise<VaultItemEnvelope>;
    create(envelope: VaultItemEnvelope, options?: WriteOptions): Promise<Json>;
    update(itemId: string, revision: number, envelope: Partial<VaultItemEnvelope>, options?: WriteOptions): Promise<Json>;
    delete(itemId: string, revision: number, options?: WriteOptions): Promise<Json>;
  };
  sync: { changes(params: { workspace_id: string; cursor?: string }): Promise<Json> };
  missions: { list(params?: ListParams): Promise<Json> };
  accessRequests: { list(params?: ListParams): Promise<Json>; create(body: Json, options?: WriteOptions): Promise<Json>; decide(requestId: string, body: Json, options?: WriteOptions): Promise<Json> };
  accessGrants: { list(params?: ListParams): Promise<Json> };

  // Organization API (pxk_ key)
  org: {
    me(): Promise<Json>;
    logs: Listable; auditEvents: Listable;
    itemTimeline(itemId: string, params?: ListParams): Promise<Json>;
    alerts: Listable & { update(alertId: string, body: Json, options?: WriteOptions): Promise<Json> };
    security: { summary(): Promise<Json>; overview(): Promise<Json>; incidents: Listable; deviceTrust(): Promise<Json> };
    reports: { weekly(params?: ListParams): Promise<Json> };
    policies: { list(): Promise<Json>; set(policyType: string, body: Json, options?: WriteOptions): Promise<Json>; stop(policyType: string, options?: WriteOptions): Promise<Json> };
    storage(): Promise<Json>;
    insights(): Promise<Json>;
    company: {
      get(): Promise<Json>; devices: Listable; createDeviceCode(body?: Json, options?: WriteOptions): Promise<Json>;
      removeDevice(deviceId: string, options?: WriteOptions): Promise<Json>; cancelDeviceCode(codeId: string, options?: WriteOptions): Promise<Json>; groupReport(): Promise<Json>;
    };
    /** Controller: company computers, groups and actions (controller:read / controller:write). */
    controller: {
      get(): Promise<Json>;
      createJob(body: { kind: string; target_kind?: "agents" | "group" | "all"; computer_ids?: string[]; group_id?: string; payload?: Json; reason: string }, options?: WriteOptions): Promise<Json>;
      job(jobId: string): Promise<Json>;
    };
    /** Remote (add-on): seats, devices, sessions and invite links (remote:read / remote:write). */
    remote: {
      get(): Promise<Json>;
      endSession(sessionId: string, options?: WriteOptions): Promise<Json>;
      invites(): Promise<Json>;
      createInvite(body?: { email?: string; note?: string; access?: "view" | "control"; hours?: number }, options?: WriteOptions): Promise<Json>;
      revokeInvite(inviteId: string, options?: WriteOptions): Promise<Json>;
    };
    members: Listable & {
      invite(body: { email: string; role?: string; [key: string]: Json | undefined }, options?: WriteOptions): Promise<Json>;
      suspend(identityId: string, body?: Json, options?: WriteOptions): Promise<Json>;
      reactivate(identityId: string, body?: Json, options?: WriteOptions): Promise<Json>;
      block(identityId: string, body?: Json, options?: WriteOptions): Promise<Json>;
      unblock(identityId: string, body?: Json, options?: WriteOptions): Promise<Json>;
      remove(identityId: string, options?: WriteOptions): Promise<Json>;
      security: Listable;
    };
    invitations: Listable & { cancel(invitationId: string, options?: WriteOptions): Promise<Json> };
    onboarding: Listable & Record<"remind" | "extend" | "resume" | "cancel", (planId: string, body?: Json, options?: WriteOptions) => Promise<Json>>;
    handovers: Listable & { preview(params?: ListParams): Promise<Json>; create(body: Json, options?: WriteOptions): Promise<Json> };
    workspaces: Listable; groups: Listable;
    accessRequests: Listable & Record<"approve" | "deny", (requestId: string, body?: Json, options?: WriteOptions) => Promise<Json>>;
    externalShares: Listable & Record<"approve" | "deny", (linkId: string, body?: Json, options?: WriteOptions) => Promise<Json>>;
    documents: Listable & {
      get(documentId: string): Promise<Json>;
      verify(body: { verify_code?: string; sha256?: string }, options?: WriteOptions): Promise<Json>;
      cancel(documentId: string, body?: { reason?: string }, options?: WriteOptions): Promise<Json>;
    };
    signatureRequests: Listable<SignatureRequest>;
    webhooks: Listable<Webhook> & {
      events(): Promise<Json>;
      get(webhookId: string): Promise<Webhook>;
      create(body: { name: string; url: string; events?: string[] }, options?: WriteOptions): Promise<Webhook>;
      update(webhookId: string, body: { name?: string; enabled?: boolean; events?: string[] }, options?: WriteOptions): Promise<Webhook>;
      delete(webhookId: string, options?: WriteOptions): Promise<Json>;
      rotateSecret(webhookId: string, body?: Json, options?: WriteOptions): Promise<Webhook>;
      test(webhookId: string, body?: Json, options?: WriteOptions): Promise<Json>;
      deliveries(webhookId: string, params?: ListParams): Promise<Json>;
      replay(webhookId: string, body?: { since?: string; until?: string }, options?: WriteOptions): Promise<Json>;
    };
  };

  // Agent API (pxa1. token)
  agent: { vaults(params?: ListParams): Promise<Json> };
}

export { verifyWebhook, parseWebhook, WebhookVerificationError } from "./webhooks.mjs";
export default PasskeyX;
