# -*- coding: utf-8 -*-
"""VintedGo 授权码模块 — 生成 / 验证 / 存取 / 远程撤销"""

import os, hashlib, hmac, struct, time

SECRET_KEY = b"VintedGo@2026!SecretKey#X9"

# 撤销列表 URL — 部署网站后替换为你的实际地址
REVOKE_URL = ""

LICENSE_DIR = os.path.join(os.getenv("APPDATA", os.path.expanduser("~")), "VintedGo")
LICENSE_FILE = os.path.join(LICENSE_DIR, "license.dat")
LAST_CHECK_FILE = os.path.join(LICENSE_DIR, "last_check.dat")
CHECK_INTERVAL = 1  # 最长离线天数，超过则强制联网验证


def _hmac_sign(data: bytes) -> bytes:
    return hmac.digest(SECRET_KEY, data, hashlib.sha256)


def generate_license(expiry_date_str: str) -> str:
    """生成授权码。expiry_date_str 格式: '2026-12-31'"""
    from datetime import datetime
    expiry = datetime.strptime(expiry_date_str.strip(), "%Y-%m-%d")
    expiry_ts = int(expiry.timestamp())

    payload = struct.pack("!Q", expiry_ts)        # 8 字节
    sig = _hmac_sign(payload)[:12]                 # 取前 12 字节
    raw = payload + sig                            # 20 字节 = 40 hex 字符
    code = raw.hex().upper()

    # VINTEDGO-XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX
    groups = [code[i:i+8] for i in range(0, 40, 8)]
    return "VINTEDGO-" + "-".join(groups)


def validate_license(key: str):
    """验证授权码。返回 (valid: bool, days_left: int, error: str)"""
    try:
        key = key.strip().replace("-", "").replace("VINTEDGO", "", 1)
        if len(key) < 40:
            return False, 0, "授权码格式无效"

        raw = bytes.fromhex(key[:40])

        payload = raw[:8]
        sig = raw[8:20]

        expected_sig = _hmac_sign(payload)[:12]
        if not hmac.compare_digest(sig, expected_sig):
            return False, 0, "授权码校验失败"

        expiry_ts = struct.unpack("!Q", payload)[0]
        now = int(time.time())
        days_left = (expiry_ts - now) // 86400

        if days_left < 0:
            return False, days_left, "授权已过期"

        return True, days_left, ""
    except Exception as e:
        return False, 0, "授权码解析失败: " + str(e)[:60]


def load_license():
    """读取已保存的授权码"""
    try:
        if os.path.exists(LICENSE_FILE):
            with open(LICENSE_FILE, "r") as f:
                return f.read().strip()
    except Exception:
        pass
    return ""


def save_license(key: str):
    """保存授权码到本地"""
    os.makedirs(LICENSE_DIR, exist_ok=True)
    with open(LICENSE_FILE, "w") as f:
        f.write(key.strip())


def delete_license():
    """删除本地授权文件"""
    try:
        if os.path.exists(LICENSE_FILE):
            os.remove(LICENSE_FILE)
    except Exception:
        pass


def _save_last_check():
    """保存本次联网验证时间戳"""
    os.makedirs(LICENSE_DIR, exist_ok=True)
    with open(LAST_CHECK_FILE, "w") as f:
        f.write(str(int(time.time())))


def _load_last_check() -> int:
    """读取上次联网验证时间戳，无记录返回 0"""
    try:
        if os.path.exists(LAST_CHECK_FILE):
            with open(LAST_CHECK_FILE, "r") as f:
                return int(f.read().strip())
    except Exception:
        pass
    return 0


def need_online_check() -> bool:
    """是否需要强制联网验证（超过 CHECK_INTERVAL 天未联网）"""
    if not REVOKE_URL:
        return False
    last = _load_last_check()
    if last == 0:
        return False  # 首次激活，不强制
    return (int(time.time()) - last) > CHECK_INTERVAL * 86400


def check_revoked(key: str) -> bool:
    """联网检查授权码是否已被撤销。返回 True 表示已撤销。无网络时返回 False（放行）
    成功后更新最后验证时间戳"""
    if not REVOKE_URL:
        return False
    try:
        import urllib.request
        req = urllib.request.Request(REVOKE_URL, headers={"User-Agent": "VintedGo/1.0"})
        with urllib.request.urlopen(req, timeout=5) as resp:
            revoked_list = resp.read().decode("utf-8", errors="ignore")
        _save_last_check()  # 联网成功，更新时间戳
        for line in revoked_list.splitlines():
            if line.strip() == key.strip():
                return True
        return False
    except Exception:
        return False
