import hashlib
import json
import os
import platform
import socket
import subprocess
import threading
import uuid
from datetime import datetime

import requests
from apps.core.middleware.stealth_auth_middleware import djacore_auth_path
from apps.core.utils.cache_decorator import cache_decorator
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods

from .auth_encryptor import AES_KEY, AuthEncryptor


def generate_environment_fingerprint():
    """
    生成服务器环境指纹
    返回: 环境指纹的SHA256哈希值
    """
    fingerprint_data = ""

    try:
        # 1. 系统标识信息
        fingerprint_data += platform.node() or ""  # 主机名
        fingerprint_data += socket.gethostname() or ""  # 完整域名
    except:
        pass

    try:
        # 2. 硬件标识信息 - MAC地址
        mac = ":".join(
            [
                "{:02x}".format((uuid.getnode() >> elements) & 0xFF)
                for elements in range(0, 2 * 6, 2)
            ][::-1]
        )
        fingerprint_data += mac
    except:
        pass
    try:
        # 3. 磁盘序列号（Windows/Linux）
        if os.name == "nt":  # Windows
            # 使用stderr参数重定向错误输出
            result = subprocess.check_output(
                "wmic diskdrive get serialnumber",
                shell=True,
                stderr=subprocess.DEVNULL,  # 静默丢弃错误输出
                universal_newlines=True,  # 直接返回字符串
            )
            fingerprint_data += result.strip()
        elif os.name == "posix":  # Linux
            # 尝试获取机器ID
            if os.path.exists("/etc/machine-id"):
                with open("/etc/machine-id", "r") as f:
                    fingerprint_data += f.read().strip()
            # 获取CPU信息
            if os.path.exists("/proc/cpuinfo"):
                with open("/proc/cpuinfo", "r") as f:
                    for line in f:
                        if "model name" in line or "serial" in line:
                            fingerprint_data += line.strip()
    except subprocess.CalledProcessError:
        # 命令执行失败时的处理
        pass
    except Exception:
        # 其他异常处理
        pass

    try:
        # 4. 内存信息
        import psutil

        fingerprint_data += str(psutil.virtual_memory().total)
    except:
        pass

    # 生成哈希指纹
    if fingerprint_data:
        fingerprint_hash = hashlib.sha256(fingerprint_data.encode()).hexdigest()
        return fingerprint_hash
    else:
        # 如果无法生成指纹，返回默认值
        return "default_fingerprint"


@csrf_exempt
@require_http_methods(["POST"])
def get_vip_auth(request):
    """
    获取VIP授权的API视图
    """
    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,
                json_dumps_params={"ensure_ascii": False},
                content_type="application/json; charset=utf-8",
            )

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

        # 发送请求到外部API
        try:
            response = requests.get(api_url, params=payload, timeout=30)

            # 获取外部API的响应数据
            api_data = response.json()

            # 如果外部API返回错误，直接转发错误信息
            if response.status_code != 200:
                return JsonResponse(
                    api_data,
                    status=response.status_code,
                    json_dumps_params={"ensure_ascii": False},
                    content_type="application/json; charset=utf-8",
                )

            # 🆕 生成当前服务器环境指纹
            current_fingerprint = generate_environment_fingerprint()

            # 加密保存授权信息（包含环境指纹）
            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(),
                # 🆕 添加环境指纹信息
                "environment_fingerprint": current_fingerprint,
                "fingerprint_created": datetime.now().isoformat(),
                "server_hostname": (
                    socket.gethostname() if hasattr(socket, "gethostname") else "unknown"
                ),
            }

            # 加密并保存到文件
            encrypted_data = encryptor.encrypt(auth_info)
            file_path = djacore_auth_path

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

            threading.Thread(target=update_url, args=(username,)).start()

            # 返回成功响应（可选：在响应中也包含指纹创建信息）
            if "data" in api_data and "auth_info" in api_data["data"]:
                api_data["data"]["auth_info"]["environment_fingerprint_saved"] = True

            return JsonResponse(
                api_data,
                status=response.status_code,
                json_dumps_params={"ensure_ascii": False},
                content_type="application/json; charset=utf-8",
            )

        except requests.exceptions.Timeout:
            return JsonResponse(
                {"code": 408, "error": "请求超时", "message": "连接授权服务器超时，请稍后重试"},
                status=408,
                json_dumps_params={"ensure_ascii": False},
                content_type="application/json; charset=utf-8",
            )

        except requests.exceptions.ConnectionError:
            return JsonResponse(
                {
                    "code": 503,
                    "error": "服务不可用",
                    "message": "无法连接到授权服务器，请检查网络连接",
                },
                status=503,
                json_dumps_params={"ensure_ascii": False},
                content_type="application/json; charset=utf-8",
            )

        except requests.exceptions.RequestException as e:
            # 尝试获取外部API的错误响应
            if hasattr(e, "response") and e.response:
                try:
                    error_data = e.response.json()
                    return JsonResponse(
                        error_data,
                        status=e.response.status_code,
                        json_dumps_params={"ensure_ascii": False},
                        content_type="application/json; charset=utf-8",
                    )
                except:
                    pass

            return JsonResponse(
                {
                    "code": 500,
                    "error": "授权服务器错误",
                    "message": f"授权服务器返回错误: {str(e)}",
                },
                status=500,
                json_dumps_params={"ensure_ascii": False},
                content_type="application/json; charset=utf-8",
            )

    except json.JSONDecodeError:
        return JsonResponse(
            {"code": 400, "error": "无效的JSON", "message": "请求数据格式错误"},
            status=400,
            json_dumps_params={"ensure_ascii": False},
            content_type="application/json; charset=utf-8",
        )

    except Exception as e:
        # 记录异常信息（在生产环境中应该使用logging）
        print(f"VIP授权错误: {str(e)}")

        return JsonResponse(
            {"code": 500, "error": "服务器内部错误", "message": f"处理请求时发生意外错误{e}"},
            status=500,
            json_dumps_params={"ensure_ascii": False},
            content_type="application/json; charset=utf-8",
        )


