/**
 * 路由权限配置 — 权限声明的单一真相源
 *
 * 规则：
 * 1. 每个受保护路由必须在此声明至少一个权限码（TypeScript 强制非空数组）
 * 2. 子路由（如 /health/patients/:id）通过前缀匹配自动继承父路由权限，无需重复声明
 * 3. 新增路由必须在此添加对应条目，否则 PrivateRoute 默认 403
 * 4. 冻结路由标记 frozen: true，自动归入 FROZEN_ROUTES
 *
 * 排列规则：精确路径优先于前缀路径（如 /plugins/admin 在 /plugins 之前）
 */

// 非空数组类型 — 确保每个路由至少有一个权限码
type Permissions = [string, ...string[]];

interface RoutePermissionEntry {
  path: string;
  permissions: Permissions;
  frozen?: boolean;
}

const ENTRIES: RoutePermissionEntry[] = [
  // ===== 基础模块 =====
  { path: "/users", permissions: ["user.list", "user.update"] },
  { path: "/roles", permissions: ["role.list", "role.update"] },
  {
    path: "/organizations",
    permissions: ["organization.list", "organization.update"],
  },
  { path: "/workflow", permissions: ["workflow.list", "workflow.read"] },
  { path: "/messages", permissions: ["message.list"] },
  { path: "/settings", permissions: ["setting.read", "setting.update"] },

  // ===== 插件模块（精确路径优先于前缀通配） =====
  { path: "/plugins/admin", permissions: ["plugin.admin"] },
  { path: "/plugins/market", permissions: ["plugin.admin"] },
  // 动态路由 catch-all: /plugins/:pluginId/:entityName 等
  { path: "/plugins", permissions: ["plugin.list", "plugin.admin"] },
];

/** 活跃路由的权限映射 — 自动从配置生成，供 PrivateRoute 使用 */
export const ROUTE_PERMISSIONS: Record<string, string[]> = Object.fromEntries(
  ENTRIES.filter((e) => !e.frozen).map((e) => [e.path, [...e.permissions]]),
);

/** 冻结路由路径列表 — 自动从配置生成 */
export const FROZEN_ROUTES: string[] = ENTRIES.filter((e) => e.frozen).map(
  (e) => e.path,
);

/** 开发模式下校验：检查是否有路由路径重复 */
if (import.meta.env.DEV) {
  const paths = ENTRIES.map((e) => e.path);
  const dupes = paths.filter((p, i) => paths.indexOf(p) !== i);
  if (dupes.length > 0) {
    console.error("[routeConfig] 检测到重复路径:", dupes);
  }
}

/**
 * Tab 级权限映射 — 详情页内 Tab 可见性的单一真相源
 *
 * key 格式: "{routePrefix}#{tabKey}"
 * value: 权限码（undefined 表示始终可见）
 *
 * 新增详情页 Tab 时必须在此声明，否则 Tab 默认不可见（安全默认）。
 */
const TAB_PERM_ENTRIES: Array<{ key: string; permission?: string }> = [
  // Phase 1+: 在此添加 boutique 模块的 Tab 权限
];

export const TAB_PERMISSIONS: Record<string, string | undefined> = Object.fromEntries(
  TAB_PERM_ENTRIES.map((e) => [e.key, e.permission]),
);

/**
 * DEV 模式路由覆盖率校验。
 * 在 App.tsx 挂载后调用，检查所有实际路由是否都有权限声明。
 * 忽略带参数的子路由（如 /health/patients/:id），它们通过前缀匹配继承权限。
 */
export function validateRouteCoverage(registeredPaths: string[]): void {
  if (!import.meta.env.DEV) return;

  const allConfigPaths = ENTRIES.map((e) => e.path);
  const uncovered = registeredPaths.filter((p) => {
    if (p === "/" || p === "/login" || p === "/*") return false;
    if (p.includes(":")) return false; // 子路由通过前缀继承
    return !allConfigPaths.includes(p);
  });

  if (uncovered.length > 0) {
    console.warn(
      "[routeConfig] 以下路由未在 routeConfig.ts 中声明权限，将被 PrivateRoute 默认 403 拦截：",
      uncovered,
    );
  }
}
