import { PipelineStage, AggregateOptions, Types, Model, Schema } from 'mongoose';

declare enum ElementType {
    ID = "id",
    STRING = "string"
}
type FilterElement = string;
interface Selectors {
    [key: string]: string | number;
}
type SearchElement = string;
declare enum SortOrderDirection {
    ASC = "asc",
    DESC = "desc"
}
type SortOrder = {
    direction: SortOrderDirection;
    id: string | null;
};
interface PaginationOptions {
    page?: number;
    limit?: number;
    sortOrder?: SortOrder;
    customFilters?: FacetPipelineStage[];
    filter?: {
        selectors: Selectors;
        filterBy: FilterElement[];
    };
    search?: {
        searchText: string;
        searchBy: SearchElement[];
    };
    /**
     * @deprecated will be removed later
     */
    lookups?: PipelineStage.Lookup[];
    extraStages?: FacetPipelineStage[];
    project?: PipelineStage.Project['$project'];
    aggregateOptions?: AggregateOptions;
}
interface PaginationResult<T> {
    total: number;
    page: number;
    limit?: number;
    records: T[];
}
type FacetPipelineStage = Exclude<PipelineStage, PipelineStage.CollStats | PipelineStage.Facet | PipelineStage.GeoNear | PipelineStage.IndexStats | PipelineStage.Out | PipelineStage.Merge | PipelineStage.PlanCacheStats>;
type FilterObject = {
    [key: string]: string | number | Types.ObjectId;
};
type SearchObject = {
    [key: string]: string | number | Types.ObjectId | {
        $regex: string;
        $options: string;
    };
};
type PaginateQuery = PipelineStage.Match['$match'];
interface PaginateModel<T> extends Model<T> {
    paginate(query: PaginateQuery, options: PaginationOptions): Promise<PaginationResult<T>>;
}

declare const paginatePlugin: <T>(schema: Schema<T>) => void;

declare const filterTransform: (filterBy: FilterElement[], selectors: Selectors) => object[];
declare const searchTransform: (searchBy: SearchElement[], searchText: string) => object[];
declare const isEmptyObject: (obj: object) => boolean;

export { ElementType, type FacetPipelineStage, type FilterElement, type FilterObject, type PaginateModel, type PaginateQuery, type PaginationOptions, type PaginationResult, type SearchElement, type SearchObject, type Selectors, type SortOrder, SortOrderDirection, filterTransform, isEmptyObject, paginatePlugin, searchTransform };
