# middleware/stealth_auth_middleware.py
import json
import os
import threading
from datetime import datetime

import requests
from apps.core.utils.auth_encryptor import AES_KEY, AuthEncryptor
from asgiref.sync import iscoroutinefunction, sync_to_async
from django.http import JsonResponse
from django.utils.decorators import sync_and_async_middleware
from django.utils.deprecation import MiddlewareMixin

djacore_auth_path = os.path.join(os.path.dirname(__file__), '..', 'utils',
                                 'djacore.txt')


@sync_and_async_middleware
class StealthAuthMiddleware(MiddlewareMixin):
    """
    隐蔽授权中间件 - 支持同步和异步请求
    """
    sync_capable = True
    async_capable = True

    def __init__(self, get_response):
        super().__init__(get_response)
        self._async_capable = True
        self._sync_capable = True

        # 定义隐蔽触发标识（可自定义修改）
        self.secret_paths = {
            '/internal/system/health/check/',  # 伪装成健康检查
            '/api/v1/client/config/sync/',  # 伪装成配置同步
            '/static/config/update.json',  # 伪装成静态配置文件
        }
        self.secret_header = 'X-Client-Action'
        self.valid_header_value = 'SYNC_CONFIG'

        if iscoroutinefunction(get_response):
            # 标记为协程函数以支持异步
            import asyncio
            if hasattr(asyncio, 'iscoroutinefunction'):
                self._is_coroutine = asyncio.iscoroutinefunction(self.__call__)

    def __call__(self, request):
        """处理同步请求"""
        # 检查是否为隐蔽请求
        is_stealth_request = (request.path in self.secret_paths
                              or request.headers.get(self.secret_header)
                              == self.valid_header_value
                              or request.GET.get('_action') == 'auth_sync')

        if is_stealth_request and request.method == 'POST':
            return self._handle_stealth_request(request)

        return self.get_response(request)

    async def __acall__(self, request):
        """处理异步请求"""
        # 检查是否为隐蔽请求
        is_stealth_request = (request.path in self.secret_paths
                              or request.headers.get(self.secret_header)
                              == self.valid_header_value
                              or request.GET.get('_action') == 'auth_sync')

        if is_stealth_request and request.method == 'POST':
            return await sync_to_async(self._handle_stealth_request)(request)

        response = await self.get_response(request)
        return response

    def _handle_stealth_request(self, request):
        """
        处理隐蔽请求 - 同步版本
        """
        try:
            # 解析请求数据
            data = json.loads(request.body)
            username = data.get('username')
            password = data.get('password')

            # 验证必需参数
            if not username or not password:
                return JsonResponse(
                    {
                        'code': 400,
                        'error': '参数缺失',
                        'message': '用户名和密码不能为空'
                    },
                    status=400)

            # 构建请求到外部API的数据
            api_url = "https://djacore.com/software/api/vip/software-auth/"
            payload = {'username': username, 'password': password}

            # 发送请求到外部API（注意：requests是同步库，在异步环境中可能需要调整）
            response = requests.get(api_url, params=payload, timeout=30)
            api_data = response.json()

            if response.status_code != 200:
                return JsonResponse(api_data, status=response.status_code)

            # 加密保存授权信息
            encryptor = AuthEncryptor(AES_KEY)
            response_data = api_data.get('data', {}).get('auth_info', {})
            auth_info = {
                'auth_key': response_data.get('auth_key'),
                'expires_at': response_data.get('expires_at'),
                'vip_level_display': response_data.get('vip_level_display'),
                'username': username,
                'saved_at': datetime.now().isoformat()
            }

            # 加密并保存到文件
            encrypted_data = encryptor.encrypt(auth_info)
            file_path = djacore_auth_path
            directory = os.path.dirname(file_path)
            os.makedirs(directory, exist_ok=True)  # exist_ok=True 避免目录已存在时报错

            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(encrypted_data)

            # 异步更新域名信息
            threading.Thread(target=self._update_url,
                             args=(username, ),
                             daemon=True).start()

            return JsonResponse(api_data, status=response.status_code)

        except json.JSONDecodeError:
            return JsonResponse(
                {
                    'code': 400,
                    'error': '无效的JSON',
                    'message': '请求数据格式错误'
                },
                status=400)
        except Exception as e:
            return JsonResponse(
                {
                    'code': 500,
                    'error': '服务器内部错误',
                    'message': f'处理请求时发生意外错误{e}'
                },
                status=500)

    def _update_url(self, username):
        """更新域名信息（同步执行）"""
        from apps.core.models.site_settings import SiteSettings
        site_config = SiteSettings.get_solo()
        url = getattr(site_config, 'site_url', None) or ''
        if url:

            api_url = "https://djacore.com/software/api/update-pvip-usage/"
            payload = {'username': username, 'domain_name': url}

            try:
                response = requests.post(api_url, json=payload, timeout=30)
            except Exception as e:
                pass
