"""Service secrets — chiffrement Fernet pour credentials en base"""
import os
import base64
from cryptography.fernet import Fernet
from sqlalchemy import text
from ..config import SECRET_KEY

# Derive une cle Fernet 32 bytes depuis SECRET_KEY
_raw = SECRET_KEY.encode()[:32].ljust(32, b'\0')
_fernet_key = base64.urlsafe_b64encode(_raw)
_fernet = Fernet(_fernet_key)


def encrypt(value: str) -> str:
    return _fernet.encrypt(value.encode()).decode()


def decrypt(value: str) -> str:
    return _fernet.decrypt(value.encode()).decode()


def get_secret(db, key: str) -> str | None:
    """Recupere et dechiffre un secret depuis app_secrets"""
    row = db.execute(text("SELECT value FROM app_secrets WHERE key = :k"), {"k": key}).fetchone()
    if not row:
        return None
    try:
        return decrypt(row.value)
    except Exception:
        return None


def set_secret(db, key: str, value: str, description: str = ""):
    """Chiffre et stocke un secret dans app_secrets"""
    enc = encrypt(value)
    db.execute(text("""
        INSERT INTO app_secrets (key, value, description, updated_at)
        VALUES (:k, :v, :d, now())
        ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value,
            description = EXCLUDED.description, updated_at = now()
    """), {"k": key, "v": enc, "d": description})
    db.commit()


def list_secrets(db):
    """Liste les cles (sans valeurs) des secrets"""
    rows = db.execute(text(
        "SELECT key, description, updated_at FROM app_secrets ORDER BY key"
    )).fetchall()
    return rows


def init_secrets_from_config(db):
    """Initialise les secrets depuis config si pas encore en base"""
    from ..config import QUALYS_URL, QUALYS_USER, QUALYS_PASS
    defaults = {
        "qualys_url": (QUALYS_URL, "URL API Qualys"),
        "qualys_user": (QUALYS_USER, "Utilisateur Qualys"),
        "qualys_pass": (QUALYS_PASS, "Mot de passe Qualys"),
        "qualys_proxy": ("http://proxy.sanef.fr:8080", "Proxy Qualys"),
    }
    for key, (val, desc) in defaults.items():
        if val and not get_secret(db, key):
            set_secret(db, key, val, desc)
