"""
slowapi Limiter singleton.

Initialized once here and imported by main.py (registered on app.state)
and by individual route handlers via @limiter.limit() decorator.

Redis backend ensures rate-limit counters are shared across multiple
uvicorn workers / pods — no per-process counter drift.
"""

from __future__ import annotations

from slowapi import Limiter
from slowapi.util import get_remote_address

from app.config import get_settings

settings = get_settings()


def _get_user_id_or_ip(request) -> str:  # type: ignore[no-untyped-def]
    """
    Rate-limit key for authenticated data endpoints.
    Uses user_id extracted from request state (set by gateway_auth).
    Falls back to IP for unauthenticated or API-key requests.
    """
    caller = getattr(request.state, "caller", None)
    if caller and hasattr(caller, "sub"):
        return f"user:{caller.sub}"
    if caller and hasattr(caller, "key_id"):
        return f"key:{caller.key_id}"
    return get_remote_address(request)


# Login endpoint: rate-limited by IP (5 attempts / 15 min)
limiter = Limiter(
    key_func=get_remote_address,
    storage_uri=settings.redis_url,
)

# Authenticated data API: rate-limited by user_id / key_id (1000 req/min)
data_limiter = Limiter(
    key_func=_get_user_id_or_ip,
    storage_uri=settings.redis_url,
)
