"""Hauptfenster: Sidebar (Pillar-Liste) + Content-Stack.

Adw.NavigationSplitView gibt das responsive Sidebar/Content-Layout, das man
von GNOME-Settings kennt — auf schmalen Fenstern klappt es automatisch zu
einer Drill-Down-Navigation um.
"""
from __future__ import annotations

import gi

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

from taninux.gui.pages import SECTIONS


class MainWindow(Adw.ApplicationWindow):
    def __init__(self, app: Adw.Application, sections=None, title: str = "TANINUX") -> None:
        super().__init__(application=app, title=title)
        self.set_default_size(960, 680)

        self._sections = sections if sections is not None else SECTIONS
        self._pages = [p for s in self._sections for p in s.pages]
        self._app_title = title
        self._stack = Gtk.Stack()
        self._stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self._title = Adw.WindowTitle(title=title)
        self._rows: dict[str, Gtk.ListBoxRow] = {}
        self._query = ""

        split = Adw.NavigationSplitView()
        split.set_sidebar(self._build_sidebar())
        split.set_content(self._build_content())
        self.set_content(split)

        # lazy: Seiten erst beim ersten Anzeigen bauen; Startseite vorwählen
        self._built: set[str] = set()
        if self._pages:
            self._listbox.select_row(self._rows[self._pages[0].key])

    # -- Sidebar -------------------------------------------------------

    def _build_sidebar(self) -> Adw.NavigationPage:
        self._listbox = Gtk.ListBox()
        self._listbox.add_css_class("navigation-sidebar")
        self._listbox.set_selection_mode(Gtk.SelectionMode.SINGLE)
        self._listbox.connect("row-selected", self._on_row_selected)
        self._listbox.set_filter_func(self._filter_row)

        for section in self._sections:
            if section.title:
                self._listbox.append(self._header_row(section.title))
            for page in section.pages:
                row = Gtk.ListBoxRow()
                row._page = page  # type: ignore[attr-defined]
                box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
                box.set_margin_top(10)
                box.set_margin_bottom(10)
                box.set_margin_start(8)
                box.set_margin_end(8)
                box.append(Gtk.Image.new_from_icon_name(page.icon))
                box.append(Gtk.Label(label=page.label, xalign=0.0))
                row.set_child(box)
                self._rows[page.key] = row
                self._listbox.append(row)

        scroller = Gtk.ScrolledWindow(vexpand=True)
        scroller.set_child(self._listbox)

        search = Gtk.SearchEntry()
        search.set_placeholder_text("Search settings")
        search.set_margin_top(6)
        search.set_margin_bottom(6)
        search.set_margin_start(6)
        search.set_margin_end(6)
        search.connect("search-changed", self._on_search)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        box.append(search)
        box.append(scroller)

        toolbar = Adw.ToolbarView()
        toolbar.add_top_bar(Adw.HeaderBar())
        toolbar.set_content(box)

        nav = Adw.NavigationPage(title=self._app_title, child=toolbar)
        nav.set_tag("sidebar")
        return nav

    def _header_row(self, title: str) -> Gtk.ListBoxRow:
        """Nicht-wählbare Sektions-Überschrift."""
        row = Gtk.ListBoxRow()
        row.set_selectable(False)
        row.set_activatable(False)
        label = Gtk.Label(label=title, xalign=0.0)
        label.add_css_class("dim-label")
        label.add_css_class("caption-heading")
        label.set_margin_top(14)
        label.set_margin_bottom(2)
        label.set_margin_start(12)
        row.set_child(label)
        return row

    # -- Content -------------------------------------------------------

    def _build_content(self) -> Adw.NavigationPage:
        toolbar = Adw.ToolbarView()
        header = Adw.HeaderBar()
        header.set_title_widget(self._title)
        toolbar.add_top_bar(header)
        toolbar.set_content(self._stack)
        nav = Adw.NavigationPage(title="Content", child=toolbar)
        nav.set_tag("content")
        return nav

    # -- Suche ---------------------------------------------------------

    def _on_search(self, entry: Gtk.SearchEntry) -> None:
        self._query = entry.get_text().strip().lower()
        self._listbox.invalidate_filter()

    def _filter_row(self, row: Gtk.ListBoxRow) -> bool:
        page = getattr(row, "_page", None)
        if page is None:                       # Sektions-Header
            return not self._query
        if not self._query:
            return True
        hay = (page.label + " " + " ".join(page.keywords)).lower()
        return self._query in hay

    # -- Navigation ----------------------------------------------------

    def _on_row_selected(self, _box: Gtk.ListBox, row: Gtk.ListBoxRow | None) -> None:
        page = getattr(row, "_page", None) if row is not None else None
        if page is not None:
            self._select(page)

    def _select(self, page) -> None:
        if page.key not in self._built:
            self._stack.add_named(page.build(), page.key)
            self._built.add(page.key)
        self._stack.set_visible_child_name(page.key)
        self._title.set_title(page.label)
