import { Collection, Document } from 'mongodb';
import { QueryOperator, QueryValue, SortDirection, PaginatedResult, ModelConstructor } from '../types/index.js';
import { BaseModel } from '../base_model/base_model.js';
import type { LoadRelationConstraint, EmbedRelationConstraint } from '../types/relationship_inference.js';
import type { MongoTransactionClient } from '../transaction_client.js';
/**
 * SEAMLESS TYPE-SAFE MODEL QUERY BUILDER - Like AdonisJS Lucid!
 *
 * This enhanced query builder provides automatic type inference for relationships
 * and seamless type safety without requiring any type assertions or extra steps.
 *
 * Key Features:
 * - Automatic relationship name inference from model definitions
 * - Type-safe load callbacks with proper IntelliSense
 * - Compile-time error checking for invalid relationship names
 * - Method chaining like AdonisJS Lucid
 * - Bulk loading to prevent N+1 query problems
 */
export declare class ModelQueryBuilder<T extends Document = Document, TModel extends BaseModel = BaseModel> {
    private collection;
    private modelConstructor;
    private whereBuilder;
    private queryExecutor;
    private queryUtils;
    private loadRelations;
    private embedRelations;
    constructor(collection: Collection<T>, modelConstructor: ModelConstructor, transactionClient?: MongoTransactionClient);
    /**
     * Associate this query builder with a transaction
     */
    useTransaction(trx: MongoTransactionClient): this;
    /**
     * Add a where condition
     */
    where(field: string, value: QueryValue): this;
    where(field: string, operator: QueryOperator, value: QueryValue): this;
    /**
     * Alias for where method
     */
    andWhere(field: string, value: QueryValue): this;
    andWhere(field: string, operator: QueryOperator, value: QueryValue): this;
    /**
     * Add a where not condition
     */
    whereNot(field: string, value: QueryValue): this;
    whereNot(field: string, operator: QueryOperator, value: QueryValue): this;
    /**
     * Alias for whereNot method
     */
    andWhereNot(field: string, operatorOrValue: QueryOperator | QueryValue, value?: QueryValue): this;
    /**
     * Add an OR where condition
     */
    orWhere(field: string, operatorOrValue: QueryOperator | QueryValue, value?: QueryValue): this;
    /**
     * Add an OR where not condition
     */
    orWhereNot(field: string, operatorOrValue: QueryOperator | QueryValue, value?: QueryValue): this;
    /**
     * Add a where like condition (case-sensitive)
     */
    whereLike(field: string, value: string): this;
    /**
     * Add a where ilike condition (case-insensitive)
     */
    whereILike(field: string, value: string): this;
    /**
     * Add a where null condition
     */
    whereNull(field: string): this;
    /**
     * Add an OR where null condition
     */
    orWhereNull(field: string): this;
    /**
     * Add a where not null condition
     */
    whereNotNull(field: string): this;
    /**
     * Add an OR where not null condition
     */
    orWhereNotNull(field: string): this;
    /**
     * Add a where exists condition
     */
    whereExists(field: string): this;
    /**
     * Add an OR where exists condition
     */
    orWhereExists(field: string): this;
    /**
     * Add a where not exists condition
     */
    whereNotExists(field: string): this;
    /**
     * Add an OR where not exists condition
     */
    orWhereNotExists(field: string): this;
    /**
     * Add a where in condition
     */
    whereIn(field: string, values: QueryValue[]): this;
    /**
     * Add an OR where in condition
     */
    orWhereIn(field: string, values: QueryValue[]): this;
    /**
     * Add a where not in condition
     */
    whereNotIn(field: string, values: QueryValue[]): this;
    /**
     * Add an OR where not in condition
     */
    orWhereNotIn(field: string, values: QueryValue[]): this;
    /**
     * Add a where between condition
     */
    whereBetween(field: string, range: [QueryValue, QueryValue]): this;
    /**
     * Add an OR where between condition
     */
    orWhereBetween(field: string, range: [QueryValue, QueryValue]): this;
    /**
     * Add a where not between condition
     */
    whereNotBetween(field: string, range: [QueryValue, QueryValue]): this;
    /**
     * Add an OR where not between condition
     */
    orWhereNotBetween(field: string, range: [QueryValue, QueryValue]): this;
    /**
     * Add distinct clause
     */
    distinct(field: string): this;
    /**
     * Add group by clause
     */
    groupBy(...fields: string[]): this;
    /**
     * Add having clause (for aggregation)
     */
    having(field: string, operatorOrValue: QueryOperator | QueryValue, value?: QueryValue): this;
    /**
     * Add order by clause
     */
    orderBy(field: string, direction?: SortDirection): this;
    /**
     * Set limit
     */
    limit(count: number): this;
    /**
     * Set skip/offset
     */
    skip(count: number): this;
    /**
     * Alias for skip method
     */
    offset(count: number): this;
    /**
     * Set pagination using page and perPage
     */
    forPage(page: number, perPage: number): this;
    /**
     * Select specific fields
     */
    select(fields: string[] | Record<string, 0 | 1>): this;
    /**
     * TYPE-SAFE LOAD METHOD - Eager Load Referenced Relationships!
     *
     * This method provides automatic type inference for REFERENCED relationship loading.
     * The callback parameter is automatically typed based on the relationship being loaded.
     * Only supports REFERENCED relationships (HasOne, HasMany, BelongsTo).
     * Embedded relationships are excluded because they need to be "embedded" instead.
     *
     * Example usage:
     * ```typescript
     * const users = await User.query().load('profile', (profileQuery) => {
     *   profileQuery.where('isActive', true).orderBy('createdAt', 'desc')
     * })
     * ```
     *
     * @param relation - The REFERENCED relationship property name (with IntelliSense support)
     * @param callback - Optional callback to modify the relationship query
     */
    load<K extends LoadRelationConstraint<TModel>>(relation: K, callback?: (query: ModelQueryBuilder<any, BaseModel>) => void): this;
    /**
     * TYPE-SAFE EMBED METHOD - Query Embedded Documents Directly!
     *
     * This method provides automatic type inference for EMBEDDED document querying.
     * The callback parameter is automatically typed based on the embedded relationship being queried.
     * Only supports EMBEDDED relationships (EmbeddedSingle, EmbeddedMany).
     * Referenced relationships are excluded because they need to be "loaded" instead.
     *
     * Example usage:
     * ```typescript
     * const users = await UserWithEnhancedEmbeddedProfile.query().embed('profiles', (profileQuery) => {
     *   profileQuery.where('age', '>', 25).orderBy('age', 'desc').limit(5)
     * })
     * ```
     *
     * @param relation - The EMBEDDED relationship property name (with IntelliSense support)
     * @param callback - Optional callback to filter/paginate the embedded documents
     */
    embed<K extends EmbedRelationConstraint<TModel>>(relation: K, callback?: (query: import('../embedded/embedded_query_builder.js').EmbeddedQueryBuilder<any>) => void): this;
    /**
     * Execute query and return first result
     */
    first(): Promise<TModel | null>;
    /**
     * Execute query and return first result or throw exception
     */
    firstOrFail(): Promise<TModel>;
    /**
     * Execute query and return all results
     */
    all(): Promise<TModel[]>;
    /**
     * Execute query and return all results (alias for all)
     */
    fetch(): Promise<TModel[]>;
    /**
     * Execute query and return paginated results
     */
    paginate(page: number, perPage: number): Promise<PaginatedResult<TModel>>;
    /**
     * Count documents matching the query
     */
    count(): Promise<number>;
    /**
     * Get array of IDs for matching documents
     */
    ids(): Promise<any[]>;
    /**
     * Update documents matching the query
     */
    update(updateData: Record<string, any>): Promise<number>;
    /**
     * Delete documents matching the query
     */
    delete(): Promise<number>;
    /**
     * Clone the query builder
     */
    clone(): ModelQueryBuilder<T, TModel>;
}
//# sourceMappingURL=model_query_builder.d.ts.map