import base64
import hashlib
import hmac
import json
import os
import time


TOKEN_TTL_SECONDS = int(os.getenv("ACCESS_TOKEN_EXPIRE_SECONDS", "28800"))


def _secret() -> bytes:
    return os.getenv("SECRET_KEY", "development-only-change-me").encode("utf-8")


def create_access_token(user_id: int, username: str, role: str) -> str:
    payload = {
        "sub": user_id,
        "username": username,
        "role": role,
        "exp": int(time.time()) + TOKEN_TTL_SECONDS,
    }
    raw = json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
    encoded = base64.urlsafe_b64encode(raw).rstrip(b"=")
    signature = hmac.new(_secret(), encoded, hashlib.sha256).digest()
    return f"{encoded.decode()}.{base64.urlsafe_b64encode(signature).rstrip(b'=').decode()}"


def verify_access_token(token: str) -> dict:
    try:
        encoded, supplied_signature = token.split(".", 1)
        expected = hmac.new(_secret(), encoded.encode("ascii"), hashlib.sha256).digest()
        signature = base64.urlsafe_b64decode(supplied_signature + "=" * (-len(supplied_signature) % 4))
        if not hmac.compare_digest(expected, signature):
            raise ValueError("invalid signature")
        raw = base64.urlsafe_b64decode(encoded + "=" * (-len(encoded) % 4))
        payload = json.loads(raw)
        if int(payload.get("exp", 0)) < int(time.time()):
            raise ValueError("expired token")
        return payload
    except (ValueError, TypeError, KeyError, json.JSONDecodeError) as exc:
        raise ValueError("无效或已过期的访问凭证") from exc


def validate_production_security() -> None:
    if os.getenv("APP_ENV", "development").lower() != "production":
        return
    secret = os.getenv("SECRET_KEY", "")
    initial_password = os.getenv("INITIAL_ADMIN_PASSWORD", "")
    if len(secret) < 32 or secret == "development-only-change-me":
        raise RuntimeError("生产环境 SECRET_KEY 必须是至少 32 位的随机密钥")
    if len(initial_password) < 12:
        raise RuntimeError("生产环境 INITIAL_ADMIN_PASSWORD 必须至少 12 位")
