"""Rate limiting sederhana (jendela geser, per IP) + header keamanan."""
from __future__ import annotations

import time
from collections import defaultdict, deque

from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import JSONResponse

from ..config import settings


class RateLimitMiddleware(BaseHTTPMiddleware):
    def __init__(self, app, rules: dict[str, int] | None = None, default: int = 900):
        super().__init__(app)
        self.rules = rules or {"/api/auth/login": settings.login_rate_per_min, "/api/setup": 5,
                               "/api/agent/register": 30, "/api/auth/refresh": 30}
        self.default = default
        self.hits: dict[tuple[str, str], deque] = defaultdict(deque)

    async def dispatch(self, request, call_next):
        path = request.url.path
        if path.startswith("/api"):
            ip = request.client.host if request.client else "?"
            limit, bucket = self.default, "default"
            for prefix, lim in self.rules.items():
                if path.startswith(prefix):
                    limit, bucket = lim, prefix
                    break
            now = time.monotonic()
            q = self.hits[(ip, bucket)]
            while q and now - q[0] > 60:
                q.popleft()
            if len(q) >= limit:
                return JSONResponse({"detail": "Terlalu banyak permintaan, coba lagi sebentar lagi."}, status_code=429,
                                    headers={"Retry-After": "30"})
            q.append(now)
        resp = await call_next(request)
        resp.headers.setdefault("X-Content-Type-Options", "nosniff")
        resp.headers.setdefault("X-Frame-Options", "DENY")
        resp.headers.setdefault("Referrer-Policy", "no-referrer")
        resp.headers.setdefault("Cache-Control", "no-store") if path.startswith("/api") else None
        return resp
