"""
API Key 加密工具

提供 API Key 的加密和解密功能，使用 Fernet 对称加密算法。
主密钥从环境变量 MASTER_ENCRYPTION_KEY 读取。
"""

import os
import logging
from typing import Optional
from cryptography.fernet import Fernet, InvalidToken

logger = logging.getLogger(__name__)


class ApiKeyEncryption:
    """API Key 加密管理器"""

    _instance = None
    _cipher = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def _get_cipher(self) -> Fernet:
        """获取或初始化加密器"""
        if self._cipher is None:
            master_key = os.getenv("MASTER_ENCRYPTION_KEY")

            if not master_key:
                # 开发环境：生成一个临时密钥并警告
                if os.getenv("NODE_ENV", "development") == "development":
                    logger.warning(
                        "MASTER_ENCRYPTION_KEY not set, generating temporary key. "
                        "DO NOT USE IN PRODUCTION!"
                    )
                    # 生成一个 32 字节的 URL-safe base64 编码密钥
                    master_key = Fernet.generate_key().decode()
                    os.environ["MASTER_ENCRYPTION_KEY"] = master_key
                else:
                    raise ValueError(
                        "MASTER_ENCRYPTION_KEY must be set in production environment"
                    )

            # 确保密钥格式正确（Fernet 需要 32 字节 base64 编码的密钥）
            try:
                self._cipher = Fernet(master_key.encode())
            except Exception as e:
                raise ValueError(f"Invalid MASTER_ENCRYPTION_KEY format: {e}")

        return self._cipher

    def encrypt(self, api_key: str) -> str:
        """
        加密 API Key

        Args:
            api_key: 原始 API Key

        Returns:
            加密后的 API Key（base64 编码）
        """
        if not api_key:
            raise ValueError("API key cannot be empty")

        cipher = self._get_cipher()
        encrypted = cipher.encrypt(api_key.encode())
        return encrypted.decode()

    def decrypt(self, encrypted_key: str) -> str:
        """
        解密 API Key

        Args:
            encrypted_key: 加密的 API Key

        Returns:
            原始 API Key

        Raises:
            ValueError: 解密失败（密钥无效或已损坏）
        """
        if not encrypted_key:
            raise ValueError("Encrypted key cannot be empty")

        cipher = self._get_cipher()
        try:
            decrypted = cipher.decrypt(encrypted_key.encode())
            return decrypted.decode()
        except InvalidToken:
            raise ValueError("Invalid encrypted key or decryption failed")
        except Exception as e:
            raise ValueError(f"Decryption error: {e}")

    def mask_key(self, api_key: str, visible_chars: int = 4) -> str:
        """
        脱敏显示 API Key

        Args:
            api_key: 原始 API Key
            visible_chars: 末尾显示的字符数

        Returns:
            脱敏后的 API Key，如 "sk-***xxxx"
        """
        if not api_key:
            return ""

        if len(api_key) <= visible_chars + 3:
            return "***"

        # 保留前缀（如果有）和末尾几个字符
        prefix = ""
        if api_key.startswith("sk-"):
            prefix = "sk-"
            key_part = api_key[3:]
        else:
            key_part = api_key

        if len(key_part) <= visible_chars:
            return f"{prefix}***"

        masked = key_part[:3] + "***" + key_part[-visible_chars:]
        return prefix + masked


def generate_encryption_key() -> str:
    """
    生成新的加密密钥

    Returns:
        新的 Fernet 密钥（base64 编码）
    """
    return Fernet.generate_key().decode()


# 全局加密实例
crypto = ApiKeyEncryption()
