from ninja.security import HttpBearer
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
import logging

logger = logging.getLogger(__name__)

# ==================== 自定义 JWT 认证 for Django Ninja ====================

class JWTAuth(HttpBearer):
    """
    Django Ninja 的 JWT 认证类
    兼容 rest_framework_simplejwt
    
    与 DRF 使用相同的认证逻辑，验证 JWT Token 并获取用户
    """
    def authenticate(self, request, token):
        jwt_authenticator = JWTAuthentication()
        try:
            # 验证 token 并获取用户
            validated_token = jwt_authenticator.get_validated_token(token)
            user = jwt_authenticator.get_user(validated_token)
            
            # 记录认证成功
            logger.debug(f"JWT 认证成功: user={user.username}")
            
            return user
        except (InvalidToken, TokenError) as e:
            logger.warning(f"JWT 认证失败: {str(e)}")
            return None


class JWTAuthWithEmployee(HttpBearer):
    """
    Django Ninja 的 JWT 认证类（要求必须有员工身份）
    
    与 CustomTokenObtainPairView 的逻辑一致：
    - 验证 JWT Token
    - 验证用户必须有关联的员工信息
    """
    
    def __call__(self, request):
        """
        重写 __call__ 方法以添加调试日志
        这个方法会被 Ninja 调用来执行认证
        """
        logger.info(f"[JWTAuthWithEmployee.__call__] 认证被调用")
        logger.info(f"[JWTAuthWithEmployee.__call__] Authorization Header: {request.META.get('HTTP_AUTHORIZATION', 'None')[:50]}...")
        
        # 调用父类的 __call__ 方法
        result = super().__call__(request)
        logger.info(f"[JWTAuthWithEmployee.__call__] 认证结果: {result}")
        return result
    
    def authenticate(self, request, token):
        logger.info(f"[JWTAuthWithEmployee.authenticate] 开始认证，token 前 20 字符: {token[:20] if token else 'None'}...")
        
        if not token:
            logger.warning(f"[JWTAuthWithEmployee.authenticate] Token 为空")
            return None
        
        jwt_authenticator = JWTAuthentication()
        try:
            # 验证 token 并获取用户
            validated_token = jwt_authenticator.get_validated_token(token)
            user = jwt_authenticator.get_user(validated_token)
            
            logger.info(f"[JWTAuthWithEmployee.authenticate] Token 验证成功，用户: {user.username}")
            
            # 检查用户是否有员工身份（与登录逻辑一致）
            if not hasattr(user, 'employee'):
                logger.warning(f"[JWTAuthWithEmployee.authenticate] 用户 {user.username} 没有关联的员工信息")
                return None  # 返回 None 会导致 401 Unauthorized
            
            logger.info(f"[JWTAuthWithEmployee.authenticate] 认证成功: user={user.username}, employee={user.employee.name}")
            return user
            
        except (InvalidToken, TokenError) as e:
            logger.warning(f"[JWTAuthWithEmployee.authenticate] Token 验证失败: {str(e)}")
            return None
        except Exception as e:
            logger.error(f"[JWTAuthWithEmployee.authenticate] 认证异常: {str(e)}", exc_info=True)
            return None
