import { Collection } from '../collection.cjs';
import { Comparator, ComparatorValue, Condition, Limit, LiteralValue, Offset, OrderBy, Query, Select, WhereCallback } from './schema.js';
import { Context, Flatten, InferResultTypeFromSelectTuple, Input, InputReference, PropertyReference, PropertyReferenceString, RemoveIndexSignature, Schema } from './types.js';
type CollectionRef = {
    [K: string]: Collection<any>;
};
export declare class BaseQueryBuilder<TContext extends Context<Schema>> {
    private readonly query;
    /**
     * Create a new QueryBuilder instance.
     */
    constructor(query?: Partial<Query<TContext>>);
    from<TCollectionRef extends CollectionRef>(collectionRef: TCollectionRef): QueryBuilder<{
        baseSchema: Flatten<TContext[`baseSchema`] & {
            [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
        }>;
        schema: Flatten<{
            [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
        }>;
        default: keyof TCollectionRef & string;
    }>;
    from<T extends InputReference<{
        baseSchema: TContext[`baseSchema`];
        schema: TContext[`baseSchema`];
    }>>(collection: T): QueryBuilder<{
        baseSchema: TContext[`baseSchema`];
        schema: {
            [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
        };
        default: T;
    }>;
    from<T extends InputReference<{
        baseSchema: TContext[`baseSchema`];
        schema: TContext[`baseSchema`];
    }>, TAs extends string>(collection: T, as: TAs): QueryBuilder<{
        baseSchema: TContext[`baseSchema`];
        schema: {
            [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
        };
        default: TAs;
    }>;
    private fromCollectionRef;
    private fromInputReference;
    /**
     * Specify what columns to select.
     * Overwrites any previous select clause.
     * Also supports callback functions that receive the row context and return selected data.
     *
     * @param selects The columns to select (can include callbacks)
     * @returns A new QueryBuilder with the select clause set
     */
    select<TSelects extends Array<Select<TContext>>>(this: QueryBuilder<TContext>, ...selects: TSelects): QueryBuilder<Flatten<Omit<TContext, `result`> & {
        result: InferResultTypeFromSelectTuple<TContext, TSelects>;
    }>>;
    /**
     * Add a where clause comparing two values.
     */
    where<T extends Comparator>(left: PropertyReferenceString<TContext> | LiteralValue, operator: T, right: ComparatorValue<T, TContext>): QueryBuilder<TContext>;
    /**
     * Add a where clause with a complete condition object.
     */
    where(condition: Condition<TContext>): QueryBuilder<TContext>;
    /**
     * Add a where clause with a callback function.
     */
    where(callback: WhereCallback<TContext>): QueryBuilder<TContext>;
    /**
     * Add a having clause comparing two values.
     * For filtering results after they have been grouped.
     */
    having(left: PropertyReferenceString<TContext> | LiteralValue, operator: Comparator, right: PropertyReferenceString<TContext> | LiteralValue): QueryBuilder<TContext>;
    /**
     * Add a having clause with a complete condition object.
     * For filtering results after they have been grouped.
     */
    having(condition: Condition<TContext>): QueryBuilder<TContext>;
    /**
     * Add a having clause with a callback function.
     * For filtering results after they have been grouped.
     */
    having(callback: WhereCallback<TContext>): QueryBuilder<TContext>;
    /**
     * Add a join clause to the query using a CollectionRef.
     */
    join<TCollectionRef extends CollectionRef>(joinClause: {
        type: `inner` | `left` | `right` | `full` | `cross`;
        from: TCollectionRef;
        on: Condition<Flatten<{
            baseSchema: TContext[`baseSchema`];
            schema: TContext[`schema`] & {
                [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
            };
        }>>;
        where?: Condition<Flatten<{
            baseSchema: TContext[`baseSchema`];
            schema: {
                [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
            };
        }>>;
    }): QueryBuilder<Flatten<Omit<TContext, `schema`> & {
        schema: TContext[`schema`] & {
            [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
        };
        hasJoin: true;
    }>>;
    /**
     * Add a join clause to the query without specifying an alias.
     * The collection name will be used as the default alias.
     */
    join<T extends InputReference<{
        baseSchema: TContext[`baseSchema`];
        schema: TContext[`baseSchema`];
    }>>(joinClause: {
        type: `inner` | `left` | `right` | `full` | `cross`;
        from: T;
        on: Condition<Flatten<{
            baseSchema: TContext[`baseSchema`];
            schema: TContext[`schema`] & {
                [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
            };
        }>>;
        where?: Condition<Flatten<{
            baseSchema: TContext[`baseSchema`];
            schema: {
                [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
            };
        }>>;
    }): QueryBuilder<Flatten<Omit<TContext, `schema`> & {
        schema: TContext[`schema`] & {
            [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
        };
        hasJoin: true;
    }>>;
    /**
     * Add a join clause to the query with a specified alias.
     */
    join<TFrom extends InputReference<{
        baseSchema: TContext[`baseSchema`];
        schema: TContext[`baseSchema`];
    }>, TAs extends string>(joinClause: {
        type: `inner` | `left` | `right` | `full` | `cross`;
        from: TFrom;
        as: TAs;
        on: Condition<Flatten<{
            baseSchema: TContext[`baseSchema`];
            schema: TContext[`schema`] & {
                [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>;
            };
        }>>;
        where?: Condition<Flatten<{
            baseSchema: TContext[`baseSchema`];
            schema: {
                [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>;
            };
        }>>;
    }): QueryBuilder<Flatten<Omit<TContext, `schema`> & {
        schema: TContext[`schema`] & {
            [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>;
        };
        hasJoin: true;
    }>>;
    private joinCollectionRef;
    private joinInputReference;
    /**
     * Add an orderBy clause to sort the results.
     * Overwrites any previous orderBy clause.
     *
     * @param orderBy The order specification
     * @returns A new QueryBuilder with the orderBy clause set
     */
    orderBy(orderBy: OrderBy<TContext>): QueryBuilder<TContext>;
    /**
     * Set a limit on the number of results returned.
     *
     * @param limit Maximum number of results to return
     * @returns A new QueryBuilder with the limit set
     */
    limit(limit: Limit<TContext>): QueryBuilder<TContext>;
    /**
     * Set an offset to skip a number of results.
     *
     * @param offset Number of results to skip
     * @returns A new QueryBuilder with the offset set
     */
    offset(offset: Offset<TContext>): QueryBuilder<TContext>;
    /**
     * Add a groupBy clause to group the results by one or more columns.
     *
     * @param groupBy The column(s) to group by
     * @returns A new QueryBuilder with the groupBy clause set
     */
    groupBy(groupBy: PropertyReference<TContext> | Array<PropertyReference<TContext>>): QueryBuilder<TContext>;
    /**
     * Define a Common Table Expression (CTE) that can be referenced in the main query.
     * This allows referencing the CTE by name in subsequent from/join clauses.
     *
     * @param name The name of the CTE
     * @param queryBuilderCallback A function that builds the CTE query
     * @returns A new QueryBuilder with the CTE added
     */
    with<TName extends string, TResult = Record<string, unknown>>(name: TName, queryBuilderCallback: (builder: InitialQueryBuilder<{
        baseSchema: TContext[`baseSchema`];
        schema: {};
    }>) => QueryBuilder<any>): InitialQueryBuilder<{
        baseSchema: TContext[`baseSchema`] & {
            [K in TName]: TResult;
        };
        schema: TContext[`schema`];
    }>;
    get _query(): Query<TContext>;
}
export type InitialQueryBuilder<TContext extends Context<Schema>> = Pick<BaseQueryBuilder<TContext>, `from` | `with`>;
export type QueryBuilder<TContext extends Context<Schema>> = Omit<BaseQueryBuilder<TContext>, `from`>;
/**
 * Create a new query builder with the given schema
 */
export declare function queryBuilder<TBaseSchema extends Schema = {}>(): InitialQueryBuilder<{
    baseSchema: TBaseSchema;
    schema: {};
}>;
export type ResultsFromContext<TContext extends Context<Schema>> = Flatten<TContext[`result`] extends object ? TContext[`result`] : TContext[`hasJoin`] extends true ? TContext[`schema`] : TContext[`default`] extends keyof TContext[`schema`] ? TContext[`schema`][TContext[`default`]] : never>;
export type ResultFromQueryBuilder<TQueryBuilder> = Flatten<TQueryBuilder extends QueryBuilder<infer C> ? C extends {
    result: infer R;
} ? R : never : never>;
export {};
