/**
 * 前端能力點 — 與後端 apps/backend/internal/module/permission 對齊。
 * UI 用 can(roles, code) 決定顯示／導航；真擋在 API middleware。
 */

export const Permission = {
  // 公開（文件用；前端通常不檢查）
  PublicPing: "public:ping",
  PublicAuthLogin: "public:auth:login",
  PublicThreadsOAuthCallback: "public:threads:oauth_callback",

  // 會員
  AuthMe: "auth:me",
  AuthProfileUpdate: "auth:profile:update",
  AuthPasswordChange: "auth:password:change",
  AuthEmailVerify: "auth:email:verify",
  AuthLogout: "auth:logout",
  AuthIdentities: "auth:identities",
  AuthBind: "auth:bind",
  AuthUnbind: "auth:unbind",

  MediaUpload: "media:upload",

  SettingsAIRead: "settings:ai:read",
  SettingsAIWrite: "settings:ai:write",
  SettingsPlacementRead: "settings:placement:read",
  SettingsPlacementWrite: "settings:placement:write",
  SettingsModelsList: "settings:models:list",

  ThreadsOAuthStart: "threads:oauth:start",
  ThreadsList: "threads:list",
  ThreadsRefresh: "threads:refresh",
  ThreadsDisconnect: "threads:disconnect",

  JobsList: "jobs:list",
  JobsGet: "jobs:get",
  /** 任務頁「產生測試任務」— 僅 admin */
  JobsDemoCreate: "jobs:demo:create",

  NotifList: "notifications:list",
  NotifUnread: "notifications:unread",
  NotifMarkRead: "notifications:mark_read",

  // 管理
  AdminAccess: "admin:access",
  AdminMembersList: "admin:members:list",
  AdminMembersGet: "admin:members:get",
  AdminMembersCreate: "admin:members:create",
  AdminMembersSuspend: "admin:members:suspend",
  AdminMembersRoles: "admin:members:roles",
  AdminMembersEmailVerified: "admin:members:email_verified",
  AdminMembersResetPassword: "admin:members:reset_password",
  AdminMembersIdentities: "admin:members:identities",
  AdminMembersStatus: "admin:members:status",
} as const;

export type PermissionCode = (typeof Permission)[keyof typeof Permission];

const memberBase: PermissionCode[] = [
  Permission.AuthMe,
  Permission.AuthProfileUpdate,
  Permission.AuthPasswordChange,
  Permission.AuthEmailVerify,
  Permission.AuthLogout,
  Permission.AuthIdentities,
  Permission.AuthBind,
  Permission.AuthUnbind,
  Permission.MediaUpload,
  Permission.SettingsAIRead,
  Permission.SettingsAIWrite,
  Permission.SettingsPlacementRead,
  Permission.SettingsPlacementWrite,
  Permission.SettingsModelsList,
  Permission.ThreadsOAuthStart,
  Permission.ThreadsList,
  Permission.ThreadsRefresh,
  Permission.ThreadsDisconnect,
  Permission.JobsList,
  Permission.JobsGet,
  Permission.NotifList,
  Permission.NotifUnread,
  Permission.NotifMarkRead,
];

const adminExtra: PermissionCode[] = [
  Permission.AdminAccess,
  Permission.AdminMembersList,
  Permission.AdminMembersGet,
  Permission.AdminMembersCreate,
  Permission.AdminMembersSuspend,
  Permission.AdminMembersRoles,
  Permission.AdminMembersEmailVerified,
  Permission.AdminMembersResetPassword,
  Permission.AdminMembersIdentities,
  Permission.AdminMembersStatus,
  Permission.JobsDemoCreate,
];

const roleGrants: Record<string, PermissionCode[]> = {
  member: memberBase,
  admin: [...memberBase, ...adminExtra],
};

/** 合併角色能力 */
export function expandPermissions(roles: string[] | undefined | null): Set<string> {
  const out = new Set<string>();
  for (const r of roles ?? []) {
    for (const p of roleGrants[r] ?? []) {
      out.add(p);
    }
  }
  return out;
}

export function can(
  roles: string[] | undefined | null,
  code: PermissionCode | string,
): boolean {
  return expandPermissions(roles).has(code);
}

export function canAny(
  roles: string[] | undefined | null,
  ...codes: (PermissionCode | string)[]
): boolean {
  const set = expandPermissions(roles);
  return codes.some((c) => set.has(c));
}

/** 是否具備管理後台總閘 */
export function canAdmin(roles: string[] | undefined | null): boolean {
  return can(roles, Permission.AdminAccess);
}
