"""
SSE认证工具模块

提供统一的认证和商户验证功能，用于SSE连接端点和其他需要认证的地方
"""

from django.http import HttpResponseForbidden
from rest_framework.authentication import get_authorization_header
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.exceptions import InvalidToken
from rest_framework.exceptions import AuthenticationFailed
import logging

logger = logging.getLogger(__name__)


def get_user_merchant_id(request):
    """获取用户所属商户ID"""
    try:
        # 检查用户是否已认证
        if not request.user.is_authenticated:
            return None
        # 获取商户ID
        return request.user.employee.merchant_id
    except (AttributeError, AttributeError):
        return None


def authenticate_sse_request(request):
    """
    对SSE连接请求进行认证
    
    参数:
    - request: Django HTTP请求对象
    
    返回:
    - tuple: (user, merchant_id) 认证成功返回用户和商户ID
    - None: 认证失败返回None
    """
    jwt_authenticator = JWTAuthentication()
    
    try:
        # 获取Authorization头
        auth_header = get_authorization_header(request).split()
        if not auth_header or auth_header[0].lower() != b'bearer':
            logger.warning("SSE认证失败: 缺少Bearer token")
            return None
        
        if len(auth_header) < 2:
            logger.warning("SSE认证失败: Bearer token格式错误")
            return None
        
        token = auth_header[1].decode('utf-8')
        
        # 验证token
        validated_token = jwt_authenticator.get_validated_token(token)
        user = jwt_authenticator.get_user(validated_token)
        
        # 检查用户是否有关联的员工和商户
        try:
            merchant_id = user.employee.merchant_id
            if not merchant_id:
                logger.warning(f"用户 {user.username} 无关联商户")
                return None
            return user, merchant_id
        except AttributeError:
            logger.warning(f"用户 {user.username} 无关联员工")
            return None
            
    except (IndexError, InvalidToken, AuthenticationFailed) as e:
        logger.warning(f"SSE认证失败: {str(e)}")
        return None


def require_sse_authentication(view_func):
    """
    装饰器：要求SSE连接认证
    
    用于SSE连接端点的认证，如果认证失败则返回403响应
    OPTIONS请求跳过认证
    """
    def wrapper(request, *args, **kwargs):
        # OPTIONS请求跳过认证
        if request.method == 'OPTIONS':
            return view_func(request, *args, **kwargs)
            
        auth_result = authenticate_sse_request(request)
        if not auth_result:
            return HttpResponseForbidden("Authentication failed or user has no associated merchant")
        
        user, merchant_id = auth_result
        request.user = user
        request.merchant_id = merchant_id
        
        return view_func(request, *args, **kwargs)
    
    return wrapper


def validate_sse_request(request):
    """
    验证SSE请求的认证状态
    
    返回:
    - tuple: (is_valid, error_response)
    - is_valid: bool 表示请求是否有效
    - error_response: HttpResponse 如果无效则返回错误响应，否则为None
    """
    auth_result = authenticate_sse_request(request)
    if not auth_result:
        return False, HttpResponseForbidden("Authentication failed or user has no associated merchant")
    
    user, merchant_id = auth_result
    request.user = user
    request.merchant_id = merchant_id
    
    return True, None