"""The R1 capability truth tables AS DATA (02-domain-model §4;
rpcs-and-authz §5; 06-test-plan §4.1 T-AZ-001).

The parity contract, verbatim from the current app's EFFECTIVE
enforcement:

| capability         | super-admin¬viewing | owner | manager | worker | none |
|--------------------|---------------------|-------|---------|--------|------|
| can_transfer       | T                   | T     | F       | F      | F    |
| can_see_income     | T                   | T     | F       | F      | F    |
| can_manage_imports | T                   | T     | T       | F      | F    |
| can_manage_team    | T                   | T     | F*      | F      | F    |
| can_enter_view_as  | T                   | F     | F       | F      | F    |

* can_manage_team encodes the EFFECTIVE rule (team owner OR org owner
  OR super admin) at the tenant level — NOT the dead `canManageTeam`
  function's any-manager grant (rpcs §5, binding). Per-team-owner
  grants are resource-scoped and land with the team feature (R2).

Lock-aware entry editing (rpcs §5 canEditEntry):
  locked  (attached to an invoice line) -> can_transfer
  unlocked                              -> can_manage_imports

View-as strips super-admin power (the `is_super_admin && !is_viewing_as`
idiom): while impersonating ANYONE — including another super admin —
only the target's derived role counts, and view-as never nests.
"""

from __future__ import annotations

#: role -> grant, per capability. Roles are the R1 derivation of
#: 02 §4: owner (official_partnership), manager (subcontract with the
#: can_manage_imports grant), worker (plain subcontract), none.
ROLE_GRANTS: dict[str, dict[str, bool]] = {
    "can_transfer": {"owner": True, "manager": False, "worker": False, "none": False},
    "can_see_income": {"owner": True, "manager": False, "worker": False, "none": False},
    "can_manage_imports": {
        "owner": True,
        "manager": True,
        "worker": False,
        "none": False,
    },
    "can_manage_team": {"owner": True, "manager": False, "worker": False, "none": False},
    # never role-derived: super-admin only, and never while viewing-as
    "can_enter_view_as": {
        "owner": False,
        "manager": False,
        "worker": False,
        "none": False,
    },
}

CAPABILITIES: tuple[str, ...] = tuple(ROLE_GRANTS)

ROLES: tuple[str, ...] = ("owner", "manager", "worker", "none")


def capability_allowed(
    capability: str,
    *,
    role: str,
    is_super_admin: bool,
    is_viewing_as: bool,
) -> bool:
    """Evaluate one cell of the truth table.

    `is_super_admin` is the EFFECTIVE user's flag; the `not
    is_viewing_as` clause strips super-admin power while impersonating
    (rpcs §5 — the foot-gun made explicit).
    """
    grants = ROLE_GRANTS[capability]  # KeyError = programming error, loud
    if is_super_admin and not is_viewing_as:
        return True
    return grants.get(role, False)


def edit_entry_capability(locked: bool) -> str:
    """The lock-aware capability for editing one entry (rpcs §5):
    invoice-locked rows need can_transfer, unlocked rows
    can_manage_imports. (No mutations exist in M3 — used by can() and
    the grid tests so the rule is pinned before writes land.)"""
    return "can_transfer" if locked else "can_manage_imports"
