from django.utils.deprecation import MiddlewareMixin
import jwt
from django.conf import settings
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.exceptions import TokenError


class TokenMiddleware(MiddlewareMixin):
    def refresh_token(self, refresh_token: str):
        try:
            # Decode the refresh token to get the access token
            refresh = RefreshToken(refresh_token)

            # Generate a new access token from the refresh token
            new_access_token = str(refresh.access_token)
            return new_access_token
        except TokenError as e:
            # Handle any errors related to the refresh token (e.g., expired or invalid)
            return None

    def process_request(self, request):
        access_token = request.COOKIES.get("access_token")
        refresh_token = request.COOKIES.get("refresh_token")
        path = request.path

        excluded_paths = all(route not in path for route in ("login", "admin"))

        if excluded_paths and access_token:
            try:
                jwt.decode(
                    access_token, settings.SECRET_KEY, algorithms=["HS256"]
                )  # Triggers ExpiredSignatureError if token is expired
                access_token = self.refresh_token(refresh_token=refresh_token)
                request.META["HTTP_AUTHORIZATION"] = f"Bearer {access_token}"
            except jwt.ExpiredSignatureError:
                if refresh_token:
                    access_token = self.refresh_token(refresh_token=refresh_token)

                    if access_token is None:
                        return None

                    request.META["HTTP_AUTHORIZATION"] = f"Bearer {access_token}"
                else:
                    del request.META["HTTP_AUTHORIZATION"]
            except jwt.InvalidSignatureError:
                if "HTTP_AUTHORIZATION" in request.META:
                    del request.META["HTTP_AUTHORIZATION"]
                return None
