"""请求指标收集中间件：计时、慢请求告警、响应时间响应头。"""
import time
import logging
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response

logger = logging.getLogger("geo.metrics")

# 慢请求阈值（秒）
SLOW_REQUEST_THRESHOLD = 1.0

# 跳过指标收集的路径前缀（健康检查等高频低价值路径）
_SKIP_PATHS = {"/health", "/ready", "/docs", "/openapi.json", "/favicon.ico"}


class MetricsMiddleware(BaseHTTPMiddleware):
    """记录每个 HTTP 请求的耗时，并：
    - 在响应头写入 X-Response-Time
    - 对超过阈值的慢请求输出 WARNING 日志（携带结构化字段）
    - 预留 Sentry / Prometheus 集成点（TODO 注释标注）
    """

    async def dispatch(self, request: Request, call_next) -> Response:
        # 跳过健康检查等低价值路径，避免日志噪音
        if request.url.path in _SKIP_PATHS:
            return await call_next(request)

        start_time = time.perf_counter()
        response = await call_next(request)
        duration = time.perf_counter() - start_time
        duration_ms = round(duration * 1000, 2)

        # 写回响应时间响应头
        response.headers["X-Response-Time"] = f"{duration:.3f}s"

        # 从 request.state 获取 request_id（由 RequestIdMiddleware 注入）
        request_id = getattr(request.state, "request_id", None)

        log_extra: dict = {
            "path": request.url.path,
            "method": request.method,
            "duration_ms": duration_ms,
            "status_code": response.status_code,
        }
        if request_id:
            log_extra["request_id"] = request_id

        if duration >= SLOW_REQUEST_THRESHOLD:
            logger.warning("Slow request detected", extra=log_extra)
        else:
            logger.debug("Request completed", extra=log_extra)

        # TODO: 集成 Prometheus Counter/Histogram
        # metrics_registry.http_request_duration.observe(duration, labels={...})

        # TODO: 集成 Sentry 性能监控
        # if sentry_sdk: sentry_sdk.set_measurement("response_time_ms", duration_ms)

        return response
