from __future__ import annotations

from dataclasses import asdict, dataclass
from typing import Iterable


@dataclass(frozen=True)
class PermissionDef:
    key: str
    name: str
    module: str
    category: str
    description: str = ""
    risk_level: str = "low"

    def to_dict(self) -> dict:
        return asdict(self)


def _p(key: str, name: str, module: str, category: str, description: str = "", risk_level: str = "low") -> PermissionDef:
    return PermissionDef(key, name, module, category, description, risk_level)


PERMISSION_CATALOG: tuple[PermissionDef, ...] = (
    _p("dashboard.view", "查看数据仪表盘", "overview", "page"),
    _p("statistics.sales.view", "查看销售分析", "overview", "page"),
    _p("statistics.products.view", "查看商品分析", "overview", "page"),
    _p("statistics.customers.view", "查看客户分析", "overview", "page"),
    _p("statistics.product_sales.view", "查看商品销售明细", "overview", "page"),
    _p("adv_stats.view", "查看高级数据统计", "overview", "page"),
    _p("adv_stats.detail", "查看统计明细（含客户信息）", "overview", "field",
       description="可下钻到订单级与商品行级明细，包含客户姓名、邮箱、电话与完整地址",
       risk_level="high"),
    _p("adv_stats.export", "导出统计报表", "overview", "action",
       description="导出报表文件；配合明细权限可导出全量客户信息",
       risk_level="high"),
    _p("orders.view", "查看订单", "orders", "page"),
    _p("orders.detail.view", "查看订单详情", "orders", "page"),
    _p("orders.create", "创建订单", "orders", "action", risk_level="medium"),
    _p("orders.update", "编辑订单", "orders", "action", risk_level="medium"),
    _p("orders.advanced_edit", "高级订单编辑", "orders", "action", risk_level="high"),
    _p("orders.delete", "删除订单", "orders", "action", risk_level="high"),
    _p("orders.export", "导出订单", "orders", "action", risk_level="medium"),
    _p("orders.print", "打印订单单据", "orders", "action"),
    _p("orders.ship", "订单发货", "orders", "action", risk_level="high"),
    _p("orders.pickup", "到店取货核销", "orders", "action", risk_level="medium"),
    _p("orders.tracking.update", "更新物流信息", "orders", "action", risk_level="medium"),
    _p("orders.payment.view", "查看订单支付明细", "orders", "field", risk_level="medium"),
    _p("dispatch.view", "查看发货管理", "dispatch", "page"),
    _p("dispatch.create_batch", "创建发货批次", "dispatch", "action", risk_level="medium"),
    _p("dispatch.update_batch", "调整发货批次", "dispatch", "action", risk_level="medium"),
    _p("dispatch.confirm_batch", "确认发货批次", "dispatch", "action", risk_level="high"),
    _p("dispatch.redispatch", "重新发货", "dispatch", "action", risk_level="high"),
    _p("dispatch.export", "导出发货数据", "dispatch", "action"),
    _p("dispatch.print_labels", "打印面单", "dispatch", "action"),
    _p("products.view", "查看商品", "products", "page"),
    _p("products.create", "创建商品", "products", "action", risk_level="medium"),
    _p("products.update", "编辑商品", "products", "action", risk_level="medium"),
    _p("products.delete", "删除商品", "products", "action", risk_level="high"),
    _p("products.inventory.update", "调整库存", "products", "action", risk_level="medium"),
    _p("products.images.upload", "上传商品图片", "products", "action"),
    _p("products.seo.update", "编辑商品 SEO", "products", "action"),
    _p("products.cost_price.view", "查看商品成本价", "products", "field", risk_level="high"),
    _p("categories.view", "查看分类", "products", "page"),
    _p("categories.create", "创建分类", "products", "action"),
    _p("categories.update", "编辑分类", "products", "action"),
    _p("categories.delete", "删除分类", "products", "action", risk_level="medium"),
    _p("brands.view", "查看品牌", "products", "page"),
    _p("brands.create", "创建品牌", "products", "action"),
    _p("brands.update", "编辑品牌", "products", "action"),
    _p("brands.delete", "删除品牌", "products", "action", risk_level="medium"),
    _p("customers.view", "查看客户", "customers", "page"),
    _p("customers.detail.view", "查看客户详情", "customers", "page"),
    _p("customers.update", "编辑客户", "customers", "action", risk_level="medium"),
    _p("customers.delete", "删除客户", "customers", "action", risk_level="high"),
    _p("customers.export", "导出客户", "customers", "action", risk_level="high"),
    _p("customers.phone.view", "查看客户手机号", "customers", "field", risk_level="high"),
    _p("customers.email.view", "查看客户邮箱", "customers", "field", risk_level="high"),
    _p("member_levels.view", "查看会员等级", "marketing", "page"),
    _p("member_levels.create", "创建会员等级", "marketing", "action"),
    _p("member_levels.update", "编辑会员等级", "marketing", "action"),
    _p("member_levels.delete", "删除会员等级", "marketing", "action", risk_level="medium"),
    _p("coupons.view", "查看优惠券", "marketing", "page"),
    _p("coupons.create", "创建优惠券", "marketing", "action", risk_level="medium"),
    _p("coupons.update", "编辑优惠券", "marketing", "action", risk_level="medium"),
    _p("coupons.delete", "删除优惠券", "marketing", "action", risk_level="medium"),
    _p("reviews.view", "查看评价", "marketing", "page"),
    _p("reviews.reply", "回复评价", "marketing", "action"),
    _p("reviews.hide", "隐藏评价", "marketing", "action", risk_level="medium"),
    _p("reviews.delete", "删除评价", "marketing", "action", risk_level="high"),
    _p("refunds.view", "查看退款", "refunds", "page"),
    _p("refunds.approve", "同意退款", "refunds", "action", risk_level="critical"),
    _p("refunds.reject", "拒绝退款", "refunds", "action", risk_level="high"),
    _p("refunds.execute", "执行退款", "refunds", "action", risk_level="critical"),
    _p("refunds.export", "导出退款", "refunds", "action", risk_level="medium"),
    _p("articles.view", "查看文章", "content", "page"),
    _p("articles.create", "创建文章", "content", "action"),
    _p("articles.update", "编辑文章", "content", "action"),
    _p("articles.delete", "删除文章", "content", "action", risk_level="medium"),
    _p("menus.view", "查看菜单", "content", "page"),
    _p("menus.create", "创建菜单", "content", "action"),
    _p("menus.update", "编辑菜单", "content", "action"),
    _p("menus.delete", "删除菜单", "content", "action", risk_level="medium"),
    _p("banners.view", "查看 Banner", "content", "page"),
    _p("banners.create", "创建 Banner", "content", "action"),
    _p("banners.update", "编辑 Banner", "content", "action"),
    _p("banners.delete", "删除 Banner", "content", "action", risk_level="medium"),
    _p("shipping.view", "查看运费配置", "settings", "page"),
    _p("shipping.create", "创建运费配置", "settings", "action", risk_level="medium"),
    _p("shipping.update", "编辑运费配置", "settings", "action", risk_level="medium"),
    _p("shipping.delete", "删除运费配置", "settings", "action", risk_level="medium"),
    _p("print_templates.view", "查看打印模板", "settings", "page"),
    _p("print_templates.create", "创建打印模板", "settings", "action"),
    _p("print_templates.update", "编辑打印模板", "settings", "action"),
    _p("print_templates.delete", "删除打印模板", "settings", "action", risk_level="medium"),
    _p("theme.view", "查看主题", "settings", "page"),
    _p("theme.update", "编辑主题", "settings", "action", risk_level="medium"),
    _p("settings.basic.view", "查看基础设置", "settings", "page"),
    _p("settings.basic.update", "编辑基础设置", "settings", "action", risk_level="medium"),
    _p("settings.payment.view", "查看支付配置", "settings", "page", risk_level="high"),
    _p("settings.payment.update", "编辑支付配置", "settings", "action", risk_level="critical"),
    _p("settings.payment.secrets.view", "查看支付密钥", "settings", "field", risk_level="critical"),
    _p("settings.currency.view", "查看货币设置", "settings", "page"),
    _p("settings.currency.update", "编辑货币设置", "settings", "action", risk_level="medium"),
    _p("settings.ai.view", "查看 AI 配置", "settings", "page", risk_level="high"),
    _p("settings.ai.update", "编辑 AI 配置", "settings", "action", risk_level="critical"),
    _p("settings.ai.secrets.view", "查看 AI 密钥", "settings", "field", risk_level="critical"),
    _p("settings.address_fields.view", "查看地址字段", "settings", "page"),
    _p("settings.address_fields.update", "编辑地址字段", "settings", "action", risk_level="medium"),
    _p("settings.email_templates.view", "查看邮件模板", "settings", "page"),
    _p("settings.email_templates.update", "编辑邮件模板", "settings", "action", risk_level="medium"),
    _p("settings.shipping_policy.view", "查看配送售后政策", "settings", "page"),
    _p("settings.shipping_policy.update", "编辑配送售后政策", "settings", "action", risk_level="medium"),
    _p("settings.storage.view", "查看文件存储配置", "settings", "page", risk_level="high"),
    _p("settings.storage.update", "编辑文件存储配置", "settings", "action", risk_level="critical"),
    _p("settings.storage.secrets.view", "查看存储密钥", "settings", "field", risk_level="critical"),
    _p("plugins.view", "查看插件中心", "plugins", "page"),
    _p("plugins.enable", "启用插件", "plugins", "action", risk_level="critical"),
    _p("plugins.disable", "停用插件", "plugins", "action", risk_level="critical"),
    _p("plugins.configure", "配置插件", "plugins", "action", risk_level="high"),
    _p("plugins.wechat_auth.configure", "配置微信登录插件", "plugins", "action", risk_level="critical"),
    _p("plugins.wechat_auth.secrets.view", "查看微信密钥", "plugins", "field", risk_level="critical"),
    _p("plugins.auto_dispatch.configure", "配置自动分单发货插件", "plugins", "action", risk_level="high"),
    _p("plugins.advanced_shipping.view", "查看高级运费规则", "plugins", "page"),
    _p("plugins.advanced_shipping.configure", "配置高级运费规则", "plugins", "action", risk_level="high"),
    _p("plugins.advanced_shipping.ai_apply", "AI 起草并应用运费规则", "plugins", "action", risk_level="critical"),
    _p("plugins.advanced_shipping.rollback", "回滚运费规则修订", "plugins", "action", risk_level="high"),
    _p("audit_logs.view", "查看审计日志", "security", "page", risk_level="high"),
    _p("permissions.view", "查看权限管理", "security", "page", risk_level="critical"),
    _p("permissions.roles.create", "创建角色", "security", "action", risk_level="critical"),
    _p("permissions.roles.update", "编辑角色", "security", "action", risk_level="critical"),
    _p("permissions.roles.delete", "删除角色", "security", "action", risk_level="critical"),
    _p("permissions.roles.assign", "分配角色", "security", "action", risk_level="critical"),
    _p("permissions.users.view", "查看后台用户", "security", "page", risk_level="critical"),
    _p("permissions.users.update", "编辑后台用户", "security", "action", risk_level="critical"),
    _p("permissions.users.override", "设置用户权限微调", "security", "action", risk_level="critical"),
    _p("pos.sell", "POS 收银销售", "pos", "action", risk_level="medium"),
    _p("pos.age_approve", "POS 18+ 年龄审批", "pos", "action", risk_level="high"),
    _p("pos.price_override", "POS 改价与折扣审批", "pos", "action", risk_level="high"),
    _p("pos.return_create", "POS 发起退货", "pos", "action", risk_level="medium"),
    _p("pos.return_approve", "POS 审批退货", "pos", "action", risk_level="high"),
    _p("pos.refund_execute", "POS 执行退款", "pos", "action", risk_level="high"),
    _p("pos.rules.manage", "维护 POS 门店规则", "pos", "action", risk_level="high"),
    _p("pos.staff.manage", "维护 POS 收银员", "pos", "action", risk_level="high"),
    _p("pos.conflict_close", "POS 冲突订单主管结案", "pos", "action", risk_level="high"),
    _p("pos.audit.view", "查看 POS 审计", "pos", "page"),
    _p("pos.drawer.open", "POS 手动开钱柜", "pos", "action", risk_level="high"),
    _p("inventory.view", "查看进销存", "inventory", "page"),
    _p("inventory.manage", "配置进销存与仓库", "inventory", "action", risk_level="high"),
    _p("inventory.adjust", "库存纠正单", "inventory", "action", risk_level="high"),
    _p("inventory.purchase", "采购单管理", "inventory", "action", risk_level="medium"),
    _p("inventory.purchase.approve", "采购单审批", "inventory", "action", risk_level="high"),
    _p("inventory.operate", "调拨/盘点/组合装", "inventory", "action", risk_level="medium"),
)

