"""Preferencias persistentes en settings.json, junto a los datos de la app."""

from __future__ import annotations

import json
from dataclasses import asdict, dataclass, field
from pathlib import Path

from .paths import writable_base

SETTINGS_NAME = "settings.json"

_THEMES = ("system", "light", "dark")


def _valid_theme(value) -> str:
    """Normaliza el tema a uno válido; cae a 'system' si es desconocido."""
    return value if value in _THEMES else "system"


_CONSOLE_MODES = ("show", "auto", "hide")


def _valid_console_mode(value) -> str:
    """Normaliza el modo de consola; cae a 'auto' si es desconocido."""
    return value if value in _CONSOLE_MODES else "auto"


@dataclass
class Settings:
    hide_not_downloaded: bool = False
    updates_pending: list[str] = field(default_factory=list)  # ids con update pendiente
    gitea_token: str = ""  # token personal de Gitea para repos privados (no se versiona)
    check_updates_on_start: bool = False  # comprobar updates automáticamente al iniciar
    theme: str = "system"  # tema de la UI: "system" | "light" | "dark"
    console_mode: str = "auto"  # consola de log: "show" | "auto" | "hide"
    # Tolerancia a repos offline/inalcanzables (segundos, salvo stall_limit en bytes/s).
    git_fetch_timeout: int = 60  # techo para fetch / comprobar update
    git_clone_timeout: int = 900  # techo para clone (repo grande)
    http_timeout: int = 15  # techo para la API de Gitea
    git_stall_limit: int = 1000  # bytes/s: por debajo se considera transferencia estancada
    git_stall_time: int = 20  # segundos estancado antes de abortar


def settings_path() -> Path:
    return writable_base() / SETTINGS_NAME


def load_settings() -> Settings:
    path = settings_path()
    if not path.exists():
        return Settings()
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
    except (OSError, json.JSONDecodeError):
        return Settings()
    return Settings(
        hide_not_downloaded=bool(data.get("hide_not_downloaded", False)),
        updates_pending=list(data.get("updates_pending", [])),
        gitea_token=str(data.get("gitea_token", "")),
        check_updates_on_start=bool(data.get("check_updates_on_start", False)),
        theme=_valid_theme(data.get("theme", "system")),
        console_mode=_valid_console_mode(data.get("console_mode", "auto")),
        git_fetch_timeout=int(data.get("git_fetch_timeout", 60)),
        git_clone_timeout=int(data.get("git_clone_timeout", 900)),
        http_timeout=int(data.get("http_timeout", 15)),
        git_stall_limit=int(data.get("git_stall_limit", 1000)),
        git_stall_time=int(data.get("git_stall_time", 20)),
    )


def save_settings(settings: Settings) -> None:
    try:
        settings_path().write_text(
            json.dumps(asdict(settings), ensure_ascii=False, indent=2),
            encoding="utf-8",
        )
    except OSError:
        pass
