"""Abstract UI for Edubuntu Menu Administration."""

from __future__ import annotations

from abc import ABC, abstractmethod
from collections.abc import Callable
from dataclasses import dataclass


@dataclass
class ChecklistItem:
    key: str
    label: str
    description: str
    checked: bool = False
    disabled: bool = False


class MenuAdminUI(ABC):

    @abstractmethod
    def show_info(self, title: str, text: str) -> None: ...

    @abstractmethod
    def show_error(self, title: str, text: str) -> None: ...

    @abstractmethod
    def show_question(
        self,
        title: str,
        text: str,
        ok_label: str = "Yes",
        cancel_label: str = "No",
    ) -> bool: ...

    @abstractmethod
    def show_checklist(
        self,
        title: str,
        text: str,
        items: list[ChecklistItem],
        ok_label: str = "OK",
        cancel_label: str = "Cancel",
        width: int = 0,
        height: int = 0,
    ) -> list[str] | None: ...

    @abstractmethod
    def show_tabbed_checklist(
        self,
        title: str,
        global_text: str,
        global_items: list[ChecklistItem],
        usernames: list[str],
        per_user_text: str,
        per_user_items_fn: Callable[[str, set[str]], list[ChecklistItem]],
        ok_label: str = "OK",
        cancel_label: str = "Cancel",
        width: int = 0,
        height: int = 0,
    ) -> tuple[list[str], str, list[str]] | None:
        """Two-tab dialog: Global and Per-User.

        *per_user_items_fn(username, globally_hidden_keys)* is called
        each time the Per-User tab is shown or the user dropdown changes.
        The second argument is the live set of keys currently checked on
        the Global tab.

        Returns ``(global_checked, username, per_user_checked)`` or
        ``None`` if cancelled.
        """

    @abstractmethod
    def show_progress(
        self,
        title: str,
        text: str,
        callback: Callable[[], None],
    ) -> bool: ...

    @abstractmethod
    def init(self) -> None: ...

    @abstractmethod
    def quit(self) -> None: ...
