"""
Custom authentication classes for DRF
"""
from rest_framework.authentication import SessionAuthentication, BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
import jwt


class CSRFExemptSessionAuthentication(SessionAuthentication):
    """
    Session authentication that doesn't enforce CSRF for API endpoints.
    This is safe for API usage since we're using session cookies and proper CORS settings.
    """
    def enforce_csrf(self, request):
        """
        Override to skip CSRF enforcement for API endpoints.
        """
        return  # Skip CSRF check


class JWTAuthentication(BaseAuthentication):
    """
    JWT token authentication for DRF.
    Extracts JWT token from Authorization header and validates it.
    """
    def authenticate(self, request):
        """
        Authenticate the request and return a two-tuple of (user, token).
        """
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        
        if not auth_header.startswith('Bearer '):
            return None  # No JWT token, let other auth classes handle it
        
        token = auth_header.split(' ')[1] if len(auth_header.split(' ')) > 1 else None
        if not token:
            return None
        
        try:
            from igny8_core.auth.utils import decode_token
            from igny8_core.auth.models import User, Account
            
            # Decode and validate token
            payload = decode_token(token)
            
            # Verify it's an access token
            if payload.get('type') != 'access':
                # Invalid token type - return None to allow other auth classes to try
                return None
            
            # Get user
            user_id = payload.get('user_id')
            if not user_id:
                # Invalid token payload - return None to allow other auth classes to try
                return None
            
            try:
                user = User.objects.get(id=user_id)
            except User.DoesNotExist:
                # User not found - return None to allow other auth classes to try
                return None
            
            # Get account from token
            account_id = payload.get('account_id')
            account = None
            if account_id:
                try:
                    account = Account.objects.get(id=account_id)
                except Account.DoesNotExist:
                    pass
            
            if not account:
                try:
                    account = getattr(user, 'account', None)
                except (AttributeError, Exception):
                    # If account access fails, set to None
                    account = None
            
            # Set account on request
            request.account = account
            
            return (user, token)
            
        except jwt.InvalidTokenError:
            # Invalid or expired token - return None to allow other auth classes (session) to try
            return None
        except Exception as e:
            # Other errors - return None to allow other auth classes to try
            # This allows session authentication to work if JWT fails
            return None

