import { Firestore, FieldValue } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { FirestoreDocument, PaginatedResult, QueryOptions } from './types';
import * as i0 from "@angular/core";
/**
 * Internal sentinel used to mark a collection path as global cross-app —
 * i.e. it should NOT be prefixed with `apps/{appId}/`.
 *
 * Apps consume this via `CollectionOptions.skipAppPrefix`; the sentinel
 * stays in `TypedCollection` and is stripped here before Firestore sees it.
 *
 * Format keeps it impossible to collide with a real Firestore path (`:` is
 * not allowed in collection segments).
 *
 * @internal
 */
export declare const ABS_PATH_SENTINEL = "__abs__:";
/**
 * Servicio para operaciones CRUD en Firestore.
 *
 * @example
 * ```typescript
 * interface User extends FirestoreDocument {
 *   name: string;
 *   email: string;
 *   role: 'admin' | 'user';
 * }
 *
 * @Component({...})
 * export class UsersComponent {
 *   private firestore = inject(FirestoreService);
 *
 *   // Lectura one-time
 *   async loadUser(id: string) {
 *     const user = await this.firestore.getDoc<User>('users', id);
 *   }
 *
 *   // Subscripción real-time
 *   users$ = this.firestore.collectionChanges<User>('users', {
 *     where: [{ field: 'role', operator: '==', value: 'admin' }],
 *     orderBy: [{ field: 'name', direction: 'asc' }]
 *   });
 *
 *   // Crear documento
 *   async createUser(data: Omit<User, 'id'>) {
 *     const user = await this.firestore.addDoc<User>('users', data);
 *   }
 * }
 * ```
 */
