"""admin 后台「页面权限目录」—— RBAC 的权限侧单一真源。

一个权限 = 一个页面(= 左侧导航项)。角色持有一组 page key,登录后左侧只展示这些页(见前端
layout.tsx 按 pages 过滤导航)。key 必须与前端路由一级对齐(/dashboard → "dashboard")。

super_admin 为内建全权角色,恒可见全部页(effective_pages 特判)。新增页面 = 这里加一条 +
前端导航加对应项(key 一致即可被各角色勾选可见)。
"""
from __future__ import annotations

SUPER_ADMIN_ROLE = "super_admin"
# 「自定义」哨兵角色:不是 admin_role 表里的行,而是标记「这个人的可见页由 pages_override 决定」。
# admin_user.role == CUSTOM_ROLE 时,有效可见页取 admin_user.pages_override(见 auth._admin_out_with_pages)。
CUSTOM_ROLE = "custom"

# 分组镜像前端导航(app/(main)/layout.tsx 的 NAV_GROUPS);key = 路由一级
PERMISSION_CATALOG: list[dict] = [
    {"group": "看板", "pages": [
        {"key": "dashboard", "label": "数据大盘"},
        {"key": "coupon-data", "label": "领券数据"},
        {"key": "ad-revenue-report", "label": "广告收益"},
        {"key": "comparison-records", "label": "比价记录"},
        {"key": "cps", "label": "CPS收益"},
    ]},
    {"group": "奖励审核", "pages": [
        {"key": "invite-withdraws", "label": "邀请提现审核"},
        {"key": "withdraws", "label": "其他提现审核"},
        {"key": "price-reports", "label": "低价审核"},
        {"key": "feedbacks", "label": "用户反馈"},
    ]},
    {"group": "数据配置", "pages": [
        {"key": "config", "label": "系统配置"},
        {"key": "ad-revenue", "label": "广告配置"},
        {"key": "huawei-review", "label": "华为审核开关"},
        {"key": "users", "label": "用户管理"},
    ]},
    {"group": "监控审计", "pages": [
        {"key": "risk-monitor", "label": "风控监控"},
        {"key": "device-liveness", "label": "设备存活"},
        {"key": "analytics-health", "label": "埋点成功率"},
        {"key": "event-logs", "label": "埋点日志"},
        {"key": "audit-logs", "label": "审计日志"},
    ]},
    {"group": "其他", "pages": [
        {"key": "admins", "label": "权限管理"},
    ]},
]

# 全部页面 key(super_admin 有效可见 = 此全集;也用于校验角色 pages 合法性)
ALL_PAGE_KEYS: list[str] = [p["key"] for g in PERMISSION_CATALOG for p in g["pages"]]
_ALL_SET = set(ALL_PAGE_KEYS)

# 内建角色定义(种子 / ensure 兜底的单一真源):(key, 中文展示名, 默认可见页)。
# 页集对齐 Prototypes/dashboard/permissions.md 的 ROLES;super_admin 恒全权(pages 空、bypass)。
# key 承重(require_role / admin_user.role),勿改;label 为 UI 展示名。
BUILTIN_ROLES: list[dict] = [
    {"name": SUPER_ADMIN_ROLE, "label": "管理员", "pages": []},
    {"name": "operator", "label": "运营", "pages": [
        "dashboard", "coupon-data", "ad-revenue-report", "comparison-records",
        "cps", "risk-monitor", "device-liveness", "price-reports", "feedbacks", "huawei-review",
    ]},
    {"name": "finance", "label": "财务", "pages": [
        "dashboard", "ad-revenue-report", "cps", "invite-withdraws", "withdraws",
    ]},
    {"name": "tech", "label": "技术", "pages": [
        "dashboard", "risk-monitor", "device-liveness", "analytics-health", "config", "ad-revenue", "huawei-review",
        "event-logs", "audit-logs",
    ]},
]

# 内建 key → 中文展示名(展示 / 自愈用)
BUILTIN_LABELS: dict[str, str] = {r["name"]: r["label"] for r in BUILTIN_ROLES}


def sanitize_pages(pages: list[str] | None) -> list[str]:
    """过滤掉不在目录里的 key(去重、保序),防脏数据/目录收缩后的悬空 key。"""
    seen: set[str] = set()
    out: list[str] = []
    for k in pages or []:
        if k in _ALL_SET and k not in seen:
            seen.add(k)
            out.append(k)
    return out


def effective_pages(role_name: str, role_pages: list[str] | None) -> list[str]:
    """某角色的有效可见页:super_admin → 全部;其余 → 其 pages 与目录取交(自愈悬空 key)。"""
    if role_name == SUPER_ADMIN_ROLE:
        return list(ALL_PAGE_KEYS)
    return sanitize_pages(role_pages)
