/**
 * Firebase Types
 *
 * Tipos e interfaces para la integración de Firebase en valtech-components.
 * Todos los modelos de Firestore deben extender FirestoreDocument.
 */
import type { AnalyticsConfig } from './analytics-types';
/**
 * Configuración de Firebase (valores de firebaseConfig)
 */
export interface FirebaseConfig {
    apiKey: string;
    authDomain: string;
    projectId: string;
    storageBucket: string;
    messagingSenderId: string;
    appId: string;
    measurementId?: string;
    /** Habilitar Firebase Cloud Messaging (default: false) */
    enableMessaging?: boolean;
    /** VAPID key para Firebase Cloud Messaging */
    messagingVapidKey?: string;
}
/**
 * Configuración de emuladores para desarrollo local
 */
export interface EmulatorConfig {
    firestore?: {
        host: string;
        port: number;
    };
    auth?: {
        host: string;
        port: number;
    };
    storage?: {
        host: string;
        port: number;
    };
}
/**
 * Configuración por defecto de emuladores.
 * Puertos estándar usados en todos los proyectos frontend.
 *
 * @see https://firebase.google.com/docs/emulator-suite
 */
export declare const DEFAULT_EMULATOR_CONFIG: EmulatorConfig;
/**
 * Identificador de aplicación para namespacing automático en Firestore y Storage.
 * Permite aislar datos de diferentes apps dentro del mismo proyecto Firebase.
 *
 * Cada app consumidora define sus propios valores de AppId en su configuración local.
 */
export type AppId = string;
/**
 * Configuración completa de Valtech Firebase
 */
export interface ValtechFirebaseConfig {
    /** Configuración de Firebase */
    firebase: FirebaseConfig;
    /** Configuración de emuladores (opcional, para desarrollo) */
    emulator?: EmulatorConfig;
    /** Habilitar persistencia offline de Firestore (default: false) */
    persistence?: boolean;
    /** Habilitar Firebase Cloud Messaging (default: false) - requiere Service Worker */
    enableMessaging?: boolean;
    /** VAPID key para Firebase Cloud Messaging */
    messagingVapidKey?: string;
    /**
     * ID de la aplicación para namespacing automático.
     * Si se proporciona:
     * - Firestore: prefija colecciones con `apps/{appId}/`
     * - Storage: prefija paths con `{appId}/`
     * Si no se proporciona, los paths quedan sin modificar (backward compatible).
     */
    appId?: AppId;
    /**
     * Persiste mensajes FCM en localStorage para debugging.
     * Solo para desarrollo, permite ver mensajes en DevTools.
     * Default: false
     */
    debugMessagePersistence?: boolean;
    /**
     * Habilitar Firebase Analytics / GA4 (default: false).
     * Requiere measurementId en firebase config.
     */
    enableAnalytics?: boolean;
    /**
     * Configuración detallada de Analytics.
     * Solo aplica si enableAnalytics es true.
     */
    analyticsConfig?: AnalyticsConfig;
}
/**
 * Interface base para todos los documentos de Firestore.
 * Todos los modelos deben extender esta interface.
 *
 * @example
 * interface User extends FirestoreDocument {
 *   name: string;
 *   email: string;
 * }
 */
export interface FirestoreDocument {
    /** ID del documento (asignado por Firestore) */
    id?: string;
    /** Fecha de creación (manejada automáticamente) */
    createdAt?: Date;
    /** Fecha de última actualización (manejada automáticamente) */
    updatedAt?: Date;
}
/**
 * Operadores disponibles para cláusulas where
 */
export type WhereOperator = '==' | '!=' | '<' | '<=' | '>' | '>=' | 'array-contains' | 'array-contains-any' | 'in' | 'not-in';
/**
 * Cláusula where para filtrar documentos
 */
export interface WhereClause {
    /** Campo a filtrar */
    field: string;
    /** Operador de comparación */
    operator: WhereOperator;
    /** Valor a comparar */
    value: unknown;
}
/**
 * Dirección de ordenamiento
 */
export type OrderDirection = 'asc' | 'desc';
/**
 * Cláusula orderBy para ordenar resultados
 */
