"""Kernel — installierte Kernel, installierbare Alternativen, Bootloader."""
from __future__ import annotations

import gi

gi.require_version("Adw", "1")
from gi.repository import Adw, GLib, Gtk  # noqa: E402

from taninux.core import bootloader, pacman, sysinfo
from taninux.gui.console import LogConsole, log_expander
from taninux.gui.process import ProcessRunner

# Paketname → Anzeigename
KNOWN_KERNELS: dict[str, str] = {
    "linux": "Linux (stable)",
    "linux-lts": "Linux LTS (longterm)",
    "linux-zen": "Linux Zen (desktop-tuned)",
    "linux-hardened": "Linux Hardened (security)",
    "linux-rt": "Linux RT (realtime)",
    "linux-rt-lts": "Linux RT LTS (realtime longterm)",
}


def _is_running(pkg: str, running: str) -> bool:
    suffix = pkg.removeprefix("linux").lstrip("-")
    tag = "-".join(running.split("-")[1:]) if "-" in running else ""
    return (pkg == "linux" and not tag) or (bool(suffix) and suffix in running)


def build() -> Gtk.Widget:
    page = Adw.PreferencesPage()
    console = LogConsole()
    runner = ProcessRunner()
    runner.connect("line", lambda _r, line: console.append_line(line))
    groups: list[Adw.PreferencesGroup] = []
    log_group = log_expander(console)

    def _install(pkg: str, btn: Gtk.Button) -> None:
        btn.set_sensitive(False)
        btn.set_label("Installing…")
        console.clear()
        runner.run(["pacman", "-S", "--needed", "--noconfirm", pkg, f"{pkg}-headers"],
                   privileged=True)

    def _set_default(bl, combo: Adw.ComboRow, btn: Gtk.Button) -> None:
        idx = combo.get_selected()
        if not (0 <= idx < len(bl.entries)):
            return
        argv = bootloader.set_default_argv(bl, bl.entries[idx])
        if not argv:
            console.append_line("⚠ not supported for this bootloader")
            return
        btn.set_sensitive(False)
        console.clear()
        runner.run(argv, privileged=True)

    def _render() -> None:
        for g in groups:
            page.remove(g)
        groups.clear()
        page.remove(log_group)

        installed = pacman.installed_packages()
        running = sysinfo.kernel_release()

        g_inst = Adw.PreferencesGroup(title="Installed kernels",
                                      description=f"Running: {running}")
        any_inst = False
        for pkg, label in KNOWN_KERNELS.items():
            if pkg in installed:
                any_inst = True
                row = Adw.ActionRow(title=label, subtitle=pkg)
                if _is_running(pkg, running):
                    badge = Gtk.Label(label="active")
                    badge.add_css_class("success")
                    badge.add_css_class("caption-heading")
                    badge.set_valign(Gtk.Align.CENTER)
                    row.add_suffix(badge)
                g_inst.add(row)
        if not any_inst:
            g_inst.add(Adw.ActionRow(title="No known kernel packages found"))
        page.add(g_inst)
        groups.append(g_inst)

        available = [(p, l) for p, l in KNOWN_KERNELS.items() if p not in installed]
        if available:
            g_avail = Adw.PreferencesGroup(title="Available to install")
            for pkg, label in available:
                row = Adw.ActionRow(title=label, subtitle=f"{pkg} · {pkg}-headers")
                btn = Gtk.Button(label="Install")
                btn.add_css_class("suggested-action")
                btn.set_valign(Gtk.Align.CENTER)
                btn.connect("clicked", lambda _b, p=pkg: _install(p, _b))
                row.add_suffix(btn)
                g_avail.add(row)
            page.add(g_avail)
            groups.append(g_avail)

        bl = bootloader.detect()
        g_boot = Adw.PreferencesGroup(title="Bootloader")
        g_boot.add(_static_row("Type", bl.kind))
        g_boot.add(_static_row("Default entry", bl.default_entry or "—"))
        if bl.kind == "systemd-boot" and bl.entries:
            combo = Adw.ComboRow(title="Default boot entry",
                                 model=Gtk.StringList.new([e.name for e in bl.entries]))
            for i, e in enumerate(bl.entries):
                if bootloader.is_default(bl, e):
                    combo.set_selected(i)
                    break
            btn = Gtk.Button(label="Set")
            btn.add_css_class("suggested-action")
            btn.set_valign(Gtk.Align.CENTER)
            btn.connect("clicked", lambda _b, c=combo: _set_default(bl, c, _b))
            combo.add_suffix(btn)
            g_boot.add(combo)
        page.add(g_boot)
        groups.append(g_boot)

        page.add(log_group)

    def on_done(_r: ProcessRunner, code: int) -> None:
        console.append_line("✔ done" if code == 0 else f"✘ exit {code}")
        pacman.invalidate()
        _render()

    runner.connect("done", on_done)
    page.add(log_group)
    GLib.idle_add(lambda: (_render(), False)[1])
    return page


def _static_row(title: str, value: str) -> Adw.ActionRow:
    row = Adw.ActionRow(title=title)
    label = Gtk.Label(label=value)
    label.add_css_class("dim-label")
    label.set_selectable(True)
    row.add_suffix(label)
    return row
