#!/usr/bin/env python3
"""Edubuntu Menu Administration — main entry point."""

from __future__ import annotations

import os
import sys
from pathlib import Path

_pkg_dir = Path(__file__).resolve().parent
if str(_pkg_dir) not in sys.path:
    sys.path.insert(0, str(_pkg_dir))

from backend import (  # noqa: E402
    APP_TITLE,
    apply_global_hidden,
    apply_user_hidden,
    build_desktop_table,
    build_user_desktop_table,
    is_gnome_session,
    list_non_admin_users,
    query_user_hidden,
    reset_gnome_apps,
)
from ui.base import MenuAdminUI, ChecklistItem  # noqa: E402
from i18n import _  # noqa: E402


def _detect_toolkit() -> str:
    """Return 'qt' or 'gtk' based on the running desktop.

    Qt desktops:  KDE Plasma (Kubuntu), LXQt (Lubuntu)
    GTK desktops: GNOME (Ubuntu, Edubuntu), Xfce (Xubuntu),
                  MATE (Ubuntu MATE), Budgie (Ubuntu Budgie),
                  Cinnamon (Ubuntu Cinnamon), Unity (Ubuntu Unity)
    """
    desktop = os.environ.get("XDG_CURRENT_DESKTOP", "").lower()
    session = os.environ.get("DESKTOP_SESSION", "").lower()
    if any(tok in desktop for tok in ("kde", "plasma", "lxqt")):
        return "qt"
    if "plasma" in session or "lxqt" in session:
        return "qt"
    return "gtk"


def _create_ui() -> MenuAdminUI:
    preferred = _detect_toolkit()
    if preferred == "qt":
        try:
            from ui.qt_ui import QtUI
            ui = QtUI()
            ui.init()
            return ui
        except ImportError:
            pass
    try:
        from ui.gtk_ui import GtkUI
        ui = GtkUI()
        ui.init()
        return ui
    except ImportError:
        pass
    try:
        from ui.qt_ui import QtUI
        ui = QtUI()
        ui.init()
        return ui
    except ImportError:
        print(
            _("ERROR: Neither GTK 4 (python3-gi + gir1.2-adw-1) nor "
              "PyQt6 (python3-pyqt6) is available."),
            file=sys.stderr,
        )
        sys.exit(1)


def _gnome_apps_reset(ui: MenuAdminUI) -> None:
    if not is_gnome_session():
        ui.show_info(
            APP_TITLE,
            _("This tool is only relevant when running GNOME Shell."),
        )
        return

    confirmed = ui.show_question(
        APP_TITLE,
        _("This will reset any customizations to the GNOME application "
          "overview and the favorites in the Ubuntu Dock.\n\n"
          "This will also reorganize items installed by Edubuntu into "
          "application folders.\n\n"
          "Do you wish to proceed?"),
        ok_label=_("Yes"),
        cancel_label=_("No"),
    )
    if confirmed:
        if reset_gnome_apps():
            ui.show_info(
                APP_TITLE,
                _("Application overview and favorites have been reset."),
            )
        else:
            ui.show_error(
                APP_TITLE,
                _("Failed to reset the application overview."),
            )


def _main_loop(ui: MenuAdminUI) -> None:
    while True:
        table = [None]
        users = [[]]

        def _build():
            table[0] = build_desktop_table()
            users[0] = list_non_admin_users()

        ui.show_progress(APP_TITLE, _("Scanning applications…"), _build)

        desktop_table = table[0]
        if desktop_table is None or len(desktop_table) == 0:
            ui.show_error(APP_TITLE, _("No applications found."))
            return

        usernames = users[0]

        # Pre-query all users' hidden files in a single pkexec call
        # so the admin is only prompted for a password once.
        user_hidden = query_user_hidden(usernames) if usernames else {}

        global_items = [
            ChecklistItem(
                key=entry.filename,
                label=entry.filename,
                description=entry.display_name,
                checked=entry.hidden,
            )
            for entry in desktop_table
        ]

        def _per_user_items(
            username: str,
            globally_hidden: set[str],
        ) -> list[ChecklistItem]:
            user_table = build_user_desktop_table(
                username, hidden_files=user_hidden.get(username),
            )
            return [
                ChecklistItem(
                    key=e.filename,
                    label=e.filename,
                    description=(
                        e.display_name + "  (" + _("hidden globally") + ")"
                        if e.filename in globally_hidden
                        else e.display_name
                    ),
                    checked=e.hidden or e.filename in globally_hidden,
                    disabled=e.filename in globally_hidden,
                )
                for e in user_table
            ]

        result = ui.show_tabbed_checklist(
            APP_TITLE,
            _("Select applications to hide for non-administrator users"),
            global_items,
            usernames,
            _("Select applications to hide for this user"),
            _per_user_items,
            ok_label=_("Apply"),
            cancel_label=_("Close"),
            width=800,
            height=600,
        )

        if result is None:
            return

        global_selected, selected_user, user_selected = result

        ok = [False]

        def _do_apply():
            ok[0] = apply_global_hidden(global_selected)
            if selected_user and ok[0]:
                ok[0] = apply_user_hidden(selected_user, user_selected)

        ui.show_progress(APP_TITLE, _("Applying changes…"), _do_apply)

        if not ok[0]:
            ui.show_error(APP_TITLE, _("Failed to apply changes."))


def main() -> None:
    ui = _create_ui()

    prog = Path(sys.argv[0]).name
    if "gnome-apps-reset" in prog:
        _gnome_apps_reset(ui)
    else:
        _main_loop(ui)

    ui.quit()


if __name__ == "__main__":
    main()
