# home/api/rate_limit.py

from functools import wraps
from django.http import JsonResponse
from django.core.cache import cache
from django.conf import settings
from wagtail.models import Site
import time


# =========================
# Config
# =========================
RATE_LIMIT_REQUESTS = getattr(settings, "TENANT_RATE_LIMIT_REQUESTS", 100)
RATE_LIMIT_WINDOW = getattr(settings, "TENANT_RATE_LIMIT_WINDOW", 60)  # detik


def _rate_limit_key(site_id):
    return f"rate_limit:tenant:{site_id}"


def tenant_rate_limited(view_func):
    """
    Rate limit per tenant (Site).
    DEV localhost bebas, PROD ketat.
    """

    @wraps(view_func)
    def _wrapped(request, *args, **kwargs):
        # DEV mode: skip rate limit
        if settings.DEBUG:
            return view_func(request, *args, **kwargs)

        site = Site.find_for_request(request)
        if not site:
            return JsonResponse({"detail": "Site not resolved"}, status=404)

        key = _rate_limit_key(site.id)

        # Ambil data rate limit
        data = cache.get(key)

        now = int(time.time())

        if data is None:
            # pertama kali dalam window
            cache.set(
                key,
                {"count": 1, "start": now},
                timeout=RATE_LIMIT_WINDOW
            )
            return view_func(request, *args, **kwargs)

        count = data.get("count", 0)
        start = data.get("start", now)

        # reset window jika waktu habis
        if now - start >= RATE_LIMIT_WINDOW:
            cache.set(
                key,
                {"count": 1, "start": now},
                timeout=RATE_LIMIT_WINDOW
            )
            return view_func(request, *args, **kwargs)

        # exceed limit
        if count >= RATE_LIMIT_REQUESTS:
            return JsonResponse(
                {
                    "detail": "Rate limit exceeded",
                    "limit": RATE_LIMIT_REQUESTS,
                    "window_seconds": RATE_LIMIT_WINDOW,
                },
                status=429
            )

        # increment counter
        data["count"] = count + 1
        cache.set(key, data, timeout=RATE_LIMIT_WINDOW)

        return view_func(request, *args, **kwargs)

    return _wrapped