"""Role templates used to seed roles when an organization is created.

These are only starting points: after seeding, roles are ordinary DB rows that managers can
customise (within their delegation limits). Nothing in the code base checks role *names*;
all decisions go through permissions.
"""
from __future__ import annotations

from dataclasses import dataclass

from apps.modules.registry import all_permission_specs


@dataclass(frozen=True)
class RoleTemplate:
    code: str
    name: str
    kind: str  # "platform" | "customer"
    # permission code -> (scope, can_delegate); "*" expands to every grantable permission
    grants: tuple[tuple[str, str, bool], ...]


TEMPLATES: tuple[RoleTemplate, ...] = (
    RoleTemplate("super_admin", "مدیرکل", "platform", (("*", "all", True),)),
    RoleTemplate(
        "exec_manager",
        "مسئول اجرایی",
        "platform",
        tuple(
            (code, "assigned_organizations", False)
            for code in (
                "organizations.view",
                "members.view",
                "modules.view",
                "audit.view",
                "attendance.view",
                "attendance.report",
            )
        ),
    ),
    RoleTemplate(
        "specialist",
        "کارشناس",
        "platform",
        (("organizations.view", "assigned_organizations", False),),
    ),
    RoleTemplate("org_manager", "مدیر مجموعه", "customer", (("*", "organization", True),)),
    RoleTemplate(
        "employee",
        "پرسنل",
        "customer",
        (
            ("attendance.view", "self", False),
            ("attendance.create", "self", False),
        ),
    ),
)


def templates_for(kind: str) -> list[RoleTemplate]:
    return [t for t in TEMPLATES if t.kind == kind]


def expand_grants(template: RoleTemplate) -> dict[str, tuple[str, bool]]:
    specs = all_permission_specs()
    result: dict[str, tuple[str, bool]] = {}
    for code, scope, can_delegate in template.grants:
        if code == "*":
            for perm_code, (_module, perm) in specs.items():
                if template.kind == "customer" and perm.platform_only:
                    continue
                result[perm_code] = (scope, can_delegate)
        else:
            result[code] = (scope, can_delegate)
    return result
