import { MongoClient, Document, ObjectId } from "mongodb";
declare global {
    var _mongoClient: MongoClient | undefined;
}
interface ReadAllOptions {
    /**
     * Optional sort object, e.g. { createdAt: 1 } for ascending or { createdAt: -1 } for descending
     */
    sort?: Document;
    limit?: number;
    skip?: number;
}
/**
 * Class representing a MongoDB client for a specific collection.
 */
declare class ClientDB {
    /**
     * Returns the native MongoDB Db instance from the global connection.
     * Useful for libraries that require a direct Db object (e.g. Better-Auth).
     */
    static getNativeDb(): Promise<import("mongodb").Db>;
    /**
     * Returns the native MongoDB Db instance for this instance's connection.
     */
    getNativeDb(): Promise<import("mongodb").Db>;
    /**
     * Returns the native MongoDB Db instance synchronously.
     * The driver will handle connection queuing in the background.
     */
    static getNativeDbSync(): import("mongodb").Db;
    private client;
    private collectionName;
    private collection;
    /**
     * Creates an instance of ClientDB.
     * @param {string} collectionName - The name of the collection to interact with.
     */
    constructor(collectionName: string);
    /**
     * Connects to the MongoDB database and initializes the collection.
     * @returns {Promise<void>}
     */
    connect(): Promise<void>;
    /**
     * Helper to convert _id string to ObjectId if needed
     * @param {Document} query - The query object to preprocess
     * @returns {Document} The processed query with _id converted if applicable
     */
    private preprocessQuery;
    /**
     * Reads a document from the collection based on the provided query.
     * @param {Document} query - The query to find the document.
     * @returns {Promise<Document|null>} The found document or null if not found.
     */
    read(query: Document): Promise<Document | null>;
    /**
     * Reads all documents from the collection with optional sorting.
     * @param {ReadAllOptions} [options] - Optional options object.
     * @param {Document} [options.sort] - Optional sort object, e.g. { createdAt: 1 } for ascending.
     * @returns {Promise<Document[]>} An array of all documents, optionally sorted.
     */
    readAll(options?: ReadAllOptions): Promise<Document[]>;
    /**
     * Inserts a new document into the collection.
     * @param {Document} data - The data to insert.
     * @returns {Promise<Document>} The result of the insert operation.
     */
    insert(data: Document): Promise<Document>;
    /**
     * Inserts multiple documents into the collection.
     * @param {Document[]} data - The data to insert.
     * @returns {Promise<Document>} The result of the insert operation.
     */
    insertMany(data: Document[]): Promise<Document>;
    /**
     * Updates a document in the collection based on the provided query.
     * @param {Document} query - The query to find the document to update.
     * @param {Document} data - The data to update.
     * @returns {Promise<Document>} The result of the update operation.
     */
    update(query: Document, data: Document): Promise<Document>;
    /**
     * Updates multiple documents in the collection.
     * - If you pass Mongo operators ($set, $inc, etc), it will use them directly.
     * - If you pass a plain object, it will wrap it inside $set.
     *
     * @param {Document} query - The filter to match documents.
     * @param {Document} data - The update data (plain object or with operators).
     * @returns {Promise<Document>} The result of the update operation.
     */
    updateMany(query: Document, data: Document | Document[], options?: {
        upsert?: boolean;
    }): Promise<Document>;
    /**
     * Deletes a document from the collection based on the provided query.
     * @param {Document} query - The query to find the document to delete.
     * @returns {Promise<Document>} The result of the delete operation.
     */
    delete(query: Document): Promise<Document>;
    /**
     * Deletes multiple documents from the collection based on the provided query.
     * @param {Document} query - The query to find the documents to delete.
     * @returns {Promise<Document>} The result of the delete operation.
     */
    deleteMany(query: Document): Promise<Document>;
    /**
     * Finds multiple documents in the collection based on the provided query.
     * @param {Document} query - The query to find the documents.
     * @returns {Promise<Document[]>} An array of found documents.
     */
    find(query: Document, options?: ReadAllOptions, project?: Document): Promise<Document[]>;
    /**
     * Reads multiple documents from the collection based on a query.
     * @param {Document} query - The filter query.
     * @returns {Promise<Document[]>} Array of matching documents.
     */
    readMany(query: Document): Promise<Document[]>;
    /**
     * Gets random documents from the collection.
     * @param {number} [total=1] - The number of random documents to retrieve.
     * @returns {Promise<Document[]>} An array of random documents.
     */
    getRandomData(total?: number): Promise<Document[]>;
    /**
     * Run an aggregation pipeline on the current collection.
     *
     * @param {Array<Document>} pipeline - An array of MongoDB aggregation stages.
     *   Example:
     *   [
     *     { $unwind: "$tags" },
     *     { $group: { _id: "$tags", count: { $sum: 1 } } },
     *     { $sort: { count: -1 } },
     *     { $limit: 10 }
     *   ]
     *
     * @returns {Promise<Document[]>} Resolves with the array of aggregation results.
     *
     * @throws {Error} If the aggregation query fails.
     */
    aggregate(pipeline?: Document[]): Promise<Document[]>;
    /**
     * Gets the storage statistics for the collection.
     * @returns {Promise<{storageSize: number, size: number, count: number}>} The storage statistics including storageSize.
     */
    getStorageStats(): Promise<{
        storageSize: number;
        size: number;
        count: number;
    }>;
    /**
     * Gets cluster-wide storage statistics.
     */
    static getClusterStats(): Promise<{
        totalDataSize: number;
        totalStorageSize: number;
        totalIndexSize: number;
        databases: any[];
    }>;
    /**
     * Closes the MongoDB connection.
     * @returns {Promise<void>}
     */
    close(): Promise<void>;
    /**
     * Finds documents in the current collection and dynamically joins related collections
     * using MongoDB's `$lookup` aggregation stage.
     *
     * This is useful when you want to "populate" data from other collections
     * (similar to Mongoose's populate) but in a flexible, dynamic way.
     *
     * ### Example:
     * ```ts
     * const tasks = await tasksDb.findWithRelations(
     *   { column: "todo" }, // filter
     *   [
     *     {
     *       from: "kanban_tags",
     *       localField: "tags",
     *       foreignField: "value",
     *       as: "tags"
     *     },
     *     {
     *       from: "kanban_persons",
     *       localField: "persons",
     *       foreignField: "_id",
     *       as: "persons",
     *       isObjectId: true // convert string IDs to ObjectId
     *     }
     *   ],
     *   {
     *     title: 1,
     *     description: 1,
     *     "tags.label": 1,
     *     "persons.name": 1
     *   },
     *   {
     *     sort: { createdAt: -1 },
     *     limit: 10,
     *     skip: 20
     *   }
     * );
     * ```
     *
     * @param {Document} [filter={}] - MongoDB query filter. Defaults to `{}` (fetch all).
     * @param {Object[]} [relations=[]] - Array of relation configurations for `$lookup`.
     * @param {string} relations[].from - Target collection name to join with.
     * @param {string} relations[].localField - Field in this collection that holds the reference.
     * @param {string} relations[].foreignField - Field in the target collection to match against.
     * @param {string} relations[].as - The alias name for the joined data in the output.
     * @param {boolean} [relations[].isObjectId] - If `true`, will map string IDs in `localField` into ObjectId before lookup.
     * @param {Document} [project={}] - Optional MongoDB projection object to limit fields in the final output.
     * @param {ReadAllOptions} [options={}] - Optional settings like sort, skip, and limit.
     *
     * @returns {Promise<Document[]>} A promise that resolves to an array of documents with joined relations applied.
     */
    findWithRelations(filter?: Document, relations?: {
        from: string;
        localField: string;
        foreignField: string;
        as: string;
        isObjectId?: boolean;
        isSingle?: boolean;
    }[], project?: Document, options?: ReadAllOptions): Promise<Document[]>;
    /**
     * Finds a single document in the current collection and dynamically joins related collections
     * using MongoDB's `$lookup` aggregation stage.
     *
     * Mirip dengan `findWithRelations`, tapi hanya return satu dokumen (bukan array).
     *
     * ### Example:
     * ```ts
     * const task = await tasksDb.findOneWithRelations(
     *   { _id: "66cfa89f3c9c7d776b5f4f10" },
     *   [
     *     {
     *       from: "kanban_tags",
     *       localField: "tags",
     *       foreignField: "value",
     *       as: "tags"
     *     },
     *     {
     *       from: "kanban_persons",
     *       localField: "persons",
     *       foreignField: "_id",
     *       as: "persons",
     *       isObjectId: true
     *     }
     *   ]
     * );
     * ```
     *
     * @param {Document} filter - MongoDB query filter. Biasanya pakai `_id`.
     * @param {Object[]} [relations=[]] - Array of relation configs sama seperti `findWithRelations`.
     * @param {Document} [project={}] - Projection untuk limit field output.
     *
     * @returns {Promise<Document | null>} A single document with joined relations, or `null`.
     */
    findOneWithRelations(filter: Document, relations?: {
        from: string;
        localField: string;
        foreignField: string;
        as: string;
        isObjectId?: boolean;
        isSingle?: boolean;
    }[], project?: Document): Promise<Document | null>;
    /**
     * Counts the number of documents matching the query.
     * Alias for countDocuments.
     * @param {Document} [query={}] - Optional filter query.
     * @returns {Promise<number>} The count of matching documents.
     */
    count(query?: Document): Promise<number>;
    /**
     * Counts the number of documents matching the query.
     * @param {Document} [query={}] - Optional filter query.
     * @returns {Promise<number>} The count of matching documents.
     */
    countDocuments(query?: Document): Promise<number>;
    /**
     * One-time migration: convert string date fields to Date objects.
     *
     * @param fields - Which fields to convert (default: createdAt, updatedAt, startAt, endAt)
     * @returns number of documents updated
     */
    migrateDateFields(fields?: string[]): Promise<number>;
    /**
     * INTERNAL: Connect to external cluster
     */
    private static _connectExternal;
    /**
     * INCREMENTAL BACKUP (NO DELETE):
     * - Hanya ambil dokumen yang updatedAt > lastBackupAt
     * - Tidak pernah hapus dokumen di backup
     * - Upsert-only
     */
    static incrementalBackupOneDatabase(params: {
        targetUri: string;
        sourceDb: string;
        targetDb: string;
    }): Promise<{
        mode: string;
        sourceDb: string;
        targetDb: string;
        lastBackupAt: Date;
        executedAt: Date;
        report: any[];
    }>;
    /**
     * MULTI-DATABASE INCREMENTAL (NO DELETE)
     */
    static incrementalBackupManyDatabases(targetUri: string, dbList: string[]): Promise<{
        mode: string;
        targetUri: string;
        results: any[];
    }>;
    /**
     * DELTA BACKUP (NO DELETE):
     * - hanya dokumen baru (yang belum ada _id nya di backup)
     * - tidak pernah hapus
     */
    static deltaBackupOneDatabase(params: {
        targetUri: string;
        sourceDb: string;
        targetDb: string;
    }): Promise<{
        mode: string;
        sourceDb: string;
        targetDb: string;
        report: any[];
    }>;
    /**
     * MULTI-DATABASE DELTA (NO DELETE)
     */
    static deltaBackupManyDatabases(targetUri: string, dbList: string[]): Promise<{
        mode: string;
        targetUri: string;
        results: any[];
    }>;
    static fullSyncOneDatabase(params: {
        sourceUri: string;
        targetUri: string;
        dbName: string;
    }): Promise<{
        mode: string;
        sourceDb: string;
        snapshotDb: string;
        inserted: number;
        updated: number;
        deleted: number;
        report: any[];
    }>;
    static fullSyncManyDatabases(params: {
        targetURI: string;
        dbs: string[];
        keepWeeks?: number;
    }): Promise<{
        mode: string;
        syncedDatabases: string[];
        results: PromiseSettledResult<{
            mode: string;
            sourceDb: string;
            snapshotDb: string;
            inserted: number;
            updated: number;
            deleted: number;
            report: any[];
        }>[];
    }>;
    static cleanupSnapshots(params: {
        targetURI: string;
        dbs: string[];
        keepWeeks?: number;
    }): Promise<void>;
}
export default ClientDB;
export { ObjectId };
