/**
 * Permission catalogue. Roles are sets of these keys.
 * Format: <domain>.<action>. Wildcards: "<domain>.*" and "*" are honoured by the guard.
 */
export const PERMISSIONS = {
  // tenant administration
  'tenant.settings.manage': 'Manage tenant settings and branding',
  'users.read': 'View users',
  'users.manage': 'Create, edit, disable users and assign roles',
  'roles.manage': 'Create and edit roles',
  'apikeys.manage': 'Create and revoke API keys',
  'audit.read': 'View audit log',

  // master data
  'masterdata.read': 'View master data',
  'masterdata.manage': 'Create and edit warehouses, zones, locations, storers, SKUs, suppliers, customers, carriers, reason codes',
  'rules.manage': 'Edit putaway and allocation rules',

  // inbound
  'inbound.read': 'View ASNs and receipts',
  'inbound.manage': 'Create, edit, cancel ASNs; schedule docks',
  'inbound.receive': 'Perform receiving (RF)',
  'inbound.close': 'Post GRN and send RCR',

  // inventory
  'inventory.read': 'View stock, movements, serials',
  'inventory.move': 'Move stock and LPNs (RF)',
  'inventory.hold': 'Place and release holds',
  'inventory.adjust.request': 'Request adjustments',
  'inventory.adjust.approve': 'Approve and post adjustments',
  'inventory.count.manage': 'Plan, release and review cycle counts',
  'inventory.count.perform': 'Count (RF)',

  // outbound
  'outbound.read': 'View orders, waves, shipments, loads',
  'outbound.manage': 'Create, edit, cancel orders',
  'outbound.allocate': 'Allocate and release waves',
  'outbound.pick': 'Pick (RF)',
  'outbound.pack': 'Pack and stage',
  'outbound.ship': 'Load, confirm shipment (PGI), gate pass',
  'returns.manage': 'Create and disposition returns',

  // tasks
  'tasks.read': 'View task queue',
  'tasks.manage': 'Assign, reprioritise, cancel tasks',
  'tasks.execute': 'Execute tasks (RF)',

  // billing (3PL)
  'billing.read': 'View contracts, charges, invoices',
  'billing.manage': 'Edit contracts and tariffs, capture manual charges',
  'billing.invoice': 'Run invoices, issue credit notes',

  // integrations
  'integrations.read': 'View integration messages and webhooks',
  'integrations.manage': 'Configure connectors, webhooks, imports',

  // reporting
  'reports.read': 'View reports and dashboards',
  'reports.export': 'Export reports',

  // AI
  'ai.use': 'Use AI copilot and view proposals',
  'ai.decide': 'Accept or reject AI proposals',
} as const;

export type Permission = keyof typeof PERMISSIONS;
export const ALL_PERMISSIONS = Object.keys(PERMISSIONS) as Permission[];

export interface SystemRoleDefinition {
  code: string;
  name: string;
  description: string;
  permissions: readonly (Permission | '*' | `${string}.*`)[];
}

/** Default roles created for every new tenant. */
export const SYSTEM_ROLES: readonly SystemRoleDefinition[] = [
  { code: 'ADMIN', name: 'Tenant Administrator', description: 'Full access', permissions: ['*'] },
  {
    code: 'OPS_MANAGER',
    name: 'Operations Manager',
    description: 'Runs the warehouse; approves adjustments; sees billing',
    permissions: [
      'masterdata.*', 'rules.manage', 'inbound.*', 'inventory.*', 'outbound.*', 'returns.manage',
      'tasks.*', 'billing.read', 'integrations.read', 'reports.*', 'ai.*', 'users.read', 'audit.read',
    ],
  },
  {
    code: 'SUPERVISOR',
    name: 'Shift Supervisor',
    description: 'Directs floor work, closes receipts, releases waves',
    permissions: [
      'masterdata.read', 'inbound.*', 'inventory.read', 'inventory.move', 'inventory.hold', 'inventory.adjust.request',
      'inventory.count.manage', 'inventory.count.perform', 'outbound.*', 'returns.manage', 'tasks.*', 'reports.read', 'ai.use',
    ],
  },
  {
    code: 'CSO',
    name: 'Customer Service Officer',
    description: 'Creates ASNs and orders, communicates with storers',
    permissions: [
      'masterdata.read', 'masterdata.manage', 'inbound.read', 'inbound.manage', 'inbound.close',
      'inventory.read', 'outbound.read', 'outbound.manage', 'returns.manage', 'tasks.read', 'reports.read', 'ai.use',
    ],
  },
  {
    code: 'WAREHOUSEMAN',
    name: 'Warehouse Operator (RF)',
    description: 'Executes receiving, putaway, picking, packing, counting on handheld',
    permissions: [
      'inbound.read', 'inbound.receive', 'inventory.read', 'inventory.move', 'inventory.count.perform',
      'outbound.read', 'outbound.pick', 'outbound.pack', 'outbound.ship', 'tasks.read', 'tasks.execute',
    ],
  },
  {
    code: 'INVENTORY_CONTROLLER',
    name: 'Inventory Controller',
    description: 'Owns stock accuracy: counts, adjustments, holds',
    permissions: [
      'masterdata.read', 'inventory.*', 'inbound.read', 'outbound.read', 'tasks.read', 'tasks.manage', 'reports.*', 'ai.use',
    ],
  },
  {
    code: 'BILLING',
    name: 'Billing Officer',
    description: 'Maintains tariffs, runs invoices',
    permissions: ['masterdata.read', 'inbound.read', 'outbound.read', 'inventory.read', 'billing.*', 'reports.*'],
  },
  {
    code: 'CUSTOMER',
    name: 'Storer Portal User',
    description: 'Storer-scoped read access plus order and ASN creation',
    permissions: ['masterdata.read', 'inbound.read', 'inbound.manage', 'inventory.read', 'outbound.read', 'outbound.manage', 'billing.read', 'reports.read'],
  },
] as const;

/** Returns true when the granted set satisfies the required permission (supports wildcards). */
export function hasPermission(granted: readonly string[], required: Permission): boolean {
  if (granted.includes('*')) return true;
  if (granted.includes(required)) return true;
  const domain = required.split('.')[0];
  return granted.includes(`${domain}.*`);
}
