#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===============================================================================
 Archivo:        email_notifications.py
 Autor:          EsteBandurria
 Fecha creación: 2026-02-03
 Versión:        1.0.0
===============================================================================
 Descripción:
    Módulo de utilidades para la gestión de listas de correos de emergencia 
    en MongoDB. Contiene lógica para lectura y escritura atómica (bulk write)
    de arrays de emails basados en identificadores compuestos (Región-Área-Centro).

===============================================================================
 Copyright:
    © 2026 ITG Chile. Todos los derechos reservados.
    Este archivo es parte del proyecto ITG Service Manager y se distribuye bajo
    los términos de la licencia Privada/Corporativa.

===============================================================================
 Interface Change List:
    Versión     Fecha        Autor                Descripción del cambio
    ---------   ----------   ------------------   ---------------------------
    v1.0.0      2026-02-03   EsteBandurria        Implementación inicial lógica Mongo
    
===============================================================================
"""

# =============================================================================
# Importación de librerias
# =============================================================================
# === Importes estandar ===
import logging
from typing import List, Dict

# === Importes de terceros ===
from pymongo import UpdateOne
from pymongo.collection import Collection
from pymongo.errors import PyMongoError, BulkWriteError

# === Importes internos ===
# (No aplica para este módulo utility independiente)

# =============================================================================
# Constantes y configuraciones globales
# =============================================================================
DEFAULT_CONFIG = {
    "debug": False,
    "log_level": "INFO"
}

# Configuración básica de logging para este módulo
logger = logging.getLogger(__name__)

# Definiciones de operaciones permitidas
OP_ADD = "add"       # Agrega sin duplicados ($addToSet)
OP_REMOVE = "remove" # Quita elementos específicos ($pull)
OP_SET = "set"       # REEMPLAZA la lista completa ($set) - Ideal para Edición tipo Snapshot
# =============================================================================
# Definiciones locales
# =============================================================================

# =============================================================================
# Clases
# =============================================================================

# =============================================================================
# Funciones Públicas
# =============================================================================
def fetch_emails_by_location(db_collection: Collection, region: str, area: str, centro: str) -> List[str]:
    """Busca los emails asociados a un centro."""
    try:
        search_id = _generate_composite_id(region, area, centro)
        doc = db_collection.find_one({"_id": search_id}, {"emails": 1, "_id": 0})
        return doc.get("emails", []) if doc else []
    except PyMongoError as e:
        tb_lineno = e.__traceback__.tb_lineno if e.__traceback__ else "Unknown"
        logger.error(f'Error {e} en linea {tb_lineno}')
        raise RuntimeError(f"Database Read Error: {str(e)}")

def update_emails(db_collection: Collection, region: str, area: str, centro: str, emails: List[str], operation: str = OP_SET) -> Dict:
    """
    Actualiza la lista de emails.
    operation='set': Reemplaza la lista actual por la nueva (Snapshot).
    operation='add': Agrega elementos.
    operation='remove': Elimina elementos.
    """
    try:
        doc_id = _generate_composite_id(region, area, centro)
        
        # Lógica de operación
        if operation == OP_ADD:
            update_query = {"$addToSet": {"emails": {"$each": emails}}}
            do_upsert = True
        elif operation == OP_REMOVE:
            update_query = {"$pull": {"emails": {"$in": emails}}}
            do_upsert = False
        elif operation == OP_SET:
            # Reemplazo total. Si la lista viene vacía, guarda array vacío.
            update_query = {"$set": {"emails": emails}}
            do_upsert = True # Crea el documento si es la primera vez que se configuran emails
        else:
            raise ValueError(f"Operación inválida '{operation}'. Use '{OP_SET}', '{OP_ADD}' o '{OP_REMOVE}'.")

        requests = [UpdateOne({"_id": doc_id}, update_query, upsert=do_upsert)]
        
        result = db_collection.bulk_write(requests, ordered=True)
        
        return {
            "matched": result.matched_count,
            "modified": result.modified_count,
            "upserted": result.upserted_count
        }

    except BulkWriteError as bwe:
        tb_lineno = bwe.__traceback__.tb_lineno if bwe.__traceback__ else "Unknown"
        logger.error(f'Error BulkWrite {bwe} en linea {tb_lineno}')
        raise RuntimeError(f"Bulk Write Error: {bwe.details}")
    except PyMongoError as e:
        tb_lineno = e.__traceback__.tb_lineno if e.__traceback__ else "Unknown"
        logger.error(f'Error {e} en linea {tb_lineno}')
        raise RuntimeError(f"Database Write Error: {str(e)}")

def delete_contact_list(db_collection: Collection, region: str, area: str, centro: str) -> bool:
    """
    Elimina físicamente el documento de emails asociado al centro.
    Usar cuando se elimina el centro del sistema.
    """
    try:
        doc_id = _generate_composite_id(region, area, centro)
        result = db_collection.delete_one({"_id": doc_id})
        return result.deleted_count > 0
    except PyMongoError as e:
        logger.error(f"Error eliminando lista de contactos: {e}")
        # No levantamos error crítico para no detener la eliminación del centro principal, solo logueamos.
        return False

# =============================================================================
# Funciones Privadas
# =============================================================================
def _generate_composite_id(region: str, area: str, centro: str) -> str:
    """
    Descripción:
        Función auxiliar privada para generar y normalizar el ID compuesto.
        Aplica formato Title Case y elimina espacios extra.
        Formato: Region-Area-Centro (ej. "Norte-Operaciones-Bodega1")
        
        Verbo estándar: generate (Generación)
    
    Parámetros:
        region (str): Input región.
        area (str): Input área.
        centro (str): Input centro.

    Retorna:
        str: ID compuesto normalizado.
    """
    return f"{region.strip().title()}-{area.strip().title()}-{centro.strip().title()}"


# =============================================================================
# Ejecución como script
# =============================================================================
if __name__ == "__main__":
    """
    Punto de entrada principal del script para pruebas manuales o debugging.
    """
    print("Este módulo es una librería de utilidades.")
    print("Funciones disponibles: fetch_emails_by_location, update_emails")