export interface OrderByClause {
    /** Campo por el cual ordenar */
    field: string;
    /** Dirección del ordenamiento */
    direction: OrderDirection;
}
/**
 * Opciones para queries de Firestore
 */
export interface QueryOptions {
    /** Filtros where (AND entre todos) */
    where?: WhereClause[];
    /** Ordenamiento de resultados */
    orderBy?: OrderByClause[];
    /** Límite de documentos a retornar */
    limit?: number;
    /** Cursor para paginación: empezar después de este documento */
    startAfter?: unknown;
    /** Cursor para paginación: empezar en este documento */
    startAt?: unknown;
    /** Cursor para paginación: terminar antes de este documento */
    endBefore?: unknown;
    /** Cursor para paginación: terminar en este documento */
    endAt?: unknown;
}
/**
 * Opciones adicionales para subscripciones real-time
 */
export interface SubscriptionOptions extends QueryOptions {
    /** Incluir cambios de metadata (ej: pendingWrites) */
    includeMetadataChanges?: boolean;
}
/**
 * Resultado de una query paginada
 */
export interface PaginatedResult<T> {
    /** Documentos de la página actual */
    data: T[];
    /** Indica si hay más páginas disponibles */
    hasMore: boolean;
    /** Cursor para la siguiente página (pasar a startAfter) */
    lastDoc: unknown;
    /** Total de documentos (opcional, requiere query adicional) */
    total?: number;
}
/**
 * Estado de una operación de upload
 */
export type UploadState = 'running' | 'paused' | 'success' | 'canceled' | 'error';
/**
 * Progreso de upload de archivo
 */
export interface UploadProgress {
    /** Bytes transferidos hasta ahora */
    bytesTransferred: number;
    /** Total de bytes a transferir */
    totalBytes: number;
    /** Porcentaje completado (0-100) */
    percentage: number;
    /** Estado actual del upload */
    state: UploadState;
}
/**
 * Resultado de un upload completado
 */
export interface UploadResult {
    /** URL de descarga del archivo */
    downloadUrl: string;
    /** Ruta completa en Storage */
    fullPath: string;
    /** Nombre del archivo */
    name: string;
    /** Tamaño en bytes */
    size: number;
    /** Tipo MIME del archivo */
    contentType: string;
    /** Metadata personalizada */
    metadata: Record<string, string>;
}
/**
 * Metadata para archivos en Storage
 */
export interface StorageMetadata {
    /** Tipo MIME del archivo */
    contentType?: string;
    /** Metadata personalizada (key-value) */
    customMetadata?: Record<string, string>;
    /** Control de caché HTTP */
    cacheControl?: string;
    /**
     * Skip the appId prefix for shared paths.
     * Use this for cross-app paths like user avatars: `users/{userId}/avatar.jpg`
     * @default false
     */
    skipPrefix?: boolean;
}
/**
 * Resultado de listar archivos en Storage
 */
export interface StorageListResult {
    /** Rutas de los archivos encontrados */
    items: string[];
    /** Token para la siguiente página (si hay más) */
    nextPageToken?: string;
}
/**
 * Información de membership en una organización.
 * Representa el rol y permisos que tiene un usuario en una org específica.
 */
export interface MembershipInfo {
    /** ID del rol (ej: 'admin', 'editor', 'viewer') */
    roleId: string;
    /** Nombre del rol para display */
    roleName: string;
    /** Lista de permisos en formato 'resource:action' */
    permissions: string[];
}
/**
 * Estructura completa de claims con RBAC.
 * Estos claims están disponibles en request.auth.token en Firestore Rules.
 */
export interface RBACClaims {
    /** Email del usuario */
    email: string;
    /** Nombre completo del usuario */
    name: string;
    /** Si el email está verificado */
    verified: boolean;
    /**
     * Mapa de organizaciones donde el usuario tiene roles.
     * Key = orgId, Value = información del rol y permisos en esa org.
     */
    memberships: Record<string, MembershipInfo>;
    /** ID de la organización actualmente seleccionada */
    activeOrg: string;
}
/**
 * Información de una organización para display
 */
export interface OrganizationInfo {
    /** ID único de la organización */
    id: string;
    /** Rol del usuario en esta organización */
    roleId: string;
    /** Nombre del rol para display */
    roleName: string;
    /** Permisos del usuario en esta organización */
    permissions: string[];
}
/**
 * Información del usuario de Firebase (simplificada)
 */
