import { Observable } from 'rxjs';
import { FirestoreService } from './firestore.service';
import { FirestoreDocument, PaginatedResult, QueryOptions } from './types';
import * as i0 from "@angular/core";
/**
 * Opciones de configuración para una colección.
 */
export interface CollectionOptions {
    /**
     * Si true, usa soft delete (marca deletedAt en lugar de eliminar).
     * Default: false
     */
    softDelete?: boolean;
    /**
     * Si true, maneja automáticamente createdAt/updatedAt.
     * Default: true
     */
    timestamps?: boolean;
    /**
     * Si true, el path se trata como global y NO se prefija con `apps/{appId}/`.
     *
     * Usar para colecciones cross-app a nivel user/global, p.ej.
     * `users/{uid}/notifications` (inbox global), `profiles/{uid}` o `public/...`.
     *
     * Las reglas de Firestore deben permitir el path absoluto correspondiente.
     *
     * Default: false (path prefijado a `apps/{appId}/...`).
     */
    skipAppPrefix?: boolean;
}
/**
 * Referencia a una sub-colección tipada.
 */
export interface SubCollectionRef<T extends FirestoreDocument> {
    getById(id: string): Promise<T | null>;
    getAll(options?: QueryOptions): Promise<T[]>;
    watch(id: string): Observable<T | null>;
    watchAll(options?: QueryOptions): Observable<T[]>;
    create(data: Omit<T, 'id' | 'createdAt' | 'updatedAt'>): Promise<T>;
    update(id: string, data: Partial<T>): Promise<void>;
    delete(id: string): Promise<void>;
}
/**
 * Factory para crear instancias de colección tipadas.
 *
 * @example
 * ```typescript
 * @Injectable({ providedIn: 'root' })
 * export class UsersService {
 *   private users = inject(FirestoreCollectionFactory).create<User>('users');
 *
 *   getAll = () => this.users.getAll();
 *   getById = (id: string) => this.users.getById(id);
 *   create = (data: Omit<User, 'id'>) => this.users.create(data);
 *
 *   // Métodos personalizados
 *   async getActiveUsers(): Promise<User[]> {
 *     return this.users.query({
 *       where: [{ field: 'active', operator: '==', value: true }]
 *     });
 *   }
 * }
 * ```
 */
export declare class FirestoreCollectionFactory {
    private firestore;
    constructor(firestore: FirestoreService);
    /**
     * Crea una instancia de colección tipada.
     *
     * @param collectionPath - Ruta de la colección en Firestore
     * @param options - Opciones de configuración
     * @returns Instancia de TypedCollection
     */
    create<T extends FirestoreDocument>(collectionPath: string, options?: CollectionOptions): TypedCollection<T>;
    static ɵfac: i0.ɵɵFactoryDeclaration<FirestoreCollectionFactory, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<FirestoreCollectionFactory>;
}
/**
 * Colección tipada con métodos CRUD.
 *
 * NO usa inject() - recibe FirestoreService por constructor.
 * Esto evita el error NG0203.
 */
export declare class TypedCollection<T extends FirestoreDocument> {
    private firestore;
    private readonly options;
    private readonly collectionPath;
    constructor(firestore: FirestoreService, collectionPath: string, options?: CollectionOptions);
    /**
     * Obtiene un documento por ID.
     */
    getById(id: string): Promise<T | null>;
    /**
     * Obtiene todos los documentos de la colección.
     */
    getAll(options?: QueryOptions): Promise<T[]>;
    /**
     * Ejecuta una query personalizada.
     */
    query(options: QueryOptions): Promise<T[]>;
    /**
     * Obtiene documentos con paginación.
     */
    paginate(options: QueryOptions & {
        limit: number;
    }): Promise<PaginatedResult<T>>;
    /**
     * Obtiene el primer documento que coincida con la query.
     */
    getFirst(options?: QueryOptions): Promise<T | null>;
    /**
     * Cuenta los documentos que coinciden con la query (server-side aggregation).
     * No descarga documentos — usa getCountFromServer() de Firestore.
     */
    count(options?: QueryOptions): Promise<number>;
    /**
     * Obtiene todos los documentos (one-time fetch sin listener).
     * A diferencia de watchAll(), no mantiene subscripciones activas.
     */
    getAllOnce(options?: QueryOptions): Promise<T[]>;
    /**
     * Verifica si un documento existe.
     */
    exists(id: string): Promise<boolean>;
    /**
     * Suscribe a cambios de un documento.
     */
    watch(id: string): Observable<T | null>;
    /**
     * Suscribe a cambios de la colección.
     */
    watchAll(options?: QueryOptions): Observable<T[]>;
    /**
     * Suscribe a una query personalizada.
     */
    watchQuery(options: QueryOptions): Observable<T[]>;
    /**
     * Crea un nuevo documento con ID auto-generado.
     */
    create(data: Omit<T, 'id' | 'createdAt' | 'updatedAt'>): Promise<T>;
    /**
     * Crea un documento con ID específico.
     */
    createWithId(id: string, data: Omit<T, 'id'>): Promise<void>;
    /**
     * Actualiza campos de un documento.
     */
    update(id: string, data: Partial<Omit<T, 'id' | 'createdAt'>>): Promise<void>;
    /**
     * Elimina un documento.
     * Si softDelete está habilitado, marca como eliminado en lugar de borrar.
     */
    delete(id: string): Promise<void>;
    /**
     * Actualiza múltiples documentos en una sola operación atómica.
     */
    batchUpdate(ids: string[], data: Partial<Omit<T, 'id' | 'createdAt'>>): Promise<void>;
    /**
     * Elimina múltiples documentos en una sola operación atómica.
     */
    batchDelete(ids: string[]): Promise<void>;
    /**
     * Restaura un documento soft-deleted.
     */
    restore(id: string): Promise<void>;
    /**
     * Obtiene una referencia a una sub-colección.
     *
     * @example
     * ```typescript
     * // En UsersService
     * getUserDocuments(userId: string) {
     *   return this.users.subcollection<Document>(userId, 'documents');
     * }
     *
     * // Uso
     * const docs = await users.getUserDocuments('user123').getAll();
     * ```
     */
    subcollection<S extends FirestoreDocument>(parentId: string, subcollectionName: string): SubCollectionRef<S>;
    /**
     * Aplica filtros por defecto a las queries.
     */
    private applyDefaultFilters;
    /**
     * Genera un nuevo ID sin crear el documento.
     */
    generateId(): string;
    /**
     * Obtiene la ruta de la colección.
     */
    getPath(): string;
}
/**
 * @deprecated Use FirestoreCollectionFactory.create() instead.
 * Type alias for backwards compatibility.
 */
export type FirestoreCollection<T extends FirestoreDocument> = TypedCollection<T>;
