import { WhereFilterOp } from 'firebase/firestore';
import { firestore } from 'firebase-admin';

type QueryOrderBy<T> = {
  field: keyof T | "modified";
  direction: "asc" | "desc";
};

type QueryWhere<T> = {
  field: keyof T | "modified";
  operation: WhereFilterOp;
  value: T[keyof T] | T[keyof T][];
};

type QueryOptions<T> = {
  perPage?: number;
  cursor?: string | number | null;
  orderBy: QueryOrderBy<T>;
  wheres?: QueryWhere<T>[];
};

type QueryResponse<T> = {
  data: T[];
  count: number;
  cursor?: string | number | null;
  perPage?: number;
};

interface Cache$1 {
  set<T>(key: string, obj: T, ttl?: number): Promise<void>;
  get<T>(key: string): Promise<T | null>;
  del(key: string): Promise<void>;
  delPattern(pattern: string): Promise<void>;
  getByPattern<T>(pattern: string): Promise<T[]>;
}

interface Database$1 {
  Save<T>(
    collection: string,
    data: Maybe<{ string: id } & T>
  ): Promise<T & { id: string }>;
  Update<T>(collection: string, id: string, data: Partial<T>): Promise<T>;
  FindOne<T>(collection: string, id: string): Promise<T | null>;
  Delete<T>(collection: string, where: QueryWhere<T>): Promise<boolean>;
  QueryData<T>(
    collection: string,
    query: QueryOptions<T>,
    noCache?: boolean
  ): Promise<QueryResponse<T>>;
  SaveBatch<T>(
    collection: string,
    items: (T & { id: string })[]
  ): Promise<void>;
}

declare class Redis implements Cache$1 {
    private logError;
    del(key: string): Promise<void>;
    get<T>(key: string): Promise<T | null>;
    set<T>(key: string, obj: T, ttl?: number): Promise<void>;
    delPattern(pattern: string): Promise<void>;
    getByPattern<T>(pattern: string): Promise<T[]>;
}

declare class Firestore implements Database$1 {
    private _db;
    private _cache;
    constructor(firestore: firestore.Firestore);
    SaveBatch<T>(collectionName: string, data: (T & {
        id?: string;
    })[]): Promise<void>;
    Save<T>(collectionName: string, data: {
        id?: string;
    } & T): Promise<T & {
        id: string;
    }>;
    FindOne<T>(collectionName: string, id: string): Promise<T | null>;
    QueryData<T>(collectionName: string, query: QueryOptions<T>, noCache?: boolean): Promise<QueryResponse<T>>;
    Delete<T>(collectionName: string, query: QueryWhere<T>): Promise<boolean>;
    Update<T>(collectionName: string, id: string, data: Partial<T>): Promise<T>;
    private __getCacheKey;
}

type Database = Database$1;
type Cache = Cache$1;
declare namespace Query {
    type Where<T> = QueryWhere<T>;
    type Response<T> = QueryResponse<T>;
    type Options<T> = QueryOptions<T>;
    type OrderBy<T> = QueryOrderBy<T>;
}

export { type Cache, type Database, Firestore, Query, Redis };