export interface FirebaseUser {
    /** UID único del usuario */
    uid: string;
    /** Email del usuario */
    email: string | null;
    /** Nombre para mostrar */
    displayName: string | null;
    /** URL de foto de perfil */
    photoURL: string | null;
    /** Email verificado */
    emailVerified: boolean;
    /** Usuario anónimo */
    isAnonymous: boolean;
    /** Proveedor de autenticación */
    providerId: string;
}
/**
 * Estado de la sesión de Firebase
 */
export interface SessionState {
    /** Usuario actual (null si no autenticado) */
    user: FirebaseUser | null;
    /** Indica si el usuario está autenticado */
    isAuthenticated: boolean;
    /** Indica si se está cargando el estado de auth */
    isLoading: boolean;
    /** Error de autenticación (si lo hay) */
    error: Error | null;
}
/**
 * Estado del permiso de notificaciones
 */
export type NotificationPermission = 'granted' | 'denied' | 'default';
/**
 * Payload de una notificación push
 */
export interface NotificationPayload {
    /** Título de la notificación */
    title?: string;
    /** Cuerpo del mensaje */
    body?: string;
    /** URL de imagen */
    image?: string;
    /** Datos personalizados */
    data?: Record<string, string>;
    /** ID del mensaje de FCM */
    messageId?: string;
}
/**
 * Acción de navegación desde una notificación
 */
export interface NotificationAction {
    /** Ruta interna de la app (ej: '/orders/123') */
    route?: string;
    /** URL externa (ej: 'https://example.com') */
    url?: string;
    /** Parámetros de query string */
    queryParams?: Record<string, string>;
    /** Tipo de acción personalizada */
    actionType?: string;
    /** Datos adicionales para la acción */
    actionData?: Record<string, unknown>;
}
/**
 * Resultado de `MessagingService.enable()`.
 *
 * Tipo discriminado descriptivo (NO se hace throw): la página consumidora lo
 * inspecciona para decidir qué toast/UX mostrar.
 *
 * `status`:
 * - `enabled`     — permiso otorgado + token FCM obtenido (`token` presente).
 * - `denied`      — el usuario denegó el permiso del navegador.
 * - `unsupported` — el navegador no soporta FCM (incl. iOS sin standalone).
 * - `error`       — el flujo falló por otra causa (ver `reason`).
 * - `timeout`     — el flujo se colgó >15s. Si `reloaded` es true, la página
 *                   está por recargarse (auto-reload, 1ª vez en la sesión); si
 *                   es false, ya se consumió el auto-reload y la página debe
 *                   mostrar un error sin recargar.
 */
export interface EnablePushResult {
    /** Resultado del flujo de activación de push. */
    status: 'enabled' | 'denied' | 'unsupported' | 'error' | 'timeout';
    /** Token FCM — presente solo cuando `status === 'enabled'`. */
    token?: string;
    /** Detalle legible de la causa — presente en `error` / `timeout`. */
    reason?: string;
    /**
     * Solo para `status === 'timeout'`: true si se disparó el auto-reload
     * (la página está por recargarse). False si el auto-reload ya se consumió
     * esta sesión y la app debe mostrar un error en lugar de recargar.
     */
    reloaded?: boolean;
}
/**
 * Evento de click en una notificación
 */
export interface NotificationClickEvent {
    /** Payload original de la notificación */
    notification: NotificationPayload;
    /** Acción de navegación extraída */
    action: NotificationAction;
    /** Timestamp del click */
    timestamp: Date;
}
/**
 * Códigos de error de Firebase
 */
export type FirebaseErrorCode = 'permission-denied' | 'not-found' | 'already-exists' | 'resource-exhausted' | 'cancelled' | 'unknown' | 'invalid-argument' | 'deadline-exceeded' | 'unauthenticated';
/**
 * Error de Firebase tipado
 */
export interface FirebaseError {
    /** Código del error */
    code: FirebaseErrorCode;
    /** Mensaje de error (en español) */
    message: string;
    /** Error original de Firebase */
    originalError?: unknown;
}
