// Central permission registry. This is the single source of truth for every
// granular permission key in the dashboard. Adding a key here automatically
// surfaces it in the GET /admin/permissions endpoint and the Roles matrix UI.
// To add a new permission: add an entry to PERMISSIONS below, then (optionally)
// grant it to roles by default in DEFAULT_ROLE_PERMISSIONS and the migration.

export type PermissionKey = string;

export interface PermissionDef {
  key: PermissionKey;
  label: string;
  group: string;
}

// Ordered list of every permission, grouped by feature area for the matrix UI.
export const PERMISSIONS: PermissionDef[] = [
  { key: 'events.create', label: 'Create events', group: 'Events' },
  { key: 'events.edit', label: 'Edit events', group: 'Events' },
  { key: 'events.delete', label: 'Delete events', group: 'Events' },

  { key: 'organizers.manage', label: 'Manage organizers', group: 'Organizers' },

  { key: 'gallery.upload', label: 'Upload media', group: 'Gallery' },
  { key: 'gallery.delete', label: 'Delete media', group: 'Gallery' },

  { key: 'blog.draft', label: 'Draft and edit posts', group: 'Blog' },
  { key: 'blog.publish', label: 'Publish posts', group: 'Blog' },
  { key: 'blog.delete', label: 'Delete posts', group: 'Blog' },

  { key: 'faq.manage', label: 'Manage FAQ', group: 'FAQ' },

  { key: 'submissions.review', label: 'Review submissions', group: 'Submissions' },

  { key: 'board.manage', label: 'Moderate the message board', group: 'Board' },

  { key: 'moderation.act', label: 'Hide content and block pubkeys', group: 'Moderation' },

  { key: 'categories.manage', label: 'Manage categories', group: 'Categories' },

  { key: 'users.assign_role', label: 'Assign user roles', group: 'Users' },
  { key: 'nip05.assign', label: 'Assign NIP-05 usernames', group: 'Users' },

  { key: 'relays.manage', label: 'Manage relays', group: 'Relays' },

  { key: 'settings.edit', label: 'Edit site settings', group: 'Settings' },

  { key: 'roles.edit_permissions', label: 'Edit roles and permissions', group: 'Roles' },

  { key: 'api_keys.manage', label: 'Create and manage API keys', group: 'API Keys' },

  { key: 'nostr_tools.use', label: 'Use Nostr tools', group: 'Nostr Tools' },
];

// Assignable roles, highest to lowest. SuperAdmin is env-sourced and never stored
// or assignable, so it is not part of this list. Guest is the absence of a role.
export const ASSIGNABLE_ROLES = ['admin', 'moderator', 'writer'] as const;
export type AssignableRole = (typeof ASSIGNABLE_ROLES)[number];

export type EffectiveRole = 'superadmin' | AssignableRole | 'guest';

// Hierarchy ranks used for safeguard comparisons.
export const ROLE_RANK: Record<EffectiveRole, number> = {
  superadmin: 4,
  admin: 3,
  moderator: 2,
  writer: 1,
  guest: 0,
};

export const ALL_PERMISSION_KEYS: ReadonlySet<PermissionKey> = new Set(
  PERMISSIONS.map((p) => p.key)
);

export function isValidPermissionKey(key: string): boolean {
  return ALL_PERMISSION_KEYS.has(key);
}

export function isAssignableRole(role: unknown): role is AssignableRole {
  return typeof role === 'string' && (ASSIGNABLE_ROLES as readonly string[]).includes(role);
}

// Default permission sets seeded per role. Admin gets everything except the
// roles editor and API key management, which stay SuperAdmin-only by default.
// Guest gets nothing and is therefore not represented here.
export const DEFAULT_ROLE_PERMISSIONS: Record<AssignableRole, PermissionKey[]> = {
  admin: PERMISSIONS.map((p) => p.key).filter(
    (k) => k !== 'roles.edit_permissions' && k !== 'api_keys.manage'
  ),
  moderator: [
    'events.create',
    'events.edit',
    'events.delete',
    'submissions.review',
    'moderation.act',
    'gallery.upload',
    'board.manage',
    'categories.manage',
    'faq.manage',
  ],
  writer: ['blog.draft', 'gallery.upload', 'events.create'],
};
