"""
Custom JWT authentication backend that automatically tracks user activity.

This extends Simple JWT's authentication to fire signals whenever JWT tokens
are validated, ensuring systematic activity tracking for API requests.
"""

import logging
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
from .signals import fire_jwt_authenticated_signal

logger = logging.getLogger(__name__)


class ActivityTrackingJWTAuthentication(JWTAuthentication):
    """
    Custom JWT authentication that automatically tracks user activity.
    
    This extends the default Simple JWT authentication to fire a signal
    whenever a user is successfully authenticated via JWT token validation.
    """
    
    def authenticate(self, request):
        """
        Authenticate the request and fire activity tracking signal on success.
        """
        # Call the parent authentication method
        result = super().authenticate(request)
        
        # If authentication was successful, fire the activity signal
        if result is not None:
            user, validated_token = result
            
            # Fire the JWT authentication signal for activity tracking
            try:
                fire_jwt_authenticated_signal(user, request)
            except Exception as e:
                # Log the error but don't break authentication
                logger.error(f"Error firing JWT authentication signal: {e}")
        
        return result
    
    def get_validated_token(self, raw_token):
        """
        Validate the given raw token and return a validated token instance.
        
        Override to add additional logging if needed.
        """
        try:
            return super().get_validated_token(raw_token)
        except TokenError as e:
            logger.debug(f"JWT token validation failed: {e}")
            raise InvalidToken(e.args[0])


class JWTCookieAuthentication(ActivityTrackingJWTAuthentication):
    """
    JWT authentication that reads tokens from cookies instead of headers.
    
    This is useful for web applications that want to use JWT tokens stored
    in HTTP-only cookies for additional security.
    """
    
    def get_raw_token(self, request):
        """
        Extract the JWT token from cookies instead of Authorization header.
        """
        # Try to get token from cookie first
        raw_token = request.COOKIES.get('access_token')
        
        if raw_token is None:
            # Fall back to header-based authentication
            return super().get_raw_token(request)
        
        return raw_token.encode('utf-8') if isinstance(raw_token, str) else raw_token


class HybridJWTAuthentication(ActivityTrackingJWTAuthentication):
    """
    Hybrid JWT authentication that tries both header and cookie methods.
    
    This provides maximum flexibility by supporting both:
    - Authorization header (for API clients)
    - HTTP-only cookies (for web applications)
    """
    
    def get_raw_token(self, request):
        """
        Try to extract JWT token from Authorization header first, then cookies.
        """
        # First try the standard header method
        header_token = super().get_raw_token(request)
        if header_token is not None:
            return header_token
        
        # If no header token, try cookies
        cookie_token = request.COOKIES.get('access_token')
        if cookie_token is not None:
            return cookie_token.encode('utf-8') if isinstance(cookie_token, str) else cookie_token
        
        return None 