import jwt
import requests
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from jwt import algorithms
from rest_framework import authentication, exceptions


class LogtoAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        auth_header = authentication.get_authorization_header(request).decode("utf-8")
        if not auth_header or not auth_header.startswith("Bearer "):
            return None  # No credentials provided

        token = auth_header.split(" ")[1]

        try:
            # Get OpenID config and JWKS
            openid_config = self._get_openid_config()
            jwks = self._get_jwks(openid_config["jwks_uri"])
            key = algorithms.RSAAlgorithm.from_jwk(jwks["keys"][0])

            # Decode and validate JWT
            decoded = jwt.decode(
                token,
                key=key,
                algorithms=["RS256"],
                audience=settings.LOGTO_CLIENT_ID,
                issuer=openid_config["issuer"]
            )

            # You can inspect 'decoded' here if needed
            request.auth_payload = decoded  # Optional: attach decoded payload to request

            return (AnonymousUser(), token)
        except Exception as e:
            raise exceptions.AuthenticationFailed(f"Invalid Logto token: {str(e)}")

    def _get_openid_config(self):
        url = f"{settings.LOGTO_ENDPOINT}/.well-known/openid-configuration"
        response = requests.get(url, timeout=5)
        response.raise_for_status()
        return response.json()

    def _get_jwks(self, jwks_uri):
        response = requests.get(jwks_uri, timeout=5)
        response.raise_for_status()
        return response.json()