_CATALOG_BY_KEY = {p.key: p for p in PERMISSION_CATALOG}
_ALL_KEYS = frozenset(_CATALOG_BY_KEY)
STAFF_PERMISSION_KEYS = frozenset(
    key
    for key in _ALL_KEYS
    if key.endswith(".view")
    or key in {"dashboard.view", "orders.detail.view", "orders.print", "reviews.reply", "dispatch.print_labels"}
)

SYSTEM_ROLE_DEFS = {
    "admin": {"name": "管理员", "description": "系统默认管理员，拥有全部后台权限。", "permissions": sorted(_ALL_KEYS)},
    "staff": {"name": "员工", "description": "系统默认员工，默认以查看和基础处理为主。", "permissions": sorted(STAFF_PERMISSION_KEYS)},
}


def get_permission(key: str) -> PermissionDef | None:
    return _CATALOG_BY_KEY.get(key)


def permission_keys() -> set[str]:
    return set(_ALL_KEYS)


def default_role_permissions(role_code: str) -> list[str]:
    return list(SYSTEM_ROLE_DEFS.get(role_code, {}).get("permissions", []))


def catalog_by_module() -> list[dict]:
    grouped: dict[str, list[dict]] = {}
    for permission in PERMISSION_CATALOG:
        grouped.setdefault(permission.module, []).append(permission.to_dict())
    return [{"module": module, "permissions": permissions} for module, permissions in grouped.items()]


def filter_known_permissions(keys: Iterable[str]) -> list[str]:
    return sorted({key for key in keys if key in _ALL_KEYS})
