import * as plugins from './plugins.js';
import { SmartdataDbCursor } from './classes.cursor.js';
import { type IManager, SmartdataCollection } from './classes.collection.js';
import { SmartdataDbWatcher } from './classes.watcher.js';
/**
 * Search options for `.search()`:
 * - filter: additional MongoDB query to AND-merge
 * - validate: post-fetch validator, return true to keep a doc
 */
export interface SearchOptions<T> {
    /**
     * Additional MongoDB filter to AND‐merge into the query
     */
    filter?: Record<string, any>;
    /**
     * Post‐fetch validator; return true to keep each doc
     */
    validate?: (doc: T) => Promise<boolean> | boolean;
    /**
     * Optional MongoDB session for transactional operations
     */
    session?: plugins.mongodb.ClientSession;
}
export type TDocCreation = 'db' | 'new' | 'mixed';
export declare function globalSvDb(): (value: undefined, context: ClassFieldDecoratorContext) => void;
/**
 * Options for custom serialization/deserialization of a field.
 */
export interface SvDbOptions {
    /** Function to serialize the field value before saving to DB */
    serialize?: (value: any) => any;
    /** Function to deserialize the field value after reading from DB */
    deserialize?: (value: any) => any;
}
/**
 * saveable - saveable decorator to be used on class properties
 */
export declare function svDb(options?: SvDbOptions): (value: undefined, context: ClassFieldDecoratorContext) => void;
/**
 * searchable - marks a property as searchable with Lucene query syntax
 */
export declare function searchable(): (value: undefined, context: ClassFieldDecoratorContext) => void;
/**
 * unique index - decorator to mark a unique index
 */
export declare function unI(): (value: undefined, context: ClassFieldDecoratorContext) => void;
/**
 * Options for MongoDB indexes
 */
export interface IIndexOptions {
    background?: boolean;
    unique?: boolean;
    sparse?: boolean;
    expireAfterSeconds?: number;
    [key: string]: any;
}
/**
 * index - decorator to mark a field for regular indexing
 */
