import type { PredicateFunction } from './database.js';
export interface QueryOperators<TValue = any> {
    $eq?: TValue;
    $ne?: TValue;
    $gt?: TValue;
    $gte?: TValue;
    $lt?: TValue;
    $lte?: TValue;
    $in?: TValue[];
    $nin?: TValue[];
    $startsWith?: string;
    $endsWith?: string;
    $contains?: TValue extends Array<infer TItem> ? TItem : TValue extends string ? string : any;
    $regex?: RegExp | string;
}
export type FieldCondition<TValue = any> = TValue | QueryOperators<TValue>;
export type MatchObject<T> = {
    [K in keyof T]?: FieldCondition<T[K]>;
} & Record<string, FieldCondition<any>>;
export type SortDirection = 'asc' | 'desc';
export interface SortOption<T = Record<string, any>> {
    field: Extract<keyof T, string>;
    direction: SortDirection;
}
export interface PaginationOption {
    page: number;
    pageSize: number;
}
export interface PaginationResult<T> {
    data: T[];
    pagination: {
        currentPage: number;
        pageSize: number;
        totalItems: number;
        totalPages: number;
        hasPrevious: boolean;
        hasNext: boolean;
    };
}
export type AggregationType = 'count' | 'sum' | 'avg' | 'min' | 'max' | 'group';
export interface AggregationOption {
    type: AggregationType;
    field?: string;
    groupBy?: string;
}
export interface AggregationResult {
    type: AggregationType;
    value: number | Record<string, number> | Record<string, any[]>;
    field?: string;
    groupBy?: string;
}
export interface QueryOptions<T = any> {
    where?: PredicateFunction<T> | MatchObject<T>;
    sort?: SortOption<T> | SortOption<T>[];
    pagination?: PaginationOption;
    aggregation?: AggregationOption[];
    select?: readonly string[];
    limit?: number;
    skip?: number;
}
export type QueryOptionsWithSelect<T = any, K extends Extract<keyof T, string> = Extract<keyof T, string>> = Omit<QueryOptions<T>, 'select'> & {
    select: readonly K[];
};
export type QueryResultForOptions<T, TOptions> = TOptions extends {
    select: readonly (infer TSelected)[];
} ? TSelected extends Extract<keyof T, string> ? QueryResult<Pick<T, TSelected>> : QueryResult<Partial<T>> : QueryResult<T>;
export interface QueryResult<T = any> {
    data: T[];
    pagination?: PaginationResult<T>['pagination'];
    aggregations?: AggregationResult[];
    stats: {
        totalRecords: number;
        filteredRecords: number;
        executionTime: number;
        usedIndex: boolean;
    };
}
