import hmac
import hashlib
import base64
from cryptography.fernet import Fernet
from app.config import settings

def sign_payload(payload: str) -> str:
    """Signs a string payload using HMAC-SHA256."""
    return hmac.new(settings.SECRET_KEY.encode(), payload.encode(), hashlib.sha256).hexdigest()

def sign_bytes(data: bytes) -> str:
    """Signs bytes using HMAC-SHA256."""
    return hmac.new(settings.SECRET_KEY.encode(), data, hashlib.sha256).hexdigest()

def verify_signature(payload: str, signature: str) -> bool:
    """Verifies a signature against a payload using HMAC-SHA256."""
    expected = sign_payload(payload)
    return hmac.compare_digest(signature, expected)

def verify_bytes_signature(data: bytes, signature: str) -> bool:
    """Verifies a signature against bytes using HMAC-SHA256."""
    expected = sign_bytes(data)
    return hmac.compare_digest(signature, expected)

def get_fernet() -> Fernet:
    """Derives a Fernet key from the system SECRET_KEY."""
    key = base64.urlsafe_b64encode(hashlib.sha256(settings.SECRET_KEY.encode()).digest())
    return Fernet(key)

def encrypt_value(value: str) -> str:
    """Encrypts a string value and returns it with an ENC() wrapper."""
    if not value or value == "***": return value
    try:
        f = get_fernet()
        token = f.encrypt(value.encode()).decode()
        return f"ENC({token})"
    except Exception:
        return value

def decrypt_value(enc_value: str) -> str:
    """Decrypts a value if it is wrapped in ENC(), otherwise returns as-is."""
    if not isinstance(enc_value, str) or not enc_value.startswith("ENC("):
        return enc_value
    
    token = enc_value[4:-1]
    try:
        f = get_fernet()
        return f.decrypt(token.encode()).decode()
    except Exception:
        return enc_value
