# shared_db_utils.py
from flask import g
from pymongo import MongoClient, ASCENDING
from datetime import datetime
# =============================================================================
# Constantes y configuraciones globales
# =============================================================================

SERVICIOS_SOPORTADOS = ["enviro", "nanoox", "scapp", "pss", "flux"]
# Configuración de Mapeo de Servicios (Nombre API -> Nombre DB Mongo)
SERVICES_DB_MAP = {
    "enviro": "ENVIRO",
    "nanoox": "NANOOX__TS",
    "flux":   "FLUX__TS",
    "scapp":  "ScappDB",
    "pss":    "PssDB",
    "notification_emails":"emails",
    "analytic" : "data_analytic",
}

# Definicion de nombres de bases de datos globales de un solo cliente
USER_DATABASE_NAME = "users"
ENVIRO_DATABASE_NAME = "ENVIRO"
NANOOX_DATABASE_NAME =  "NANOOX__TS" 
SCAPP_DATABASE_NAME = "ScappDB" 
FLUX_DATABASE_NAME = "FLUX__TS"
EMAIL_COLLECTION_NAME = "emails"
ANALYTIC_COLLECTION_NAME = "data_analytic"
ANALYTIC_UNIQUE_INDEX_NAME = "uq_centro_camera_timestamp"
ANALYTIC_QUERY_INDEX_NAME = "idx_centro_timestamp"
ANALYTIC_TIMESTAMP_INDEX_NAME = "idx_timestamp"
_analytic_schema_ready = set()


# =============================================================================
# Funciones Públicas
# =============================================================================

def get_db():
    """Obtiene una conexion de MongoDB por request."""
    if 'db_client' not in g:
        # Ajusta la URI según tu config real
        g.db_client = MongoClient("mongodb://localhost:27017/")
    return g.db_client


def insert_log_in_user_history(collection, username, edit_object, log_type):
    timestamp = datetime.now()
    if log_type=='renew_password':
        action = f"reestablecio su contraseña"
    elif log_type=='add_user':
        action = f"creo al usuario {edit_object}"
    elif log_type=='edit_user':
        action = f"edito al usuario {edit_object}"
    elif log_type=='delete_user':
        action = f"elimino al usuario {edit_object}"
    elif log_type=='add_center':
        action = f"creo el centro {edit_object}"
    elif log_type=='edit_center':
        action = f"edito el centro {edit_object}"
    elif log_type=='delete_center':
        action = f"elimino el centro {edit_object}"
    elif log_type=='add_scapp_threshold':
        action = f"edito los umbrales de Region Scapp del centro {edit_object}"
    elif log_type=='add_center_permission':
        action = f"agregó automáticamente permiso del centro {edit_object[1]} al ususario {edit_object[0]}"
    elif log_type == 'read_notification':
        # edit_object esperamos que sea una tupla/dict: (service_name, centro_id, notif_title)
        svc = edit_object.get('service', '?')
        centro = edit_object.get('centro', '?')
        alerta_msg = edit_object.get('message', 'Sin detalle')
        action = f"confirmó lectura de alerta '{alerta_msg}' ({svc}) en centro {centro}"
    
    log_entry = {
        'date': timestamp,
        'username': username,
        'type': log_type,
        'msg': f'El usuario {username} {action} a las {timestamp.isoformat()}'
    }
    collection.insert_one(log_entry)
    # print(log_entry['msg'])
    return


def ensure_analytic_collection(database, collection_name=ANALYTIC_COLLECTION_NAME):
    """Garantiza el esquema normal requerido por la analítica de SCAPP."""
    cache_key = (database.name, collection_name)
    # El esquema sólo cambia con el backend detenido; una migración online deberá invalidar esta caché.
    if cache_key in _analytic_schema_ready:
        return database[collection_name]

    info = next(
        iter(database.list_collections(filter={"name": collection_name})),
        None,
    )
    if info and info.get("type") == "timeseries":
        raise RuntimeError(
            f"{collection_name} aún es time-series; ejecute la migración manual antes de iniciar el backend."
        )
    if info is None:
        database.create_collection(collection_name)
        print(f"[Init] Colección normal '{collection_name}' creada.")

    collection = database[collection_name]
    collection.create_index(
        [("centro_id", ASCENDING), ("camera_id", ASCENDING), ("timestamp", ASCENDING)],
        name=ANALYTIC_UNIQUE_INDEX_NAME,
        unique=True,
    )
    collection.create_index(
        [("centro_id", ASCENDING), ("timestamp", ASCENDING)],
        name=ANALYTIC_QUERY_INDEX_NAME,
    )
    collection.create_index(
        [("timestamp", ASCENDING)],
        name=ANALYTIC_TIMESTAMP_INDEX_NAME,
    )
    _analytic_schema_ready.add(cache_key)
    return collection


def ensure_analytic_indexes():
    """Verifica la colección de analítica al iniciar el servidor."""
    client = MongoClient("mongodb://localhost:27017/")
    try:
        ensure_analytic_collection(client[SCAPP_DATABASE_NAME])
        print("[Init] Colección e índices de analítica verificados.")
    except Exception as error:
        print(f"[Error] Fallo al verificar la colección de analítica: {error}")
    finally:
        client.close()
