// Core option types and data shapes

export type OKDBPrimaryKey = string | number;
export type OKDBIndexKey = Array<string | number | null | Buffer>;
export type OKDBFilter = Record<string, unknown>;

// ── Constructor options ───────────────────────────────────────────────────────

export interface OKDBOptions {
    maxDbs?: number;
    pageSize?: number;
    compression?: boolean;
    encryptionKey?: string | Buffer;
    mapSize?: number;
    durability?: 'strict' | 'balanced' | 'fast' | 'custom';
    allowUnsafe?: boolean;
    lmdb?: Record<string, unknown>;
    auth?: OKDBAuthOptions;
    sync?: OKDBSyncOptions;
    queue?: OKDBQueueOptions;
    bus?: boolean | Record<string, unknown>;
    functions?: Record<string, unknown>;
    timeMachine?: OKDBTimeMachineOptions;
    runtimeDeclarations?: boolean;
    log?: { retainDays?: number };
    shutdownTimeout?: number;
    /** Lifecycle role flags — gate which background work this instance runs.
     *  Defaults preserve full-role behavior; passive instances serve reads/writes
     *  but skip engines / async processors / compaction scheduling. */
    engines?: boolean;
    asyncProcessors?: boolean;
    compaction?: 'active' | 'passive';
    http?: boolean;
    /** Which registered envs open() eagerly opens: 'all' (default), 'core'
     *  (~system/~log/default only), or an array of names (core + listed —
     *  an unknown listed name makes open() throw). Use openEnv(name) to open
     *  more on demand. */
    envs?: 'all' | 'core' | string[];
}

export interface OKDBAuthOptions {
    open?: boolean | string | string[];
    session?: { secure?: boolean; sameSite?: 'Lax' | 'Strict' | 'None' };
    token?: { secret?: string; ttl?: number };
    oauth?: OKDBOAuthConfig;
    providers?: Record<string, OKDBOAuthProviderConfig>;
}

export interface OKDBOAuthConfig {
    providerLabel?: string;
    issuer?: string;
    clientId?: string;
    scopes?: string[];
    [key: string]: unknown;
}

export interface OKDBOAuthProviderConfig {
    issuer: string;
    clientId: string;
    scopes?: string[];
    [key: string]: unknown;
}

export interface OKDBSyncOptions {
    address?: string;
    delta_limit?: number;
    reconcile_concurrency?: number;
    auto_reconcile?: boolean;
    gcPeerStalenessLimitDays?: number;
    gcIntervalMs?: number;
    [key: string]: unknown;
}

export interface OKDBQueueOptions {
    default_ttl?: number;
    claim_batch_limit?: number;
    reconcile_batch_limit?: number;
    default_bucket_tokens?: number;
    default_max_tries?: number | null;
    default_retry_delay?: number;
    default_backoff_multiplier?: number;
    cron_next?: ((cronExpr: string, fromTimestamp: number) => number) | null;
    done_ttl?: number | null;
    failed_ttl?: number | null;
    [key: string]: unknown;
}

export interface OKDBTimeMachineOptions {
    [key: string]: unknown;
}

export interface OKDBEnvironmentConfig {
    sync?: boolean;
    durability?: 'strict' | 'balanced' | 'fast' | 'custom';
    lmdb?: Record<string, unknown>;
    compression?: boolean;
    encryptionKey?: string | Buffer;
    parentEnv?: string;
    [key: string]: unknown;
}

// ── Query and range options ───────────────────────────────────────────────────

export interface OKDBRangeOptions {
    start?: OKDBPrimaryKey;
    end?: OKDBPrimaryKey;
    limit?: number;
    reverse?: boolean;
    offset?: number;
    snapshot?: boolean;
}

export interface OKDBQueryOptions {
    index?: string[];
    prefix?: OKDBIndexKey;
    start?: OKDBIndexKey;
    end?: OKDBIndexKey;
    startIndex?: OKDBIndexKey;
    limit?: number;
    reverse?: boolean;
    offset?: number;
}

export interface OKDBGeoQueryOptions {
    lat: number;
    lon: number;
    radius?: number;
    limit?: number;
    reverse?: boolean;
}

export interface OKDBFtsQueryOptions {
    limit?: number;
    offset?: number;
    [key: string]: unknown;
}

export interface OKDBWriteOptions {
    ifVersion?: number;
    timestamp?: number;
    ttl?: number;
}

// ── Result shapes ─────────────────────────────────────────────────────────────

export interface OKDBEntry<T = unknown> {
    key: OKDBPrimaryKey;
    value: T;
    version: number;
}

export interface OKDBIndexEntry<T = unknown> extends OKDBEntry<T> {
    indexKey: OKDBIndexKey;
}

export interface OKDBChangeEntry {
    clock: number;
    origin: string;
    type: string;
    key: OKDBPrimaryKey;
    action: string;
    version?: number;
    timestamp: number;
    newValue?: unknown;
    oldValue?: unknown;
    txnId?: string;
}

export interface OKDBIndexDefinition {
    fields: string[];
    type?: 'geo';
    precision?: number;
    unique?: boolean;
}

export interface OKDBTypeSchema {
    definition: Record<string, unknown>;
    enforce?: boolean;
}

export interface OKDBCompactResult {
    ok: boolean;
    sizeBefore: number;
    sizeAfter: number;
    saved: number;
    savedPct: number;
}

export interface OKDBRemoveEnvironmentResult {
    ok: boolean;
    name: string;
    filesRemoved: string[];
    filesLocked: string[];
    keptSubEnvs?: string[];
}

export interface OKDBTtlListOptions {
    limit?: number;
    reverse?: boolean;
}

export interface OKDBInfoResult {
    id: string;
    pageSize: number;
    lastPageNumber: number;
    mapSize: number;
    clock: number;
    plugins: string[];
    versions: { okdb: string; lmdb: string | null; lmdbNative: string };
    version: string;
    ttl: unknown;
    types: Record<string, unknown>;
    config: unknown;
}