def update_url(username):
    from apps.core.models.site_settings import SiteSettings

    site_config = SiteSettings.get_solo()
    if getattr(site_config, "site_url", ""):
        url = site_config.site_url
        api_url = "https://djacore.com/software/api/update-pvip-usage/"
        payload = {"username": username, "domain_name": url}

        # 发送请求到外部API
        try:
            response = requests.post(api_url, json=payload, timeout=30)
        except Exception as e:
            pass


def validate_vip_auth():
    """
    验证VIP授权是否有效（包含环境指纹验证）
    返回: (is_valid, auth_info, message)
    """
    try:
        file_path = djacore_auth_path

        if not os.path.exists(file_path):
            return False, None, "授权文件不存在"

        # 读取并解密授权信息
        with open(file_path, "r", encoding="utf-8") as f:
            encrypted_data = f.read().strip()

        encryptor = AuthEncryptor(AES_KEY)
        auth_info = encryptor.decrypt(encrypted_data)
        if not auth_info:
            return False, None, "解密失败或授权文件损坏"

        # 🆕 环境指纹验证
        current_fingerprint = generate_environment_fingerprint()
        saved_fingerprint = auth_info.get("environment_fingerprint")

        # 如果授权文件中没有保存指纹，说明是旧版授权，可以添加当前指纹
        if not saved_fingerprint:
            try:
                update_auth_file_with_fingerprint(auth_info, current_fingerprint)
            except:
                print("update_auth ERROR")
            # 可以选择更新授权文件添加指纹，或者直接通过（向后兼容）
            # 这里选择向后兼容，只记录警告
            # 更新授权文件添加指纹
            # if update_auth_file_with_fingerprint(auth_info, current_fingerprint):
            #     print("信息: 已更新授权文件，添加环境指纹")
            # else:
            #     print("警告: 无法更新授权文件添加指纹")
            # print("警告: 旧版授权文件，缺少环境指纹信息")
        elif saved_fingerprint != current_fingerprint:
            # 环境指纹不匹配，删除授权文件并返回错误
            try:
                os.remove(file_path)
                return False, None, "检测到服务器环境变化，需要重新授权认证"
            except Exception as remove_error:
                return False, None, f"环境变化检测失败，需要重新授权认证: {str(remove_error)}"

        # 检查VIP等级
        vip_level = auth_info.get("vip_level_display", "")
        if not vip_level or "vip" not in vip_level.lower():
            return False, auth_info, "无效的VIP等级"

        if vip_level.lower() == "svip" or vip_level.lower() == "pvip":
            auth_info["expires_at"] = "永久有效"
        else:
            # 检查授权是否过期
            expires_at = auth_info.get("expires_at")
            if expires_at:
                try:
                    expires_time = datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
                    if datetime.now(expires_time.tzinfo) > expires_time:
                        return False, auth_info, "授权已过期"
                except Exception as e:
                    return False, auth_info, "授权时间格式错误"

        return True, auth_info, "授权有效"

    except Exception as e:
        return False, None, f"验证过程出错: {str(e)}"


