import json
import os
from pathlib import Path

from app.database import BASE_DIR
from app.permissions import verrouiller_fichier

CONFIG_PATH = BASE_DIR / "config.local.json"
DOSSIER_SAUVEGARDE_DEFAUT = BASE_DIR / "sauvegardes"
GOOGLE_TOKEN_PATH = BASE_DIR / "google_token.json"


def charger_configuration() -> dict:
    """Lit config.local.json (fichier local, non versionné). Absent = configuration par défaut."""
    if not CONFIG_PATH.exists():
        return {}
    try:
        return json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
    except (json.JSONDecodeError, OSError):
        return {}


def obtenir_dossier_sauvegarde() -> Path:
    """Dossier où sont écrites les sauvegardes. À pointer vers un dossier synchronisé par
    le client Google Drive local en définissant "dossier_sauvegarde" dans config.local.json."""
    chemin = charger_configuration().get("dossier_sauvegarde")
    return Path(chemin) if chemin else DOSSIER_SAUVEGARDE_DEFAUT


def definir_dossier_sauvegarde(chemin: str) -> None:
    """Enregistre le dossier de sauvegarde choisi (ex. un dossier Google Drive local)
    dans config.local.json (fichier local, non versionné)."""
    config = charger_configuration()
    config["dossier_sauvegarde"] = chemin
    CONFIG_PATH.write_text(json.dumps(config, ensure_ascii=False, indent=2), encoding="utf-8")
    verrouiller_fichier(CONFIG_PATH)


def obtenir_identifiants_google() -> tuple[str | None, str | None]:
    """Client ID / Client Secret OAuth Google (créés par l'utilisateur dans Google Cloud
    Console), enregistrés dans config.local.json (fichier local, non versionné)."""
    config = charger_configuration()
    return config.get("google_client_id"), config.get("google_client_secret")


def definir_identifiants_google(client_id: str, client_secret: str) -> None:
    config = charger_configuration()
    config["google_client_id"] = client_id
    config["google_client_secret"] = client_secret
    CONFIG_PATH.write_text(json.dumps(config, ensure_ascii=False, indent=2), encoding="utf-8")
    verrouiller_fichier(CONFIG_PATH)


def obtenir_jeton_google() -> dict:
    """Jeton Google Drive (refresh_token + email du compte connecté), stocké séparément
    de config.local.json dans un fichier dédié (même traitement que secret.key)."""
    if not GOOGLE_TOKEN_PATH.exists():
        return {}
    try:
        return json.loads(GOOGLE_TOKEN_PATH.read_text(encoding="utf-8"))
    except (json.JSONDecodeError, OSError):
        return {}


def definir_jeton_google(refresh_token: str, email: str) -> None:
    GOOGLE_TOKEN_PATH.write_text(
        json.dumps({"refresh_token": refresh_token, "email": email}, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    verrouiller_fichier(GOOGLE_TOKEN_PATH)


def supprimer_jeton_google() -> None:
    GOOGLE_TOKEN_PATH.unlink(missing_ok=True)


def detecter_dossiers_cloud() -> list[dict]:
    """Détecte les comptes cloud déjà connectés sur ce poste (Google Drive, Dropbox) via
    les applications de synchronisation déjà installées — aucun mot de passe requis,
    c'est l'appli officielle qui gère la connexion. Renvoie [{"service", "compte", "chemin"}]."""
    trouves = []

    for lettre in "DEFGHIJKLMNOPQRSTUVWXYZ":
        for nom in ("Mon Drive", "My Drive"):
            candidat = Path(f"{lettre}:/{nom}")
            if candidat.is_dir():
                trouves.append({"service": "Google Drive", "compte": f"lecteur {lettre}:", "chemin": str(candidat)})

    for base_env in ("LOCALAPPDATA", "APPDATA"):
        base = Path(os.environ.get(base_env, ""))
        info_path = base / "Dropbox" / "info.json"
        if info_path.is_file():
            try:
                info = json.loads(info_path.read_text(encoding="utf-8"))
            except (json.JSONDecodeError, OSError):
                continue
            for cle in ("personal", "business"):
                if cle in info and "path" in info[cle]:
                    trouves.append(
                        {"service": "Dropbox", "compte": cle, "chemin": info[cle]["path"]}
                    )
            break

    return trouves