export declare class FirestoreService {
    private firestore;
    private config;
    constructor(firestore: Firestore);
    /**
     * Prefija el path de colección con el appId si está configurado.
     * Si no hay appId, retorna el path sin modificar (backward compatible).
     *
     * Si el path empieza con `ABS_PATH_SENTINEL` (`__abs__:`), se asume que el
     * caller quiere un path global cross-app (ej. `users/{uid}/notifications` —
     * el inbox global de notificaciones). El sentinel se strippea y el resto
     * del path se pasa verbatim, sin prefijo `apps/{appId}/`.
     *
     * @internal
     */
    private prefixCollectionPath;
    /**
     * Obtiene un documento por ID (lectura única).
     *
     * @param collectionPath - Ruta de la colección
     * @param docId - ID del documento
     * @returns Documento o null si no existe
     *
     * @example
     * ```typescript
     * const user = await firestoreService.getDoc<User>('users', 'abc123');
     * if (user) {
     *   console.log(user.name);
     * }
     * ```
     */
    getDoc<T extends FirestoreDocument>(collectionPath: string, docId: string): Promise<T | null>;
    /**
     * Obtiene múltiples documentos con opciones de query.
     *
     * @param collectionPath - Ruta de la colección
     * @param options - Opciones de query (where, orderBy, limit)
     * @returns Array de documentos
     *
     * @example
     * ```typescript
     * // Todos los usuarios activos ordenados por nombre
     * const users = await firestoreService.getDocs<User>('users', {
     *   where: [{ field: 'active', operator: '==', value: true }],
     *   orderBy: [{ field: 'name', direction: 'asc' }],
     *   limit: 50
     * });
     * ```
     */
    getDocs<T extends FirestoreDocument>(collectionPath: string, options?: QueryOptions): Promise<T[]>;
    /**
     * Cuenta documentos usando aggregation query del servidor.
     * No descarga los documentos — mucho más eficiente para conteos y badges.
     */
    countDocs(collectionPath: string, options?: QueryOptions): Promise<number>;
    /**
     * Obtiene documentos con paginación basada en cursores.
     *
     * @param collectionPath - Ruta de la colección
     * @param options - Opciones de query (debe incluir limit)
     * @returns Resultado paginado con cursor para la siguiente página
     *
     * @example
     * ```typescript
     * // Primera página
     * const page1 = await firestoreService.getPaginated<User>('users', {
     *   orderBy: [{ field: 'createdAt', direction: 'desc' }],
     *   limit: 10
     * });
     *
     * // Siguiente página
     * if (page1.hasMore) {
     *   const page2 = await firestoreService.getPaginated<User>('users', {
     *     orderBy: [{ field: 'createdAt', direction: 'desc' }],
     *     limit: 10,
     *     startAfter: page1.lastDoc
     *   });
     * }
     * ```
     */
    getPaginated<T extends FirestoreDocument>(collectionPath: string, options: QueryOptions & {
        limit: number;
    }): Promise<PaginatedResult<T>>;
    /**
     * Verifica si un documento existe.
     *
     * @param collectionPath - Ruta de la colección
     * @param docId - ID del documento
     * @returns true si el documento existe
     */
    exists(collectionPath: string, docId: string): Promise<boolean>;
    /**
     * Suscribe a cambios de un documento (real-time).
     *
     * @param collectionPath - Ruta de la colección
     * @param docId - ID del documento
     * @returns Observable que emite cuando el documento cambia
     *
     * @example
     * ```typescript
     * // En el componente
     * user$ = this.firestoreService.docChanges<User>('users', this.userId);
     *
     * // En el template
     * @if (user$ | async; as user) {
     *   <p>{{ user.name }}</p>
     * }
     * ```
     */
    docChanges<T extends FirestoreDocument>(collectionPath: string, docId: string): Observable<T | null>;
    /**
     * Suscribe a cambios de una colección (real-time).
     *
     * @param collectionPath - Ruta de la colección
     * @param options - Opciones de query
     * @returns Observable que emite cuando la colección cambia
     *
     * @example
     * ```typescript
     * // Usuarios activos en tiempo real
     * activeUsers$ = this.firestoreService.collectionChanges<User>('users', {
     *   where: [{ field: 'status', operator: '==', value: 'online' }]
     * });
     * ```
     */
    collectionChanges<T extends FirestoreDocument>(collectionPath: string, options?: QueryOptions): Observable<T[]>;
    /**
     * Agrega un documento con ID auto-generado.
     *
     * @param collectionPath - Ruta de la colección
     * @param data - Datos del documento (sin id, createdAt, updatedAt)
     * @returns Documento creado con su ID
     *
     * @example
     * ```typescript
     * const newUser = await firestoreService.addDoc<User>('users', {
     *   name: 'John Doe',
     *   email: 'john@example.com',
     *   role: 'user'
     * });
     * console.log('Created user with ID:', newUser.id);
     * ```
     */
    addDoc<T extends FirestoreDocument>(collectionPath: string, data: Omit<T, 'id' | 'createdAt' | 'updatedAt'>): Promise<T>;
    /**
     * Crea o sobrescribe un documento con ID específico.
     *
     * @param collectionPath - Ruta de la colección
     * @param docId - ID del documento
     * @param data - Datos del documento
     * @param options - Opciones (merge: true para merge en lugar de sobrescribir)
     *
     * @example
     * ```typescript
     * // Sobrescribir completamente
     * await firestoreService.setDoc<User>('users', 'user123', userData);
     *
     * // Merge con datos existentes
     * await firestoreService.setDoc<User>('users', 'user123', { name: 'New Name' }, { merge: true });
     * ```
     */
    setDoc<T extends FirestoreDocument>(collectionPath: string, docId: string, data: Omit<T, 'id'>, options?: {
        merge?: boolean;
    }): Promise<void>;
    /**
     * Actualiza campos específicos de un documento.
     *
     * @param collectionPath - Ruta de la colección
     * @param docId - ID del documento
     * @param data - Campos a actualizar
     *
     * @example
     * ```typescript
     * await firestoreService.updateDoc<User>('users', 'user123', {
     *   name: 'Updated Name',
     *   lastLogin: new Date()
     * });
     * ```
     */
    updateDoc<T extends FirestoreDocument>(collectionPath: string, docId: string, data: Partial<Omit<T, 'id' | 'createdAt'>>): Promise<void>;
    /**
     * Elimina un documento.
     *
     * @param collectionPath - Ruta de la colección
     * @param docId - ID del documento
     *
     * @example
     * ```typescript
     * await firestoreService.deleteDoc('users', 'user123');
     * ```
     */
    deleteDoc(collectionPath: string, docId: string): Promise<void>;
    /**
     * Ejecuta múltiples operaciones de escritura de forma atómica.
     *
     * @param operations - Función que recibe el batch y agrega operaciones
     *
     * @example
     * ```typescript
     * await firestoreService.batch((batch) => {
     *   batch.set('users/user1', { name: 'User 1' });
     *   batch.update('users/user2', { status: 'inactive' });
     *   batch.delete('users/user3');
     * });
     * ```
     */
    batch(operations: (batch: {
        set: <T>(path: string, data: T) => void;
        update: <T>(path: string, data: Partial<T>) => void;
        delete: (path: string) => void;
    }) => void): Promise<void>;
    /**
     * Construye una ruta a partir de un template.
     *
     * @param template - Template con placeholders {param}
     * @param params - Valores para los placeholders
     * @returns Ruta construida
     *
     * @example
     * ```typescript
     * const path = firestoreService.buildPath('users/{userId}/documents/{docId}', {
     *   userId: 'user123',
     *   docId: 'doc456'
     * });
     * // => 'users/user123/documents/doc456'
     * ```
     */
    buildPath(template: string, params: Record<string, string>): string;
    /**
     * Genera un ID único para un documento (sin crearlo).
     *
     * @param collectionPath - Ruta de la colección
     * @returns ID único generado por Firestore
     */
    generateId(collectionPath: string): string;
    /**
     * Retorna un valor de timestamp del servidor.
     * Usar en campos de fecha para que Firestore asigne el timestamp.
     */
    serverTimestamp(): FieldValue;
    /**
     * Retorna un valor para agregar elementos a un array.
     *
     * @example
     * ```typescript
     * await firestoreService.updateDoc('users', 'user123', {
     *   tags: firestoreService.arrayUnion('new-tag')
     * });
     * ```
     */
    arrayUnion(...elements: unknown[]): FieldValue;
    /**
     * Retorna un valor para remover elementos de un array.
     */
    arrayRemove(...elements: unknown[]): FieldValue;
    /**
     * Retorna un valor para incrementar un campo numérico.
     *
     * @example
     * ```typescript
     * await firestoreService.updateDoc('users', 'user123', {
     *   loginCount: firestoreService.increment(1)
     * });
     * ```
     */
    increment(n: number): FieldValue;
    /**
     * Construye los QueryConstraints a partir de QueryOptions
     */
    private buildQueryConstraints;
    /**
     * Mapea un DocumentSnapshot a nuestro tipo
     */
    private mapDocument;
    /**
     * Convierte Timestamps de Firestore a Date de JavaScript
     */
    private convertTimestamps;
    /**
     * Divide una ruta de documento en colección e ID
     */
    private splitPath;
    static ɵfac: i0.ɵɵFactoryDeclaration<FirestoreService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<FirestoreService>;
}