export declare function index(options?: IIndexOptions): (value: undefined, context: ClassFieldDecoratorContext) => void;
type ElementOf<T> = T extends ReadonlyArray<infer U> ? U : T;
type InValues<T> = ReadonlyArray<ElementOf<T>>;
export type MongoFilterCondition<T> = T | {
    $eq?: T;
    $ne?: T;
    $gt?: T;
    $gte?: T;
    $lt?: T;
    $lte?: T;
    $in?: InValues<T>;
    $nin?: InValues<T>;
    $exists?: boolean;
    $type?: string | number;
    $regex?: string | RegExp;
    $options?: string;
    $all?: T extends ReadonlyArray<infer U> ? ReadonlyArray<U> : never;
    $elemMatch?: T extends ReadonlyArray<infer U> ? MongoFilter<U> : never;
    $size?: T extends ReadonlyArray<any> ? number : never;
    $not?: MongoFilterCondition<T>;
};
export type MongoFilter<T> = {
    [K in keyof T]?: T[K] extends object ? T[K] extends any[] ? MongoFilterCondition<T[K]> : MongoFilter<T[K]> | MongoFilterCondition<T[K]> : MongoFilterCondition<T[K]>;
} & {
    $and?: MongoFilter<T>[];
    $or?: MongoFilter<T>[];
    $nor?: MongoFilter<T>[];
    $not?: MongoFilter<T>;
    [key: string]: any;
};
export declare const convertFilterForMongoDb: (filterArg: {
    [key: string]: any;
}) => {
    [key: string]: any;
};
export declare class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends IManager = any> {
    /**
     * the collection object an Doc belongs to
     */
    static collection: SmartdataCollection<any>;
    collection: SmartdataCollection<any>;
    static defaultManager: any;
    static manager: any;
    manager: TManager;
    /**
     * Helper to get collection with fallback to static for Deno compatibility
     */
    private getCollectionSafe;
    static createInstanceFromMongoDbNativeDoc<T>(this: plugins.tsclass.typeFest.Class<T>, mongoDbNativeDocArg: any): T;
    /**
     * gets all instances as array
     * @param this
     * @param filterArg - Type-safe MongoDB filter with nested object support and operators
     * @returns
     */
    static getInstances<T>(this: plugins.tsclass.typeFest.Class<T>, filterArg: MongoFilter<T>, opts?: {
        session?: plugins.mongodb.ClientSession;
    }): Promise<T[]>;
    /**
     * Cursor-paged query with stable seek pagination — the org-standard way to
     * list unbounded collections. Orders by a comparable (ideally indexed)
     * sort field with a unique tiebreaker, returns one page plus the cursor
     * for the next, and never materializes the full result set.
     */
    static getPagedInstances<T>(this: plugins.tsclass.typeFest.Class<T>, optionsArg: {
        filter?: MongoFilter<T>;
        /** Comparable, ideally indexed field that orders the pages (e.g. a numeric timestamp). */
        sortField: string;
        sortDirection?: 'asc' | 'desc';
        /** Unique tiebreaker field present on every document. Defaults to 'id'. */
        uniqueField?: string;
        /** Page size, default 100, capped at 1000. */
        limit?: number;
        /** Seek position returned as nextCursor by the previous page. */
        cursor?: {
            sortValue: number | string;
            uniqueValue: string;
        };
        /** Also count all filter matches (extra query). */
        withTotal?: boolean;
        session?: plugins.mongodb.ClientSession;
    }): Promise<{
        documents: T[];
        nextCursor?: {
            sortValue: number | string;
            uniqueValue: string;
        };
        total?: number;
    }>;
    /**
     * gets the first matching instance
     * @param this
     * @param filterArg
     * @returns
     */
    static getInstance<T>(this: plugins.tsclass.typeFest.Class<T>, filterArg: MongoFilter<T>, opts?: {
        session?: plugins.mongodb.ClientSession;
    }): Promise<T>;
    /**
     * get a unique id prefixed with the class name
     */
    static getNewId<T = any>(this: plugins.tsclass.typeFest.Class<T>, lengthArg?: number): Promise<string>;
    /**
     * Get a cursor for streaming results, with optional session and native cursor modifiers.
     * @param filterArg Partial filter to apply
     * @param opts Optional session and modifier for the raw MongoDB cursor
     */
    static getCursor<T>(this: plugins.tsclass.typeFest.Class<T>, filterArg: MongoFilter<T>, opts?: {
        session?: plugins.mongodb.ClientSession;
        modifier?: (cursorArg: plugins.mongodb.FindCursor<plugins.mongodb.WithId<plugins.mongodb.BSON.Document>>) => plugins.mongodb.FindCursor<plugins.mongodb.WithId<plugins.mongodb.BSON.Document>>;
    }): Promise<SmartdataDbCursor<T>>;
    /**
     * watch the collection
     * @param this
     * @param filterArg
     * @param forEachFunction
     */
    /**
     * Watch the collection for changes, with optional buffering and change stream options.
     * @param filterArg MongoDB filter to select which changes to observe
     * @param opts optional ChangeStreamOptions plus bufferTimeMs
     */
    static watch<T>(this: plugins.tsclass.typeFest.Class<T>, filterArg: MongoFilter<T>, opts?: plugins.mongodb.ChangeStreamOptions & {
        bufferTimeMs?: number;
    }): Promise<SmartdataDbWatcher<T>>;
    /**
     * run a function for all instances
     * @returns
     */
    static forEach<T>(this: plugins.tsclass.typeFest.Class<T>, filterArg: MongoFilter<T>, forEachFunction: (itemArg: T) => Promise<any>): Promise<void>;
    /**
     * returns a count of the documents in the collection
     */
    static getCount<T>(this: plugins.tsclass.typeFest.Class<T>, filterArg?: MongoFilter<T>): Promise<number>;
    /**
     * Runs an integrity check on this collection.
     * Returns a summary with estimated vs actual counts and any duplicate unique fields.
     */
    static checkCollectionIntegrity<T>(this: plugins.tsclass.typeFest.Class<T>): Promise<{
        ok: boolean;
        estimatedCount: number;
        actualCount: number;
        duplicateFields: Array<{
            field: string;
            duplicateValues: number;
        }>;
    }>;
    /**
     * Create a MongoDB filter from a Lucene query string
     * @param luceneQuery Lucene query string
     * @returns MongoDB query object
     */
    static createSearchFilter<T>(this: plugins.tsclass.typeFest.Class<T>, luceneQuery: string): any;
    /**
     * List all searchable fields defined on this class
     */
    static getSearchableFields(): string[];
    /**
     * Execute a query with optional hard filter and post-fetch validation
     */
    private static execQuery;
    /**
     * Search documents by text or field:value syntax, with safe regex fallback
     * Supports additional filtering and post-fetch validation via opts
     * @param query A search term or field:value expression
     * @param opts Optional filter and validate hooks
     * @returns Array of matching documents
     */
    static search<T>(this: plugins.tsclass.typeFest.Class<T>, query: string, opts?: SearchOptions<T>): Promise<T[]>;
    /**
     * how the Doc in memory was created, may prove useful later.
     */
    creationStatus: TDocCreation;
    /**
     * updated from db in any case where doc comes from db
     */
    _createdAt: string;
    /**
     * will be updated everytime the doc is saved
     */
    _updatedAt: string;
    /**
     * an array of saveable properties of ALL doc
     * Note: Set by decorators on prototype - NOT declared as instance property to avoid shadowing in Deno
     * Declared with definite assignment assertion to satisfy TypeScript without creating instance property
     */
    globalSaveableProperties: string[];
    /**
     * unique indexes
     * Note: Set by decorators on prototype - NOT declared as instance property to avoid shadowing in Deno
     */
    uniqueIndexes: string[];
    /**
     * regular indexes with their options
     * Note: Set by decorators on prototype - NOT declared as instance property to avoid shadowing in Deno
     */
    regularIndexes: Array<{
        field: string;
        options: IIndexOptions;
    }>;
    /**
     * an array of saveable properties of a specific doc
     * Note: Set by decorators on prototype - NOT declared as instance property to avoid shadowing in Deno
     */
    saveableProperties: string[];
    /**
     * name
     */
    name: string;
    /**
     * primary id in the database
     */
    dbDocUniqueId: string;
    /**
     * class constructor
     */
    constructor();
    /**
     * saves this instance (optionally within a transaction)
     */
    save(opts?: {
        session?: plugins.mongodb.ClientSession;
    }): Promise<any>;
    /**
     * deletes a document from the database (optionally within a transaction)
     */
    delete(opts?: {
        session?: plugins.mongodb.ClientSession;
    }): Promise<any>;
    /**
     * also store any referenced objects to DB
     * better for data consistency
     */
    saveDeep(savedMapArg?: plugins.lik.ObjectMap<SmartDataDbDoc<any, any>>): void;
    /**
     * updates an object from db
     */
    updateFromDb(): Promise<boolean>;
    /**
     * creates a saveable object so the instance can be persisted as json in the database
     */
    createSavableObject(): Promise<TImplements>;
    /**
     * creates an identifiable object for operations that require filtering
     */
    createIdentifiableObject(): Promise<any>;
}
export {};
