"""Application user session and permission scaffolding for the warehouse app."""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import datetime
from typing import FrozenSet

from version_info import module_version

__version__ = module_version(__name__)

ALL_ACTIONS: FrozenSet[str] = frozenset(
    {
        "launcher.open_reset_corsie",
        "launcher.open_layout",
        "launcher.open_multi_udc",
        "launcher.open_search",
        "launcher.open_non_shelved",
        "launcher.open_history_udc",
        "launcher.open_pickinglist",
        "launcher.open_history_pickinglist",
        "launcher.arrange_windows",
        "launcher.exit",
        "reset_corsie.view",
        "search.view",
        "non_shelved.view",
        "history_udc.view",
        "history_pickinglist.view",
        "multi_udc.view",
        "layout.view",
        "layout.carico",
        "layout.scarico",
        "layout.prenota",
        "layout.libera_prenotazione",
        "layout.disabilita_cella",
        "layout.abilita_cella",
        "pickinglist.view",
        "pickinglist.prenota",
        "pickinglist.sprenota",
    }
)


def build_allowed_actions(_privilegio: int | None) -> FrozenSet[str]:
    """Return the currently enabled action set for the given operator profile.

    For this first iteration every authenticated operator can execute every
    function, but the explicit action map already exists so that a future admin
    UI can refine profiles without refactoring the whole application.
    """

    return ALL_ACTIONS


@dataclass(frozen=True)
class UserSession:
    """Minimal in-memory representation of one authenticated application user."""

    operator_id: int
    login: str
    nominativo: str
    privilegio: int | None = None
    codice_unita: str = ""
    session_started_at: datetime = field(default_factory=datetime.now)
    allowed_actions: FrozenSet[str] = field(default_factory=lambda: ALL_ACTIONS)

    def can(self, action: str) -> bool:
        """Return whether the current user can execute one named action."""

        return action in self.allowed_actions

    @property
    def display_name(self) -> str:
        """Return the best human-readable identity for the current session."""

        if str(self.nominativo or "").strip():
            return str(self.nominativo).strip()
        return str(self.login or "").strip()


def create_user_session(
    *,
    operator_id: int,
    login: str,
    nominativo: str,
    privilegio: int | None,
    codice_unita: str,
) -> UserSession:
    """Create one user session with the current default action set."""

    return UserSession(
        operator_id=int(operator_id),
        login=str(login or "").strip(),
        nominativo=str(nominativo or "").strip(),
        privilegio=int(privilegio) if privilegio is not None else None,
        codice_unita=str(codice_unita or "").strip(),
        allowed_actions=build_allowed_actions(privilegio),
    )
