from django.http import JsonResponse
from django.utils import timezone


class SubscriptionExpiryMiddleware:
    """
    Check the gym owner's subscription expiry on every request.
    - Skips unauthenticated, superusers, and auth/billing paths.
    - Free-tier subscriptions (expires_at=None) never expire.
    - If expired, marks the subscription as "expired" and returns 403.

    Uses DRF's JWT authentication so it works with token-based auth.
    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        path = request.path

        # Skip paths that must always be accessible
        if (
            path.startswith("/api/auth/")
            or path.startswith("/api/billing/")
            or path.startswith("/admin/")
            or not path.startswith("/api/")
        ):
            return self.get_response(request)

        # Authenticate via DRF's JWT (Django session auth won't have the user)
        user = self._get_jwt_user(request)
        if not user or not user.is_authenticated or user.is_superuser:
            return self.get_response(request)

        from apps.billing.models import Subscription
        from apps.core.permissions import get_gym_owner

        # Resolve the owner whose subscription we check
        owner = get_gym_owner(user)
        if not owner:
            owner = user

        sub = (
            Subscription.objects.filter(user=owner, status__in=["active", "expired"])
            .select_related("package")
            .order_by("-created_at")
            .first()
        )

        if sub and sub.expires_at and sub.expires_at < timezone.now():
            # Mark as expired if still active
            if sub.status == "active":
                sub.status = "expired"
                sub.save(update_fields=["status"])

            return JsonResponse(
                {"detail": "subscription_expired"},
                status=403,
            )

        return self.get_response(request)

    def _get_jwt_user(self, request):
        """Extract user from JWT Authorization header using DRF's auth."""
        auth_header = request.META.get("HTTP_AUTHORIZATION", "")
        if not auth_header.startswith("Bearer "):
            return None

        try:
            from rest_framework_simplejwt.authentication import JWTAuthentication
            jwt_auth = JWTAuthentication()
            validated = jwt_auth.authenticate(request)
            if validated:
                return validated[0]  # (user, token)
        except Exception:
            pass

        return None
