package authx

import (
	"context"
	"fmt"
	"strings"
)

// CompanyPermCatalog 公司可被授予的权限模块（不含平台专属「管理租户」）。
func CompanyPermCatalog() []string {
	return []string{
		Perm读取模块, Perm写入模块, Perm发布模块,
		Perm查询数据, Perm新增数据, Perm更新数据, Perm删除数据, Perm导入数据, Perm导出数据,
		Perm下载文件, Perm上传文件,
		Perm查看审计,
		Perm管理智能体, Perm邀请成员, Perm管理组织,
		Perm数据同步,
	}
}

// PermModule 权限模块分组。
type PermModule struct {
	Title string     `json:"title"`
	Items []PermItem `json:"items"`
}

type PermItem struct {
	Perm string `json:"perm"`
	Desc string `json:"desc"`
}

// PermDesc 权限说明（超管授权 / 公司分配时展示）。
func PermDesc(p string) string {
	switch NormalizePerm(p) {
	case Perm读取模块:
		return "查看模块列表、蓝图与智能体胶囊"
	case Perm写入模块:
		return "保存在建草稿（不发布）"
	case Perm发布模块:
		return "发布/更新线上模块"
	case Perm查询数据:
		return "查询业务列表与详情"
	case Perm新增数据:
		return "新增业务数据行"
	case Perm更新数据:
		return "更新业务数据行"
	case Perm删除数据:
		return "删除业务数据行"
	case Perm导入数据:
		return "导入 Excel/CSV/JSON"
	case Perm导出数据:
		return "导出业务数据"
	case Perm下载文件:
		return "下载已上传文件"
	case Perm上传文件:
		return "上传附件与素材"
	case Perm查看审计:
		return "查看操作审计日志"
	case Perm管理智能体:
		return "管理智能体账号与角色权限"
	case Perm邀请成员:
		return "生成邀请码、管理成员角色"
	case Perm管理组织:
		return "管理组织单元与成员归属"
	case Perm数据同步:
		return "配置跨库数据同步通道"
	case Perm管理租户:
		return "平台级：管理公司与权限额度"
	default:
		return p
	}
}

func PermModules() []PermModule {
	mk := func(title string, perms ...string) PermModule {
		items := make([]PermItem, 0, len(perms))
		for _, p := range perms {
			items = append(items, PermItem{Perm: p, Desc: PermDesc(p)})
		}
		return PermModule{Title: title, Items: items}
	}
	return []PermModule{
		mk("模块", Perm读取模块, Perm写入模块, Perm发布模块),
		mk("数据", Perm查询数据, Perm新增数据, Perm更新数据, Perm删除数据, Perm导入数据, Perm导出数据),
		mk("文件", Perm下载文件, Perm上传文件),
		mk("审计", Perm查看审计),
		mk("公司管理", Perm管理智能体, Perm邀请成员, Perm管理组织),
		mk("数据同步", Perm数据同步),
	}
}

// FilterWithinAllowance 只保留额度内的权限。
func FilterWithinAllowance(want, allowance []string) ([]string, []string) {
	allow := map[string]struct{}{}
	for _, p := range NormalizePerms(allowance) {
		allow[p] = struct{}{}
	}
	var ok, denied []string
	for _, p := range NormalizePerms(want) {
		if _, hit := allow[p]; hit {
			ok = append(ok, p)
		} else {
			denied = append(denied, p)
		}
	}
	return ok, denied
}

var EntitlementChecker func(ctx context.Context, tenantID int64, perm string) bool

func AssertWithinEntitlement(want, allowance []string) error {
	_, denied := FilterWithinAllowance(want, allowance)
	if len(denied) == 0 {
		return nil
	}
	return fmt.Errorf("超出公司权限额度: %s", strings.Join(denied, "、"))
}
