"""GraphQL context for request handling and authentication."""

import jwt
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractBaseUser, AnonymousUser
from strawberry.django.context import StrawberryDjangoContext

UserModel = get_user_model()


def get_user_from_token(token: str) -> AbstractBaseUser | AnonymousUser:
    """Extract and validate user from JWT token."""
    if not token:
        return AnonymousUser()

    try:
        # Remove 'Bearer ' prefix if present
        if token.startswith("Bearer "):
            token = token[7:]

        payload = jwt.decode(
            token,
            settings.SECRET_KEY,
            algorithms=["HS256"],
        )
        user_id = payload.get("user_id")
        if user_id:
            try:
                return UserModel.objects.get(pk=user_id)
            except UserModel.DoesNotExist:
                return AnonymousUser()
    except jwt.ExpiredSignatureError:
        return AnonymousUser()
    except jwt.InvalidTokenError:
        return AnonymousUser()

    return AnonymousUser()


class DexxyGraphQLContext(StrawberryDjangoContext):
    """Custom GraphQL context with user authentication."""

    def __init__(self, request, response=None):
        super().__init__(request=request, response=response)
        self._user = None

    @property
    def user(self):
        """Get authenticated user from JWT token."""
        if self._user is None:
            auth_header = self.request.META.get("HTTP_AUTHORIZATION", "")
            self._user = get_user_from_token(auth_header)
        return self._user


def get_context(request, response=None) -> DexxyGraphQLContext:
    """Create context for each GraphQL request."""
    return DexxyGraphQLContext(request=request, response=response)
