"""admin 角色 → 可见页面(权限)映射表。

RBAC 的「角色」侧:每个角色持有一组「页面 key」(= 左侧导航项),决定该角色登录后台后左边能看到
哪些页。super_admin 是内建全权角色(is_builtin=True),恒可见全部页(effective_pages 里特判,
不依赖本表存的 pages)、不可编辑/删除。其余角色(含 operator/finance)可由 super_admin 增删改。

admin_user.role 存的是本表的 name(字符串弱引用,不建外键——与既有 require_role 字符串口径一致;
删除在用角色由业务层拦截,见 routers/roles.py)。页面 key 清单见 app/admin/permissions.py。
"""
from __future__ import annotations

from datetime import datetime

from sqlalchemy import JSON, Boolean, DateTime, Integer, String, func
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base

_JSON = JSON().with_variant(JSONB(), "postgresql")


class AdminRole(Base):
    __tablename__ = "admin_role"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    # 角色标识 key(不可变,承重):admin_user.role 引用它、require_role 按它鉴权。
    # 内建 = super_admin/operator/finance/tech(英文,勿改);自定义 = 创建时的名称。
    name: Mapped[str] = mapped_column(String(32), unique=True, index=True, nullable=False)
    # 展示名(可改):内建 = 管理员/运营/财务/技术;自定义默认 = name。UI 一律展示 label。
    label: Mapped[str] = mapped_column(String(32), nullable=False, default="")
    # 该角色可见页面 key 列表(= 左侧导航项),见 app/admin/permissions.py 的 PERMISSION_CATALOG
    pages: Mapped[list] = mapped_column(_JSON, nullable=False, default=list)
    # 内建角色(当前仅 super_admin):不可编辑/删除,恒全权
    is_builtin: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    def __repr__(self) -> str:  # pragma: no cover
        return f"<AdminRole name={self.name} pages={len(self.pages)} builtin={self.is_builtin}>"
