import re
import time

from prometheus_client import Counter, Gauge, Histogram


HTTP_REQUESTS = Counter(
    "documenta_http_requests_total",
    "Solicitudes HTTP procesadas por portal y ruta acotada.",
    ("portal", "method", "route", "status"),
)
HTTP_DURATION = Histogram(
    "documenta_http_request_duration_seconds",
    "Duración HTTP por portal y ruta acotada.",
    ("portal", "method", "route"),
    buckets=(0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10),
)
COMPONENT_HEALTH = Gauge(
    "documenta_component_health",
    "Estado del componente: 1 operativo, 0 degradado o no disponible.",
    ("component",),
)
PENDING_ITEMS = Gauge(
    "documenta_pending_items",
    "Elementos pendientes por cola o integración.",
    ("component",),
)

KNOWN_HOSTS = {
    "documenta.cl": "portal",
    "www.documenta.cl": "portal",
    "tramites.documenta.cl": "tramites",
    "personas.documenta.cl": "personas",
    "pro.documenta.cl": "pro",
    "notaria.documenta.cl": "notaria",
    "cbr.documenta.cl": "cbr",
    "archivero.documenta.cl": "archivero",
}


def portal_name(host: str | None) -> str:
    clean = (host or "").split(":", 1)[0].lower()
    return KNOWN_HOSTS.get(clean, "interno")


def safe_route(request) -> str:
    route = request.scope.get("route")
    path = getattr(route, "path", None) or request.url.path
    path = re.sub(r"/[0-9a-fA-F-]{16,}", "/:id", path)
    path = re.sub(r"/\d+", "/:id", path)
    return path[:180]


def observe_request(request, response_status: int, started: float) -> None:
    portal = portal_name(request.headers.get("host"))
    route = safe_route(request)
    method = request.method[:10]
    status = str(response_status)
    HTTP_REQUESTS.labels(portal, method, route, status).inc()
    HTTP_DURATION.labels(portal, method, route).observe(max(0.0, time.monotonic() - started))


def set_component(name: str, healthy: bool) -> None:
    COMPONENT_HEALTH.labels(name).set(1 if healthy else 0)


def set_pending(name: str, value: int | float) -> None:
    PENDING_ITEMS.labels(name).set(max(0, value))
