"""Razlike medu sustavima na jednom mjestu.

Kontrolni prozor je isti na Linuxu i na Windowsu. Razlikuje se samo ono ispod:
gdje stoji konfiguracija, kako se pokrece i gasi pozadinski proces, cime se
otvara poveznica i kako se program upisuje u autostart. Bez ovog modula bi ta
grananja bila razasuta po cijelom prozoru.
"""
from __future__ import annotations

import os
import shutil
import subprocess
import sys
from pathlib import Path

WINDOWS = sys.platform.startswith("win")

# Na Windowsu se pozadinski procesi pokrecu bez konzolnog prozora, inace svaki
# start agenta baci crni pravokutnik preko ekrana.
_BEZ_KONZOLE = 0x08000000 if WINDOWS else 0


def konfig_dir(ime: str) -> Path:
    """Isti direktorij koji koristi agent (`dirs::config_dir()` u Rustu)."""
    if WINDOWS:
        korijen = Path(os.environ.get("APPDATA", str(Path.home() / "AppData" / "Roaming")))
    else:
        korijen = Path(os.environ.get("XDG_CONFIG_HOME", str(Path.home() / ".config")))
    return korijen / ime


def izvrsni(ime: str) -> str:
    return f"{ime}.exe" if WINDOWS else ime


def nadji(ime: str, dodatni: list[Path] | None = None) -> Path | None:
    """Nadji binarij: prvo pokraj nas, pa na PATH-u."""
    imena = izvrsni(ime)
    mjesta: list[Path] = []
    if dodatni:
        mjesta.extend(dodatni)
    # U Windows paketu su exe datoteke iznad gui direktorija; koliko tocno
    # ovisi o rasporedu, pa se penjemo nekoliko razina.
    ovdje = Path(__file__).resolve().parent
    for razina in (ovdje, ovdje.parent, ovdje.parent.parent, ovdje.parent.parent.parent):
        mjesta.append(razina / imena)
    for p in mjesta:
        if p.exists():
            return p
    put = shutil.which(imena)
    return Path(put) if put else None


def pokreni_pozadinski(argv: list[str], env: dict | None = None) -> None:
    kwargs: dict = {
        "stdout": subprocess.DEVNULL,
        "stderr": subprocess.DEVNULL,
    }
    if env is not None:
        kwargs["env"] = env
    if WINDOWS:
        kwargs["creationflags"] = _BEZ_KONZOLE
    else:
        kwargs["start_new_session"] = True
    subprocess.Popen(argv, **kwargs)


def radi(ime: str) -> bool:
    """Vrti li se proces s ovim imenom."""
    try:
        if WINDOWS:
            out = subprocess.run(
                ["tasklist", "/FI", f"IMAGENAME eq {izvrsni(ime)}", "/NH"],
                capture_output=True,
                text=True,
                timeout=5,
                creationflags=_BEZ_KONZOLE,
            )
            return izvrsni(ime).lower() in (out.stdout or "").lower()
        return subprocess.run(["pgrep", "-x", ime], capture_output=True, timeout=2).returncode == 0
    except Exception:
        return False


def ugasi(*imena: str) -> None:
    for ime in imena:
        try:
            if WINDOWS:
                subprocess.run(
                    ["taskkill", "/F", "/IM", izvrsni(ime)],
                    capture_output=True,
                    timeout=10,
                    creationflags=_BEZ_KONZOLE,
                )
            else:
                subprocess.run(["pkill", "-x", ime], capture_output=True, timeout=10)
        except Exception:
            pass


def otvori_url(url: str) -> None:
    if WINDOWS:
        os.startfile(url)  # noqa: S606
    else:
        pokreni_pozadinski(["xdg-open", url])


def preglednik_app(url: str, razred: str) -> bool:
    """Otvori adresu kao zaseban prozor aplikacije. Vraca je li uspjelo."""
    if WINDOWS:
        kandidati = [
            Path(os.environ.get("PROGRAMFILES", "C:\\Program Files"))
            / "Google/Chrome/Application/chrome.exe",
            Path(os.environ.get("PROGRAMFILES(X86)", "C:\\Program Files (x86)"))
            / "Google/Chrome/Application/chrome.exe",
            Path(os.environ.get("PROGRAMFILES", "C:\\Program Files"))
            / "Microsoft/Edge/Application/msedge.exe",
            Path(os.environ.get("PROGRAMFILES(X86)", "C:\\Program Files (x86)"))
            / "Microsoft/Edge/Application/msedge.exe",
        ]
        for p in kandidati:
            if p.exists():
                pokreni_pozadinski([str(p), f"--app={url}"])
                return True
        return False
    for prog in ("google-chrome", "chromium", "chromium-browser", "brave-browser"):
        put = shutil.which(prog)
        if put:
            pokreni_pozadinski([put, f"--app={url}", f"--class={razred}"])
            return True
    return False


# ---------- autostart ----------

_RUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"


def autostart_ukljucen(ime: str, xdg_put: Path) -> bool:
    if WINDOWS:
        try:
            import winreg

            with winreg.OpenKey(winreg.HKEY_CURRENT_USER, _RUN_KEY) as k:
                winreg.QueryValueEx(k, ime)
                return True
        except Exception:
            return False
    return xdg_put.exists()


def autostart_postavi(ime: str, naredba: str, xdg_put: Path, xdg_sadrzaj: str, ukljuci: bool) -> None:
    if WINDOWS:
        try:
            import winreg

            with winreg.CreateKey(winreg.HKEY_CURRENT_USER, _RUN_KEY) as k:
                if ukljuci:
                    winreg.SetValueEx(k, ime, 0, winreg.REG_SZ, naredba)
                else:
                    try:
                        winreg.DeleteValue(k, ime)
                    except FileNotFoundError:
                        pass
        except Exception:
            pass
        return
    if ukljuci:
        xdg_put.parent.mkdir(parents=True, exist_ok=True)
        xdg_put.write_text(xdg_sadrzaj, encoding="utf-8")
    elif xdg_put.exists():
        xdg_put.unlink()
