"""Wallpaper-Verwaltung über waypaper (Backend swaybg). UI-frei.

Liest die waypaper-Config (~/.config/waypaper/config.ini), liefert den
Hintergrundordner, das aktuelle Bild, erkannte Monitore und die flache Liste
der Bilddateien. Setzen läuft über die waypaper-CLI (argv für ProcessRunner).

WICHTIG: Dieses Modul lädt NIEMALS Bilddaten — nur Pfade. Das Skalieren /
Rendern der Thumbnails passiert ausschließlich in der GUI (RAM-kontrolliert).
"""
from __future__ import annotations

import configparser
import os
import shutil
from pathlib import Path

_EXTS = {".jpg", ".jpeg", ".png", ".webp", ".bmp"}


def _config_path() -> Path:
    base = os.environ.get("XDG_CONFIG_HOME") or os.path.expanduser("~/.config")
    return Path(base) / "waypaper" / "config.ini"


def _expand(value: str) -> str:
    """`~` und Umgebungs-Tilde expandieren, Whitespace strippen."""
    return os.path.expanduser(value.strip())


def config() -> dict[str, str]:
    """Liest [Settings] aus der waypaper-Config. Defensiv: leeres dict bei Fehler.

    `folder`/`wallpaper` werden bei der weiteren Auswertung expandiert; hier
    bleiben die Rohwerte (mehrzeilige Werte wie `monitors`/`wallpaper` erhalten
    ihre Zeilenumbrüche).
    """
    path = _config_path()
    if not path.exists():
        return {}
    parser = configparser.ConfigParser()
    try:
        parser.read(path, encoding="utf-8")
    except (configparser.Error, OSError):
        return {}
    if not parser.has_section("Settings"):
        return {}
    out: dict[str, str] = {}
    for key in ("folder", "wallpaper", "backend", "monitors"):
        if parser.has_option("Settings", key):
            out[key] = parser.get("Settings", key)
    return out


def wallpaper_dir() -> Path:
    """Expandierter Hintergrundordner; Fallback ~/Pictures."""
    folder = config().get("folder", "").strip()
    if folder:
        return Path(_expand(folder))
    return Path(os.path.expanduser("~/Pictures"))


def set_folder(path: str) -> None:
    """Hintergrundordner in waypapers config.ini setzen (andere Keys bleiben)."""
    cfg_path = _config_path()
    parser = configparser.ConfigParser()
    try:
        if cfg_path.exists():
            parser.read(cfg_path, encoding="utf-8")
    except (configparser.Error, OSError):
        pass
    if not parser.has_section("Settings"):
        parser.add_section("Settings")
    parser.set("Settings", "folder", path)
    try:
        cfg_path.parent.mkdir(parents=True, exist_ok=True)
        with cfg_path.open("w", encoding="utf-8") as f:
            parser.write(f)
    except OSError:
        pass


def current() -> str:
    """Aktuell gesetztes Wallpaper (expandiert) oder "" wenn keiner.

    waypaper kann pro Monitor ein Bild speichern (mehrzeiliger Wert); wir nehmen
    die erste nicht-leere Zeile als „das" aktuelle Bild.
    """
    raw = config().get("wallpaper", "")
    for line in raw.splitlines():
        line = line.strip()
        if line:
            return _expand(line)
    return ""


def monitors() -> list[str]:
    """["All"] + erkannte Monitornamen aus dem (mehrzeiligen) monitors-Block."""
    out = ["All"]
    raw = config().get("monitors", "")
    for line in raw.splitlines():
        name = line.strip()
        if name and name != "All" and name not in out:
            out.append(name)
    return out


def list_wallpapers() -> list[Path]:
    """Bilddateien im wallpaper_dir (flach, case-insensitive), nach Name sortiert.

    Lädt KEINE Bilddaten — gibt nur Pfade zurück.
    """
    base = wallpaper_dir()
    try:
        entries = [
            p for p in base.iterdir()
            if p.is_file() and p.suffix.lower() in _EXTS
        ]
    except OSError:
        return []
    return sorted(entries, key=lambda p: p.name.lower())


def set_argv(path, monitor: str = "All") -> list[str]:
    argv = ["waypaper", "--wallpaper", str(path)]
    if monitor and monitor != "All":
        argv += ["--monitor", monitor]
    return argv


def random_argv() -> list[str]:
    return ["waypaper", "--random"]


def available() -> bool:
    return shutil.which("waypaper") is not None
