"""
Kela Logger - 简化版
只有两个接口：log_install() 和 log_data()
"""

import hashlib
import json
import time
import uuid
import os
import subprocess
import platform
import threading
from typing import Dict, Any

import requests

# 配置
_CONFIG_URL = "https://kela-agents.oss-ap-northeast-1.aliyuncs.com/config.json"
_SECRET_KEY = None  # 必须由主程序调用 init() 传入

# 运行时
_endpoint = None
_enabled = True
_initialized = False
_init_lock = threading.Lock()
_installation_id = None

# 调试模式
_debug = False


def _get_hardware_id() -> str:
    """获取硬件 ID：主板序列号 + 硬盘序列号 -> SHA256，失败则用保存的或生成新的UUID"""
    id_file = os.path.expanduser("~/.kela_id")

    # 尝试获取硬件ID
    hw_id = _try_get_hardware_id()
    if hw_id:
        return hw_id

    # 硬件ID获取失败，尝试读取本地保存的ID
    if os.path.exists(id_file):
        try:
            with open(id_file, "r") as f:
                saved_id = f.read().strip()
                if saved_id and len(saved_id) == 32:
                    return saved_id
        except:
            pass

    # 生成新的随机ID并保存
    new_id = str(uuid.uuid4()).replace("-", "")[:32]
    try:
        with open(id_file, "w") as f:
            f.write(new_id)
    except:
        pass

    return new_id


def _try_get_hardware_id() -> str:
    """尝试获取硬件ID，失败返回空字符串"""
    try:
        sys_name = platform.system()
        board_id = ""
        disk_id = ""

        if sys_name == "Windows":
            # 方法1: PowerShell
            try:
                result = subprocess.run(
                    ["powershell", "-Command", "(Get-WmiObject Win32_BaseBoard).SerialNumber"],
                    capture_output=True, text=True, timeout=10,
                    creationflags=subprocess.CREATE_NO_WINDOW
                )
                if result.returncode == 0:
                    board_id = result.stdout.strip()
            except:
                pass

            try:
                result = subprocess.run(
                    ["powershell", "-Command", "(Get-WmiObject Win32_DiskDrive | Select-Object -First 1).SerialNumber"],
                    capture_output=True, text=True, timeout=10,
                    creationflags=subprocess.CREATE_NO_WINDOW
                )
                if result.returncode == 0:
                    disk_id = result.stdout.strip()
            except:
                pass

            # 方法2: wmic（完整路径）
            if not board_id:
                try:
                    wmic_path = os.path.join(os.environ.get("SystemRoot", "C:\\Windows"), "System32", "wbem", "wmic.exe")
                    result = subprocess.run(
                        [wmic_path, "baseboard", "get", "serialnumber"],
                        capture_output=True, text=True, timeout=5,
                        creationflags=subprocess.CREATE_NO_WINDOW
                    )
                    lines = result.stdout.strip().split("\n")
                    if len(lines) > 1:
                        board_id = lines[1].strip()
                except:
                    pass

            if not disk_id:
                try:
                    wmic_path = os.path.join(os.environ.get("SystemRoot", "C:\\Windows"), "System32", "wbem", "wmic.exe")
                    result = subprocess.run(
                        [wmic_path, "diskdrive", "get", "serialnumber"],
                        capture_output=True, text=True, timeout=5,
                        creationflags=subprocess.CREATE_NO_WINDOW
                    )
                    lines = result.stdout.strip().split("\n")
                    if len(lines) > 1:
                        disk_id = lines[1].strip()
                except:
                    pass

        elif sys_name == "Linux":
            try:
                result = subprocess.run(
                    ["cat", "/sys/class/dmi/id/board_serial"],
                    capture_output=True, text=True, timeout=5
                )
                board_id = result.stdout.strip()
            except:
                pass

            try:
                result = subprocess.run(
                    ["lsblk", "-o", "SERIAL", "-n", "-d"],
                    capture_output=True, text=True, timeout=5
                )
                disk_id = result.stdout.strip().split("\n")[0]
            except:
                pass

        elif sys_name == "Darwin":
            try:
                result = subprocess.run(
                    ["system_profiler", "SPHardwareDataType"],
                    capture_output=True, text=True, timeout=5
                )
                for line in result.stdout.split("\n"):
                    if "Hardware UUID" in line:
                        board_id = line.split(":")[1].strip()
                        break
            except:
                pass

        combined = f"{board_id}:{disk_id}"
        if combined != ":":
            return hashlib.sha256(combined.encode()).hexdigest()[:32]
    except:
        pass

    return ""