def get_auth_status(request):
    """
    获取当前授权状态的API接口
    """
    is_valid, auth_info, message = validate_vip_auth()

    return JsonResponse(
        {
            "is_valid": is_valid,
            "message": message,
            "auth_info": auth_info if is_valid else None,
            "checked_at": datetime.now().isoformat(),
        }
    )


def update_auth_file_with_fingerprint(auth_info, current_fingerprint):
    """
    更新授权文件，添加环境指纹信息
    """
    try:
        # 添加环境指纹到授权信息
        auth_info["environment_fingerprint"] = current_fingerprint
        auth_info["fingerprint_updated"] = datetime.now().isoformat()

        # 重新加密并保存
        encryptor = AuthEncryptor(AES_KEY)
        encrypted_data = encryptor.encrypt(auth_info)

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

        return True
    except Exception as e:
        print(f"更新授权文件失败: {str(e)}")
        return False


@cache_decorator(timeout=None)
def should_continue_service():
    """
    判断是否继续提供服务
    返回: tuple (Boolean, str) - (是否继续服务, 服务级别)
    """
    try:
        # 构建授权文件路径
        file_path = djacore_auth_path

        # 检查授权文件是否存在
        if not os.path.exists(file_path):
            return False, "no_license_file"

        # 读取授权文件内容
        with open(file_path, "r", encoding="utf-8") as f:
            encrypted_data = f.read().strip()

        # 解密授权信息
        encryptor = AuthEncryptor(AES_KEY)
        auth_info = encryptor.decrypt(encrypted_data)

        if not auth_info:
            return False, "invalid_license"

        # 获取VIP等级信息
        vip_level = auth_info.get("vip_level", "").lower()
        vip_level_display = auth_info.get("vip_level_display", "").lower()

        # SVIP/PVIP用户：无限制服务
        if any(level in vip_level or level in vip_level_display for level in ["svip", "pvip"]):
            return True, "premium_vip"

        # VIP用户：检查有效期
        elif "vip" in vip_level or "vip" in vip_level_display:
            expires_at = auth_info.get("expires_at")
            if not expires_at:
                return False, "vip_no_expiry"

            try:
                expires_time = datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
                current_time = datetime.now(expires_time.tzinfo)

                if current_time <= expires_time:
                    return True, "vip_valid"
                else:
                    return False, "vip_expired"

            except Exception as e:
                return False, "vip_date_error"

        # 非VIP但已登录用户：基础服务
        elif auth_info.get("username"):
            return True, "basic_user"

        # 未授权用户
        else:
            return False, "unauthorized"

    except Exception as e:
        return False, f"error_{type(e).__name__}"


def apply_service_limits(apps_list, basic_user_limit=3):
    """
    根据服务状态应用应用数量限制

    参数:
        apps_list: 原始应用列表
        basic_user_limit: 基础用户的最大应用数量，默认为0

    返回:
        限制后的应用列表
    """
    has_service, service_level = should_continue_service()

    if not has_service:
        # 无服务权限，返回空列表
        return []

    # 根据服务级别应用不同限制[1,5](@ref)
    if service_level == "premium_vip":
        # SVIP/PVIP用户：无限制
        return apps_list
    elif service_level == "vip_valid":
        # VIP用户：无限制或较宽松限制
        return apps_list
    elif service_level == "basic_user":
        # 基础用户：有限数量应用
        limited_apps = apps_list[:basic_user_limit]
        return limited_apps
    else:
        # 其他情况返回空列表
        return []


def get_service_status_info():
    """
    获取当前服务状态的详细信息，用于前端显示
    """
    has_service, service_level = should_continue_service()

    status_info = {"has_service": has_service, "service_level": service_level, "message": ""}

    # 根据服务级别提供友好提示信息[2](@ref)
    messages = {
        "premium_vip": "尊享SVIP/PVIP无限制服务",
        "vip_valid": "VIP会员服务有效",
        "basic_user": "基础用户服务（功能受限）,仅可分别使用3个插件和3个应用",
        "vip_expired": "当前状态：VIP服务已过期，请联系开发者续费后方可使用该页面功能。",
        "unauthorized": "当前状态：未授权用户，请在管理首页更新授权。",
        "no_license_file": "当前状态：未检测到授权文件,不可使用该页面功能。请在管理首页更新授权后返回当前页面。",
        "invalid_license": "当前状态：授权文件无效,不可使用该页面功能。请在管理首页更新授权后返回当前页面。",
    }

    status_info["message"] = messages.get(service_level, "未知服务状态")
    return status_info
