"""
加密工具类 - 用于加密/解密敏感信息
支持字段级加密，用于保护收货人信息等隐私数据
"""

from cryptography.fernet import Fernet
import os
import logging

logger = logging.getLogger(__name__)


class EncryptionService:
    """加密/解密服务"""

    def __init__(self):
        """初始化加密服务"""
        # 环境判断
        is_production = os.getenv("ENV", "development").lower() == "production"

        # 从环境变量获取密钥
        encryption_key = os.getenv('ENCRYPTION_KEY')

        if encryption_key:
            self.key = encryption_key.encode() if isinstance(encryption_key, str) else encryption_key
            logger.info("Encryption service initialized with configured key")
        elif is_production:
            # 生产环境必须配置密钥
            raise ValueError(
                "CRITICAL SECURITY ERROR: ENCRYPTION_KEY environment variable is required in production! "
                "Generate one with: python -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\""
            )
        else:
            # 开发环境使用临时密钥（不记录密钥值）
            self.key = Fernet.generate_key()
            logger.warning(
                "ENCRYPTION_KEY not configured - using temporary key. "
                "Data encrypted in this session cannot be decrypted after restart. "
                "DO NOT USE IN PRODUCTION!"
            )

        self.cipher = Fernet(self.key)

    def encrypt(self, plaintext: str) -> str:
        """
        加密字符串

        Args:
            plaintext: 明文字符串

        Returns:
            加密后的密文字符串（可直接存储到数据库）
        """
        if not plaintext:
            return None

        try:
            ciphertext = self.cipher.encrypt(plaintext.encode('utf-8'))
            return ciphertext.decode('utf-8')
        except Exception as e:
            logger.error(f"加密失败: {str(e)}")
            raise

    def decrypt(self, ciphertext: str) -> str:
        """
        解密字符串

        Args:
            ciphertext: 密文字符串

        Returns:
            解密后的明文字符串
        """
        if not ciphertext:
            return None

        try:
            plaintext = self.cipher.decrypt(ciphertext.encode('utf-8'))
            return plaintext.decode('utf-8')
        except Exception as e:
            logger.error(f"解密失败: {str(e)}")
            raise

    @staticmethod
    def mask_phone(phone: str) -> str:
        """
        手机号脱敏处理
        示例: 13812345678 -> 138****5678

        Args:
            phone: 完整手机号

        Returns:
            脱敏后的手机号
        """
        if not phone:
            return phone

        phone = str(phone).strip()
        if len(phone) < 7:
            return phone

        return f"{phone[:3]}****{phone[-4:]}"

    @staticmethod
    def mask_address(address: str, show_chars: int = 20) -> str:
        """
        地址脱敏处理
        示例: 广东省珠海市香洲区梅华街道... -> 广东省珠海市香洲区梅华街...

        Args:
            address: 完整地址
            show_chars: 显示的字符数

        Returns:
            脱敏后的地址
        """
        if not address:
            return address

        address = str(address).strip()
        if len(address) <= show_chars:
            return address

        return address[:show_chars] + "***"

    @staticmethod
    def mask_name(name: str) -> str:
        """
        收货人姓名脱敏处理
        示例: 张三 -> 张* 或 张三丰 -> 张*丰

        Args:
            name: 完整姓名

        Returns:
            脱敏后的姓名
        """
        if not name:
            return name

        name = str(name).strip()
        if len(name) <= 1:
            return name
        elif len(name) == 2:
            return f"{name[0]}*"
        else:
            return f"{name[0]}{'*' * (len(name) - 2)}{name[-1]}"


# 全局加密服务实例
_encryption_service = None


def get_encryption_service() -> EncryptionService:
    """获取全局加密服务实例（单例）"""
    global _encryption_service
    if _encryption_service is None:
        _encryption_service = EncryptionService()
    return _encryption_service