def _init():
    """初始化：获取远程配置和硬件ID"""
    global _endpoint, _enabled, _initialized, _installation_id

    if _initialized:
        return

    with _init_lock:
        if _initialized:
            return

        # 获取远程配置
        try:
            resp = requests.get(_CONFIG_URL, timeout=5)
            if resp.status_code == 200:
                data = resp.json()
                _endpoint = data.get("endpoint")
                _enabled = data.get("enabled", True)
        except:
            pass

        # 获取硬件ID
        _installation_id = _get_hardware_id()
        _initialized = True


def _checksum(ts: int) -> str:
    """生成校验值: sha256(timestamp + secret)"""
    return hashlib.sha256(f"{ts}{_SECRET_KEY}".encode()).hexdigest()


def init(secret_key: str):
    """
    初始化 logger，必须在调用 log_install/log_data 之前调用

    Args:
        secret_key: 校验密钥（由主程序提供）
    """
    global _SECRET_KEY
    _SECRET_KEY = secret_key


def set_debug(enabled: bool):
    """开启/关闭调试模式"""
    global _debug
    _debug = enabled


def get_installation_id() -> str:
    """获取安装ID"""
    _init()
    return _installation_id


# ========== 内部请求函数 ==========

def _do_request(payload: dict):
    """执行请求（在后台线程中运行，包含初始化）"""
    global _endpoint, _enabled, _initialized, _installation_id

    # 检查是否已调用 init()
    if not _SECRET_KEY:
        if _debug:
            print("[DEBUG] Request skipped: init() not called, secret_key not set")
        return

    # 在后台线程中初始化
    if not _initialized:
        with _init_lock:
            if not _initialized:
                try:
                    resp = requests.get(_CONFIG_URL, timeout=5)
                    if resp.status_code == 200:
                        data = resp.json()
                        _endpoint = data.get("endpoint")
                        _enabled = data.get("enabled", True)
                except:
                    pass
                _installation_id = _get_hardware_id()
                _initialized = True

    if not _enabled or not _endpoint:
        if _debug:
            print(f"[DEBUG] Request skipped: enabled={_enabled}, endpoint={_endpoint}")
        return

    # 更新 payload 中的 installation_id（因为初始化可能刚完成）
    payload["installation_id"] = _installation_id

    try:
        if _debug:
            print(f"[DEBUG] POST {_endpoint}")
            print(f"[DEBUG] Payload: {payload}")

        resp = requests.post(_endpoint, json=payload, timeout=5)

        if _debug:
            print(f"[DEBUG] Response: {resp.status_code} {resp.text}")
    except Exception as e:
        if _debug:
            print(f"[DEBUG] Request failed: {e}")


# ========== 对外暴露的接口 ==========

def log_install():
    """
    上报安装事件（异步非阻塞）
    """
    ts = int(time.time())
    payload = {
        "timestamp": ts,
        "checksum": _checksum(ts),
        "installation_id": None,  # 在后台线程中填充
        "type": "install",
    }

    threading.Thread(target=_do_request, args=(payload,), daemon=True).start()


def log_data(data: Dict[str, Any]):
    """
    上报全部数据（异步非阻塞）

    Args:
        data: {
            "workspace_count": int,
            "chat_count": int,
            "excel_count": int,
            "field_count": int,
            "tool_usage": {"tool_name": count, ...}
        }
    """
    ts = int(time.time())
    payload = {
        "timestamp": ts,
        "checksum": _checksum(ts),
        "installation_id": None,  # 在后台线程中填充
        "type": "data",
        "workspace_count": data.get("workspace_count", 0),
        "chat_count": data.get("chat_count", 0),
        "excel_count": data.get("excel_count", 0),
        "field_count": data.get("field_count", 0),
        "tool_usage": json.dumps(data.get("tool_usage", {})),
    }

    threading.Thread(target=_do_request, args=(payload,), daemon=True).start()
