"""Configuración centralizada de logging estructurado para el supervisor.

- En desarrollo (LOG_FORMAT=text) emite líneas legibles con color por nivel.
- En producción (LOG_FORMAT=json, valor por defecto) emite JSON por línea,
  compatible con Loki, Datadog, CloudWatch y cualquier agregador estándar.
- El nivel se controla con LOG_LEVEL (default: INFO).
- Silencia loggers ruidosos de librerías externas que no aportan valor operativo.
"""
from __future__ import annotations

import json
import logging
import os
import sys
import time
from typing import Any


class _JsonFormatter(logging.Formatter):
    """Formatea cada registro como una línea JSON."""

    def format(self, record: logging.LogRecord) -> str:
        payload: dict[str, Any] = {
            "ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(record.created)),
            "level": record.levelname,
            "logger": record.name,
            "msg": record.getMessage(),
        }
        if record.exc_info:
            payload["exc"] = self.formatException(record.exc_info)
        # Campos extra que el código puede añadir con extra={...}
        for key, value in record.__dict__.items():
            if key not in {
                "args", "asctime", "created", "exc_info", "exc_text",
                "filename", "funcName", "id", "levelname", "levelno",
                "lineno", "message", "module", "msecs", "msg", "name",
                "pathname", "process", "processName", "relativeCreated",
                "stack_info", "thread", "threadName",
            }:
                try:
                    json.dumps(value)
                    payload[key] = value
                except (TypeError, ValueError):
                    payload[key] = str(value)
        return json.dumps(payload, ensure_ascii=False)


class _TextFormatter(logging.Formatter):
    _COLORS = {
        "DEBUG": "\033[36m",
        "INFO": "\033[32m",
        "WARNING": "\033[33m",
        "ERROR": "\033[31m",
        "CRITICAL": "\033[35m",
    }
    _RESET = "\033[0m"

    def format(self, record: logging.LogRecord) -> str:
        color = self._COLORS.get(record.levelname, "")
        ts = time.strftime("%H:%M:%S", time.gmtime(record.created))
        prefix = f"{color}{ts} {record.levelname:<8}{self._RESET} {record.name}"
        return f"{prefix}  {record.getMessage()}"


def configure_logging() -> None:
    """Llama una sola vez al arrancar la aplicación (startup_event)."""
    level_name = os.getenv("LOG_LEVEL", "INFO").upper()
    level = getattr(logging, level_name, logging.INFO)

    fmt = os.getenv("LOG_FORMAT", "json").lower()
    formatter: logging.Formatter = _TextFormatter() if fmt == "text" else _JsonFormatter()

    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(formatter)

    root = logging.getLogger()
    root.setLevel(level)
    # Evita duplicar handlers si se llama varias veces (--reload de uvicorn)
    root.handlers.clear()
    root.addHandler(handler)

    # Silenciar loggers ruidosos que no aportan valor operativo
    for noisy in (
        "httpx",
        "httpcore",
        "uvicorn.access",   # sustituido por nuestro middleware
        "uvicorn.lifespan",
        "multipart",
        "python_multipart",
    ):
        logging.getLogger(noisy).setLevel(logging.WARNING)

    logging.getLogger("uvicorn.error").setLevel(logging.INFO)
    logging.getLogger("uvicorn").setLevel(logging.INFO)
