from __future__ import annotations

from pathlib import Path
from typing import Any

_CSS_PATH = Path(__file__).with_name("style.css")
_css_applied = False


def _load_gtk_modules() -> tuple[Any, Any] | None:
    try:
        import gi

        gi.require_version("Gtk", "3.0")
        gi.require_version("Gdk", "3.0")
        from gi.repository import Gdk, Gtk

        return Gtk, Gdk
    except Exception:
        return None


def apply_app_css(gtk_module: Any | None = None, gdk_module: Any | None = None) -> bool:
    """Load ui/style.css into one app-scoped CssProvider at APPLICATION priority.

    Idempotent. Returns False (no-op) headless/on failure.
    """
    global _css_applied
    if _css_applied:
        return True
    if gtk_module is None or gdk_module is None:
        loaded = _load_gtk_modules()
        if loaded is None:
            return False
        if gtk_module is None:
            gtk_module = loaded[0]
        if gdk_module is None:
            gdk_module = loaded[1]
    try:
        screen = gdk_module.Screen.get_default()
        if screen is None:
            return False
        provider = gtk_module.CssProvider()
        provider.load_from_path(str(_CSS_PATH))
        gtk_module.StyleContext.add_provider_for_screen(
            screen, provider, gtk_module.STYLE_PROVIDER_PRIORITY_APPLICATION
        )
    except Exception:
        return False
    _css_applied = True
    return True


def add_css_class(widget: Any, name: str) -> None:
    try:
        widget.get_style_context().add_class(name)
        return
    except Exception:
        pass
    classes = getattr(widget, "css_classes", None)
    if not isinstance(classes, list):
        classes = []
        widget.css_classes = classes
    if name not in classes:
        classes.append(name)


def remove_css_class(widget: Any, name: str) -> None:
    try:
        widget.get_style_context().remove_class(name)
        return
    except Exception:
        pass
    classes = getattr(widget, "css_classes", None)
    if isinstance(classes, list) and name in classes:
        classes.remove(name)


def apply_theme_class(widget: Any, resolved: str) -> None:
    """Ensure widget has exactly one of theme-light / theme-dark."""
    target = "theme-dark" if resolved == "dark" else "theme-light"
    other = "theme-light" if target == "theme-dark" else "theme-dark"
    remove_css_class(widget, other)
    add_css_class(widget, target)
