const EDR_FREIGHT_APP_KEY = 'edr_freight_app';

export type FreightPermissionSeed = {
  id: string;
  key: string;
  name: { am: string; en: string };
  applicationKey: string;
};

export const RULE_ENGINE_RESOURCE_SLUGS = [
  'cargo-types',
  'container-types',
  'wagon-types',
  'service-types',
  'yards',
  'shipping-lines',
  'weight-limit-rules',
  'priority-configs',
  'rates',
  'approval-rules',
  'yard-distances',
  // Keep new slugs at the END: ruleEngineCrudId derives ids from list index,
  // so a mid-list insert would shift ids already seeded for later slugs.
  'truck-types',
] as const;

export type RuleEngineResourceSlug = (typeof RULE_ENGINE_RESOURCE_SLUGS)[number];

const slugToResourceKey = (slug: RuleEngineResourceSlug): string =>
  slug.replace(/-/g, '_');

const perm = (
  id: string,
  key: string,
  en: string,
): FreightPermissionSeed => ({
  id,
  key,
  name: { am: en, en },
  applicationKey: EDR_FREIGHT_APP_KEY,
});

export const BOOKING_PERMISSIONS: FreightPermissionSeed[] = [
  perm('a1000001-0001-4000-8000-000000000001', 'edr_freight_app:bookings:view', 'View bookings'),
  perm('a1000001-0001-4000-8000-000000000002', 'edr_freight_app:bookings:staff_accept', 'Accept booking intake'),
  perm('a1000001-0001-4000-8000-000000000003', 'edr_freight_app:bookings:request_changes', 'Request booking changes'),
  perm('a1000001-0001-4000-8000-000000000004', 'edr_freight_app:bookings:reject', 'Reject booking submission'),
  perm('a1000001-0001-4000-8000-000000000005', 'edr_freight_app:bookings:approve_line_staff', 'Approve as line staff'),
  perm('a1000001-0001-4000-8000-000000000006', 'edr_freight_app:bookings:approve_director', 'Approve as director'),
  perm('a1000001-0001-4000-8000-000000000007', 'edr_freight_app:bookings:approve_ceo', 'Approve as CEO'),
  perm('a1000001-0001-4000-8000-000000000008', 'edr_freight_app:bookings:reject_approval', 'Reject at approval step'),
  perm('a1000001-0001-4000-8000-000000000009', 'edr_freight_app:bookings:generate_contract', 'Generate contract'),
  perm('a1000001-0001-4000-8000-00000000000a', 'edr_freight_app:bookings:sign_staff', 'Staff contract signature'),
  perm('a1000001-0001-4000-8000-00000000000b', 'edr_freight_app:bookings:payment_pnr', 'Generate PNR'),
  perm('a1000001-0001-4000-8000-00000000000c', 'edr_freight_app:bookings:payment_verify', 'Verify payment'),
  perm('a1000001-0001-4000-8000-00000000000d', 'edr_freight_app:bookings:operations', 'Booking operations'),
  perm('a1000001-0001-4000-8000-00000000000e', 'edr_freight_app:bookings:cancel', 'Cancel booking'),
  perm('a1000001-0001-4000-8000-000000000023', 'edr_freight_app:bookings:clearance_view', 'View customs-clearance queue'),
  perm('a1000001-0001-4000-8000-000000000020', 'edr_freight_app:bookings:review_documents', 'Review clearance documents'),
  perm('a1000001-0001-4000-8000-000000000021', 'edr_freight_app:bookings:upload_clearance_output', 'Upload customs output documents'),
  perm('a1000001-0001-4000-8000-000000000022', 'edr_freight_app:bookings:finalize_clearance', 'Finalize document clearance'),
  perm('a1000001-0001-4000-8000-00000000000f', 'edr_freight_app:train_scheduling:view', 'View train scheduling'),
  perm('a1000001-0001-4000-8000-000000000011', 'edr_freight_app:fleet:view', 'View fleet'),
  perm('a1000001-0001-4000-8000-000000000012', 'edr_freight_app:fleet:manage', 'Manage fleet'),
  perm('a1000001-0001-4000-8000-000000000013', 'edr_freight_app:admin', 'Freight administration'),
  perm('a1000001-0001-4000-8000-000000000024', 'edr_freight_app:bookings:create', 'Create booking'),
  // Header alarm for the document-review deadline: its own key so only the
  // position types that actually decide operation requests are alerted.
  perm('a1000001-0001-4000-8000-000000000025', 'edr_freight_app:bookings:doc_review_alert', 'See document-review deadline alarm'),
];

/**
 * Contract-phase permissions (contract–booking separation). Mirror the booking
 * approval/sign/clearance permissions but scoped to the new contracts module.
 */
export const CONTRACT_PERMISSIONS: FreightPermissionSeed[] = [
  perm('a3000001-0001-4000-8000-000000000001', 'edr_freight_app:contracts:view', 'View contracts'),
  // Intake actions are split per freight type (bulk vs container) — fresh ids
  // because the seeder upserts ON CONFLICT (key); reusing the old ids with new
  // keys would PK-collide with the legacy staff_accept/request_changes/reject rows.
  perm('a3000001-0001-4000-8000-000000000011', 'edr_freight_app:contracts:staff_accept:bulk', 'Accept bulk contract intake'),
  perm('a3000001-0001-4000-8000-000000000012', 'edr_freight_app:contracts:staff_accept:container', 'Accept container contract intake'),
  perm('a3000001-0001-4000-8000-000000000013', 'edr_freight_app:contracts:request_changes:bulk', 'Request bulk contract changes'),
  perm('a3000001-0001-4000-8000-000000000014', 'edr_freight_app:contracts:request_changes:container', 'Request container contract changes'),
  perm('a3000001-0001-4000-8000-000000000015', 'edr_freight_app:contracts:reject:bulk', 'Reject bulk contract'),
  perm('a3000001-0001-4000-8000-000000000016', 'edr_freight_app:contracts:reject:container', 'Reject container contract'),
  perm('a3000001-0001-4000-8000-000000000005', 'edr_freight_app:contracts:approve_line_staff', 'Approve contract as line staff'),
  perm('a3000001-0001-4000-8000-000000000006', 'edr_freight_app:contracts:approve_director', 'Approve contract as director'),
  perm('a3000001-0001-4000-8000-000000000007', 'edr_freight_app:contracts:approve_ceo', 'Approve contract as CEO'),
  perm('a3000001-0001-4000-8000-000000000008', 'edr_freight_app:contracts:generate_contract', 'Generate contract document'),
  // Staff counter-signature is split per freight type too — fresh ids for the
  // same reason as the intake keys above.
  perm('a3000001-0001-4000-8000-000000000017', 'edr_freight_app:contracts:sign_staff:bulk', 'Staff contract signature: bulk'),
  perm('a3000001-0001-4000-8000-000000000018', 'edr_freight_app:contracts:sign_staff:container', 'Staff contract signature: container'),
  perm('a3000001-0001-4000-8000-00000000000a', 'edr_freight_app:contracts:clearance_review', 'Review pre-booking clearance docs'),
  perm('a3000001-0001-4000-8000-00000000000b', 'edr_freight_app:contracts:finalize_clearance', 'Finalize pre-booking clearance'),
  perm('a3000001-0001-4000-8000-00000000000c', 'edr_freight_app:contracts:create_booking', 'GL ET create booking under contract'),
  perm('a3000001-0001-4000-8000-00000000000d', 'edr_freight_app:contracts:ops_clearance_review', 'Operations review of self-clearance docs (Path A)'),
  perm('a3000001-0001-4000-8000-00000000000e', 'edr_freight_app:contracts:clearance_et_actions', 'GL Ethiopia phased clearance actions'),
  perm('a3000001-0001-4000-8000-00000000000f', 'edr_freight_app:contracts:clearance_dj_actions', 'GL Djibouti phased clearance actions'),
  perm('a3000001-0001-4000-8000-000000000010', 'edr_freight_app:contracts:clearance_duty_advise', 'Advise contract duty/tax'),
  // Hazardous contracts get two extra approval steps ahead of the normal chain.
  // Each has its own permission so the two desks are genuinely separate people.
  perm('a3000001-0001-4000-8000-000000000019', 'edr_freight_app:contracts:hazardous_approval_one', 'Hazardous approval — first review'),
  perm('a3000001-0001-4000-8000-00000000001a', 'edr_freight_app:contracts:hazardous_approval_two', 'Hazardous approval — second review'),
];

// Existing per-slug view ids are kept as-is: position-type grants reference
// them by id, so re-minting would orphan those rows.
const RULE_ENGINE_VIEW_IDS: Record<RuleEngineResourceSlug, string> = {
  'cargo-types': 'b2000001-0001-4000-8000-000000000001',
  'container-types': 'b2000001-0001-4000-8000-000000000003',
  'wagon-types': 'b2000001-0001-4000-8000-000000000015',
  'truck-types': 'b2000001-0001-4000-8000-00000000001a',
  'service-types': 'b2000001-0001-4000-8000-000000000005',
  yards: 'b2000001-0001-4000-8000-000000000007',
  'shipping-lines': 'b2000001-0001-4000-8000-000000000009',
  'weight-limit-rules': 'b2000001-0001-4000-8000-00000000000b',
  'priority-configs': 'b2000001-0001-4000-8000-00000000000f',
  rates: 'b2000001-0001-4000-8000-000000000011',
  'approval-rules': 'b2000001-0001-4000-8000-000000000013',
  'yard-distances': 'b2000001-0001-4000-8000-000000000018',
};

// CRUD replaces the retired coarse `:manage`. New ids live in a fresh block
// (b2000002-…) so a stale `:manage` grant can never silently confer a CRUD
// action — the migration re-grants create/update/delete explicitly.
const RULE_ENGINE_CRUD_ACTIONS = ['create', 'update', 'delete'] as const;
type RuleEngineCrudAction = (typeof RULE_ENGINE_CRUD_ACTIONS)[number];
const ruleEngineCrudId = (
  slug: RuleEngineResourceSlug,
  action: RuleEngineCrudAction,
): string => {
  const n =
    RULE_ENGINE_RESOURCE_SLUGS.indexOf(slug) * 3 +
    RULE_ENGINE_CRUD_ACTIONS.indexOf(action) +
    1; // 1..36
  return `b2000002-0001-4000-8000-${n.toString(16).padStart(12, '0')}`;
};

/**
 * Slugs whose changes go through a separate approver. CRUD lets a staff member
 * propose a change; only `approve` lets someone put it into effect. Only listed
 * slugs get the permission.
 */
const RULE_ENGINE_APPROVE_PERMISSION_IDS: Partial<Record<RuleEngineResourceSlug, string>> = {
  rates: 'b2000001-0001-4000-8000-000000000017',
};

export type RuleEngineApprovableSlug = 'rates';

export const RULE_ENGINE_PERMISSIONS: FreightPermissionSeed[] = RULE_ENGINE_RESOURCE_SLUGS.flatMap(
  (slug) => {
    const resource = slugToResourceKey(slug);
    const approveId = RULE_ENGINE_APPROVE_PERMISSION_IDS[slug];
    return [
      perm(RULE_ENGINE_VIEW_IDS[slug], `edr_freight_app:rule_engine:${resource}:view`, `View ${slug}`),
      perm(ruleEngineCrudId(slug, 'create'), `edr_freight_app:rule_engine:${resource}:create`, `Create ${slug}`),
      perm(ruleEngineCrudId(slug, 'update'), `edr_freight_app:rule_engine:${resource}:update`, `Update ${slug}`),
      perm(ruleEngineCrudId(slug, 'delete'), `edr_freight_app:rule_engine:${resource}:delete`, `Delete ${slug}`),
      ...(approveId
        ? [perm(approveId, `edr_freight_app:rule_engine:${resource}:approve`, `Approve ${slug} changes`)]
        : []),
    ];
  },
);

/**
 * Container-allocation permission for the previously-unguarded
 * booking allocate-containers endpoint.
 */
export const GAP_CONTROLLER_PERMISSIONS: FreightPermissionSeed[] = [
  perm('c1000001-0001-4000-8000-000000000001', 'edr_freight_app:allocation:manage', 'Allocate containers to vehicles'),
];

/**
 * Advanced backoffice resources — full CRUD + workflow-action keys.
 * See docs/rbac/freight-backoffice-permissions.md. Additive only: the existing
 * bookings/contracts/rule-engine/allocation keys above are unchanged.
 */

// C. Customers
export const CUSTOMER_PERMISSIONS: FreightPermissionSeed[] = [
  perm('d1a00001-0001-4000-8000-000000000001', 'edr_freight_app:customers:view', 'View customers'),
  perm('d1a00001-0001-4000-8000-000000000002', 'edr_freight_app:customers:create', 'Create customer'),
  perm('d1a00001-0001-4000-8000-000000000003', 'edr_freight_app:customers:update', 'Update customer'),
  perm('d1a00001-0001-4000-8000-000000000004', 'edr_freight_app:customers:deactivate', 'Deactivate customer'),
  perm('d1a00001-0001-4000-8000-000000000005', 'edr_freight_app:customers:verify', 'Verify customer (KYC/Fayda)'),
  perm('d1a00001-0001-4000-8000-000000000006', 'edr_freight_app:customers:reset-password', 'Trigger customer password reset'),
];

// D. Finance — payments + invoices
export const FINANCE_PERMISSIONS: FreightPermissionSeed[] = [
  perm('d2a00001-0001-4000-8000-000000000001', 'edr_freight_app:payments:view', 'View payments'),
  perm('d2a00001-0001-4000-8000-000000000002', 'edr_freight_app:payments:verify', 'Verify/settle payment'),
  perm('d2a00001-0001-4000-8000-000000000003', 'edr_freight_app:payments:refund', 'Refund payment'),
  perm('d2b00001-0001-4000-8000-000000000001', 'edr_freight_app:invoices:view', 'View invoices'),
  perm('d2b00001-0001-4000-8000-000000000002', 'edr_freight_app:invoices:create', 'Generate invoice'),
  perm('d2b00001-0001-4000-8000-000000000003', 'edr_freight_app:invoices:cancel', 'Cancel invoice'),
  perm('d2b00001-0001-4000-8000-000000000004', 'edr_freight_app:invoices:export', 'Download invoice document'),
];

// E. First / last mile operations
export const MILE_PERMISSIONS: FreightPermissionSeed[] = [
  perm('d3a00001-0001-4000-8000-000000000001', 'edr_freight_app:first_mile:view', 'View first-mile'),
  perm('d3a00001-0001-4000-8000-000000000002', 'edr_freight_app:first_mile:accept', 'Accept first-mile request'),
  perm('d3a00001-0001-4000-8000-000000000003', 'edr_freight_app:first_mile:create', 'Create first-mile'),
  perm('d3a00001-0001-4000-8000-000000000004', 'edr_freight_app:first_mile:update', 'Update first-mile'),
  perm('d3a00001-0001-4000-8000-000000000005', 'edr_freight_app:first_mile:delete', 'Delete first-mile'),
  perm('d3a00001-0001-4000-8000-000000000006', 'edr_freight_app:first_mile:assign_vehicles', 'Assign first-mile vehicles'),
  perm('d3a00001-0001-4000-8000-000000000007', 'edr_freight_app:first_mile:set_distances', 'Set first-mile distances'),
  perm('d3a00001-0001-4000-8000-000000000008', 'edr_freight_app:first_mile:generate_invoice', 'Generate first-mile invoice'),
  perm('d3b00001-0001-4000-8000-000000000001', 'edr_freight_app:last_mile:view', 'View last-mile'),
  perm('d3b00001-0001-4000-8000-000000000002', 'edr_freight_app:last_mile:accept', 'Accept last-mile request'),
  perm('d3b00001-0001-4000-8000-000000000003', 'edr_freight_app:last_mile:create', 'Create last-mile'),
  perm('d3b00001-0001-4000-8000-000000000004', 'edr_freight_app:last_mile:update', 'Update last-mile'),
  perm('d3b00001-0001-4000-8000-000000000005', 'edr_freight_app:last_mile:delete', 'Delete last-mile'),
  perm('d3b00001-0001-4000-8000-000000000006', 'edr_freight_app:last_mile:assign_vehicles', 'Assign last-mile vehicles'),
  perm('d3b00001-0001-4000-8000-000000000007', 'edr_freight_app:last_mile:set_distances', 'Set last-mile distances'),
  perm('d3b00001-0001-4000-8000-000000000008', 'edr_freight_app:last_mile:generate_invoice', 'Generate last-mile invoice'),
];

// F. Fleet — rail assets (splits the flat fleet:view/manage)
export const FLEET_RAIL_PERMISSIONS: FreightPermissionSeed[] = [
  perm('e1a00001-0001-4000-8000-000000000001', 'edr_freight_app:locomotives:view', 'View locomotives'),
  perm('e1a00001-0001-4000-8000-000000000002', 'edr_freight_app:locomotives:create', 'Create locomotive'),
  perm('e1a00001-0001-4000-8000-000000000003', 'edr_freight_app:locomotives:update', 'Update locomotive'),
  perm('e1a00001-0001-4000-8000-000000000004', 'edr_freight_app:locomotives:delete', 'Delete locomotive'),
  perm('e1b00001-0001-4000-8000-000000000001', 'edr_freight_app:wagons:view', 'View wagons'),
  perm('e1b00001-0001-4000-8000-000000000002', 'edr_freight_app:wagons:create', 'Create wagon'),
  perm('e1b00001-0001-4000-8000-000000000003', 'edr_freight_app:wagons:update', 'Update wagon'),
  perm('e1b00001-0001-4000-8000-000000000004', 'edr_freight_app:wagons:delete', 'Delete wagon'),
  perm('e1b00001-0001-4000-8000-000000000005', 'edr_freight_app:wagons:transfer_request', 'Request wagon transfer'),
  perm('e1b00001-0001-4000-8000-000000000006', 'edr_freight_app:wagons:transfer_fulfill', 'Fulfil wagon transfer (OCC)'),
  perm('e1b00001-0001-4000-8000-000000000007', 'edr_freight_app:wagons:transfer_history_all', "View all staff's transfer history"),
  // The transfer desk is its own screen, so it carries its own per-action keys —
  // seeing the queue, withdrawing a request and short-closing one are separate
  // grants from filing or fulfilling.
  perm('e1b00001-0001-4000-8000-000000000008', 'edr_freight_app:wagons:transfer_view', 'View wagon transfer requests'),
  perm('e1b00001-0001-4000-8000-000000000009', 'edr_freight_app:wagons:transfer_cancel', 'Withdraw a wagon transfer request'),
  perm('e1b00001-0001-4000-8000-00000000000a', 'edr_freight_app:wagons:transfer_close_short', 'Close a transfer request short of the requested count'),
  perm('e1c00001-0001-4000-8000-000000000001', 'edr_freight_app:trains:view', 'View trains'),
  perm('e1c00001-0001-4000-8000-000000000002', 'edr_freight_app:trains:create', 'Create train'),
  perm('e1c00001-0001-4000-8000-000000000003', 'edr_freight_app:trains:update', 'Update train'),
  perm('e1c00001-0001-4000-8000-000000000004', 'edr_freight_app:trains:delete', 'Delete train'),
  perm('e1c00001-0001-4000-8000-000000000005', 'edr_freight_app:trains:assign_wagons', 'Assign wagons to train'),
  perm('e1d00001-0001-4000-8000-000000000001', 'edr_freight_app:routes:view', 'View routes'),
  perm('e1d00001-0001-4000-8000-000000000002', 'edr_freight_app:routes:create', 'Create route'),
  perm('e1d00001-0001-4000-8000-000000000003', 'edr_freight_app:routes:update', 'Update route'),
  perm('e1d00001-0001-4000-8000-000000000004', 'edr_freight_app:routes:delete', 'Delete route'),
  perm('e1e00001-0001-4000-8000-000000000001', 'edr_freight_app:containers:view', 'View containers'),
  perm('e1e00001-0001-4000-8000-000000000002', 'edr_freight_app:containers:create', 'Create container'),
  perm('e1e00001-0001-4000-8000-000000000003', 'edr_freight_app:containers:update', 'Update container'),
  perm('e1e00001-0001-4000-8000-000000000004', 'edr_freight_app:containers:delete', 'Delete container'),
  perm('e1f00001-0001-4000-8000-000000000001', 'edr_freight_app:cargoes:view', 'View cargoes'),
  perm('e1f00001-0001-4000-8000-000000000002', 'edr_freight_app:cargoes:create', 'Create cargo'),
  perm('e1f00001-0001-4000-8000-000000000003', 'edr_freight_app:cargoes:update', 'Update cargo'),
  perm('e1f00001-0001-4000-8000-000000000004', 'edr_freight_app:cargoes:delete', 'Delete cargo'),
  // NB: id prefixes must stay hex — 'e1g…' once crashed the boot seeder
  // (postgres: invalid input syntax for type uuid).
  perm('e1900001-0001-4000-8000-000000000001', 'edr_freight_app:consignments:view', 'View consignments'),
  perm('e1900001-0001-4000-8000-000000000002', 'edr_freight_app:consignments:create', 'Create consignment'),
];

// G. Fleet — road & telemetry
export const FLEET_ROAD_PERMISSIONS: FreightPermissionSeed[] = [
  perm('e2a00001-0001-4000-8000-000000000001', 'edr_freight_app:vehicles:view', 'View vehicles'),
  perm('e2a00001-0001-4000-8000-000000000002', 'edr_freight_app:vehicles:create', 'Create vehicle'),
  perm('e2a00001-0001-4000-8000-000000000003', 'edr_freight_app:vehicles:update', 'Update vehicle'),
  perm('e2a00001-0001-4000-8000-000000000004', 'edr_freight_app:vehicles:delete', 'Delete vehicle'),
  perm('e2b00001-0001-4000-8000-000000000001', 'edr_freight_app:drivers:view', 'View drivers'),
  perm('e2b00001-0001-4000-8000-000000000002', 'edr_freight_app:drivers:create', 'Create driver'),
  perm('e2b00001-0001-4000-8000-000000000003', 'edr_freight_app:drivers:update', 'Update driver'),
  perm('e2b00001-0001-4000-8000-000000000004', 'edr_freight_app:drivers:delete', 'Delete driver'),
  perm('e2c00001-0001-4000-8000-000000000001', 'edr_freight_app:tracking:view', 'Track vehicles'),
  perm('e2c00001-0001-4000-8000-000000000002', 'edr_freight_app:tracking:manage', 'Manage GPS trackers'),
  perm('e2d00001-0001-4000-8000-000000000001', 'edr_freight_app:fuel:view', 'View fuel purchases'),
  perm('e2d00001-0001-4000-8000-000000000002', 'edr_freight_app:fuel:create', 'Create fuel purchase'),
  perm('e2d00001-0001-4000-8000-000000000003', 'edr_freight_app:fuel:update', 'Update fuel purchase'),
  perm('e2d00001-0001-4000-8000-000000000004', 'edr_freight_app:fuel:delete', 'Delete fuel purchase'),
  perm('e2d00001-0001-4000-8000-000000000005', 'edr_freight_app:fuel:approve', 'Approve fuel purchase'),
  perm('e2e00001-0001-4000-8000-000000000001', 'edr_freight_app:maintenance:view', 'View maintenance'),
  perm('e2e00001-0001-4000-8000-000000000002', 'edr_freight_app:maintenance:create', 'Create maintenance'),
  perm('e2e00001-0001-4000-8000-000000000003', 'edr_freight_app:maintenance:update', 'Update maintenance'),
  perm('e2e00001-0001-4000-8000-000000000004', 'edr_freight_app:maintenance:delete', 'Delete maintenance'),
  perm('e2e00001-0001-4000-8000-000000000005', 'edr_freight_app:maintenance:complete', 'Complete maintenance'),
  perm('e2f00001-0001-4000-8000-000000000001', 'edr_freight_app:fleet_reports:view', 'View fleet financial reports'),
  perm('e2f00001-0001-4000-8000-000000000002', 'edr_freight_app:fleet_reports:export', 'Export fleet financial reports'),
  perm('e2000001-0001-4000-8000-000000000001', 'edr_freight_app:fleet_dashboard:view', 'View fleet dashboard'),
];

// H. Warehouse management
export const WAREHOUSE_PERMISSIONS: FreightPermissionSeed[] = [
  perm('f1000001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_dashboard:view', 'View warehouse dashboard'),
  perm('f1a00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouses:view', 'View warehouses'),
  perm('f1a00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouses:create', 'Create warehouse'),
  perm('f1a00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouses:update', 'Update warehouse'),
  perm('f1a00001-0001-4000-8000-000000000004', 'edr_freight_app:warehouses:delete', 'Delete warehouse'),
  perm('f1b00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_yards:view', 'View warehouse yards'),
  perm('f1b00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouse_yards:create', 'Create warehouse yard'),
  perm('f1b00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouse_yards:update', 'Update warehouse yard'),
  perm('f1b00001-0001-4000-8000-000000000004', 'edr_freight_app:warehouse_yards:delete', 'Delete warehouse yard'),
  perm('f1c00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_zones:view', 'View warehouse zones'),
  perm('f1c00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouse_zones:create', 'Create warehouse zone'),
  perm('f1c00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouse_zones:update', 'Update warehouse zone'),
  perm('f1d00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_allocation_rules:view', 'View allocation rules'),
  perm('f1d00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouse_allocation_rules:create', 'Create allocation rule'),
  perm('f1d00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouse_allocation_rules:update', 'Update allocation rule'),
  perm('f1d00001-0001-4000-8000-000000000004', 'edr_freight_app:warehouse_allocation_rules:delete', 'Delete allocation rule'),
  perm('f1e00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_fee_rules:view', 'View fee rules'),
  perm('f1e00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouse_fee_rules:create', 'Create fee rule'),
  perm('f1e00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouse_fee_rules:update', 'Update fee rule'),
  perm('f1e00001-0001-4000-8000-000000000004', 'edr_freight_app:warehouse_fee_rules:delete', 'Delete fee rule'),
  perm('f1f00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_inspection_reports:view', 'View inspection reports'),
  perm('f1f00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouse_inspection_reports:create', 'Create inspection report'),
  perm('f1f00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouse_inspection_reports:update', 'Update inspection report'),
];

// I. Port & terminal — inventory movement + interchange + fee invoices
export const PORT_TERMINAL_PERMISSIONS: FreightPermissionSeed[] = [
  perm('f2a00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_inventory:view', 'View terminal inventory'),
  perm('f2a00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouse_inventory:receive', 'Receive inventory'),
  perm('f2a00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouse_inventory:move', 'Move/store/reserve inventory'),
  perm('f2a00001-0001-4000-8000-000000000004', 'edr_freight_app:warehouse_inventory:load', 'Load inventory'),
  perm('f2a00001-0001-4000-8000-000000000005', 'edr_freight_app:warehouse_inventory:unload', 'Unload inventory'),
  perm('f2a00001-0001-4000-8000-000000000006', 'edr_freight_app:warehouse_inventory:dispatch', 'Dispatch inventory'),
  perm('f2a00001-0001-4000-8000-000000000007', 'edr_freight_app:warehouse_inventory:gate_pass', 'Gate-clearance inventory'),
  perm('f2a00001-0001-4000-8000-000000000008', 'edr_freight_app:warehouse_inventory:release', 'Release inventory'),
  perm('f2a00001-0001-4000-8000-000000000009', 'edr_freight_app:warehouse_inventory:deliver', 'Deliver inventory'),
  perm('f2a00001-0001-4000-8000-00000000000a', 'edr_freight_app:warehouse_inventory:inspect', 'Inspect inventory'),
  perm('f2b00001-0001-4000-8000-000000000001', 'edr_freight_app:interchange_documents:view', 'View interchange documents'),
  perm('f2b00001-0001-4000-8000-000000000002', 'edr_freight_app:interchange_documents:generate', 'Generate interchange document'),
  perm('f2b00001-0001-4000-8000-000000000003', 'edr_freight_app:interchange_documents:acknowledge', 'Acknowledge interchange document'),
  perm('f2b00001-0001-4000-8000-000000000004', 'edr_freight_app:interchange_documents:dispute', 'Dispute interchange document'),
  perm('f2b00001-0001-4000-8000-000000000005', 'edr_freight_app:interchange_documents:cancel', 'Cancel interchange document'),
  perm('f2c00001-0001-4000-8000-000000000001', 'edr_freight_app:warehouse_fee_invoices:view', 'View warehouse fee invoices'),
  perm('f2c00001-0001-4000-8000-000000000002', 'edr_freight_app:warehouse_fee_invoices:generate', 'Generate warehouse fee invoice'),
  perm('f2c00001-0001-4000-8000-000000000003', 'edr_freight_app:warehouse_fee_invoices:cancel', 'Cancel warehouse fee invoice'),
  perm('f2c00001-0001-4000-8000-000000000004', 'edr_freight_app:warehouse_fee_invoices:pay', 'Pay warehouse fee invoice'),
];

// E'. Train-scheduling finer actions (augment existing view/manage)
export const SCHEDULING_EXTRA_PERMISSIONS: FreightPermissionSeed[] = [
  perm('a2a00001-0001-4000-8000-000000000001', 'edr_freight_app:train_scheduling:create', 'Create train schedule'),
  perm('a2a00001-0001-4000-8000-000000000002', 'edr_freight_app:train_scheduling:update', 'Update train schedule'),
  perm('a2a00001-0001-4000-8000-000000000003', 'edr_freight_app:train_scheduling:cancel', 'Cancel train schedule'),
  perm('a2a00001-0001-4000-8000-000000000004', 'edr_freight_app:train_scheduling:reschedule', 'Reschedule train'),
  perm('a2a00001-0001-4000-8000-000000000005', 'edr_freight_app:train_scheduling:rules_manage', 'Manage global scheduling rules'),
];

// L. Administration & settings (split from the coarse admin umbrella)
export const CONFIG_SETTINGS_PERMISSIONS: FreightPermissionSeed[] = [
  perm('b4a00001-0001-4000-8000-000000000001', 'edr_freight_app:settings:file_upload:view', 'View file-upload settings'),
  perm('b4a00001-0001-4000-8000-000000000002', 'edr_freight_app:settings:file_upload:manage', 'Manage file-upload settings'),
  perm('b4b00001-0001-4000-8000-000000000001', 'edr_freight_app:settings:dropdown:view', 'View dropdown settings'),
  perm('b4b00001-0001-4000-8000-000000000002', 'edr_freight_app:settings:dropdown:manage', 'Manage dropdown settings'),
];

// M. Staff / IAM admin — NEW keys only. The employee_registration / role_assignment
// / hierarchy_* / position_types:view keys are seeded separately in edr-freight.seed.ts.
export const STAFF_IAM_PERMISSIONS: FreightPermissionSeed[] = [
  perm('c2a00001-0001-4000-8000-000000000001', 'edr_freight_app:staff:roles:view', 'View roles'),
  perm('c2a00001-0001-4000-8000-000000000002', 'edr_freight_app:staff:roles:create', 'Create role'),
  perm('c2a00001-0001-4000-8000-000000000003', 'edr_freight_app:staff:roles:update', 'Update role'),
  perm('c2a00001-0001-4000-8000-000000000004', 'edr_freight_app:staff:roles:delete', 'Delete role'),
  perm('c2b00001-0001-4000-8000-000000000001', 'edr_freight_app:staff:permissions:view', 'View permission assignments'),
  perm('c2b00001-0001-4000-8000-000000000002', 'edr_freight_app:staff:permissions:assign', 'Assign permissions'),
  perm('c2c00001-0001-4000-8000-000000000001', 'edr_freight_app:position_types:create', 'Create position type'),
  perm('c2c00001-0001-4000-8000-000000000002', 'edr_freight_app:position_types:update', 'Update position type'),
  perm('c2c00001-0001-4000-8000-000000000003', 'edr_freight_app:position_types:delete', 'Delete position type'),
];

export const ADVANCED_BACKOFFICE_PERMISSIONS: FreightPermissionSeed[] = [
  ...CUSTOMER_PERMISSIONS,
  ...FINANCE_PERMISSIONS,
  ...MILE_PERMISSIONS,
  ...FLEET_RAIL_PERMISSIONS,
  ...FLEET_ROAD_PERMISSIONS,
  ...WAREHOUSE_PERMISSIONS,
  ...PORT_TERMINAL_PERMISSIONS,
  ...SCHEDULING_EXTRA_PERMISSIONS,
  ...CONFIG_SETTINGS_PERMISSIONS,
  ...STAFF_IAM_PERMISSIONS,
];

export const BOOKING_RULE_ENGINE_PERMISSIONS = [
  ...BOOKING_PERMISSIONS,
  ...CONTRACT_PERMISSIONS,
  ...RULE_ENGINE_PERMISSIONS,
  ...GAP_CONTROLLER_PERMISSIONS,
  ...ADVANCED_BACKOFFICE_PERMISSIONS,
];

export const BOOKING_RULE_ENGINE_PERMISSION_KEYS = BOOKING_RULE_ENGINE_PERMISSIONS.map(
  (p) => p.key,
);

export const FREIGHT_PERMS = {
  bookings: {
    view: 'edr_freight_app:bookings:view',
    create: 'edr_freight_app:bookings:create',
    clearanceView: 'edr_freight_app:bookings:clearance_view',
    staffAccept: 'edr_freight_app:bookings:staff_accept',
    requestChanges: 'edr_freight_app:bookings:request_changes',
    reject: 'edr_freight_app:bookings:reject',
    approveLineStaff: 'edr_freight_app:bookings:approve_line_staff',
    approveDirector: 'edr_freight_app:bookings:approve_director',
    approveCeo: 'edr_freight_app:bookings:approve_ceo',
    rejectApproval: 'edr_freight_app:bookings:reject_approval',
    generateContract: 'edr_freight_app:bookings:generate_contract',
    signStaff: 'edr_freight_app:bookings:sign_staff',
    operations: 'edr_freight_app:bookings:operations',
    cancel: 'edr_freight_app:bookings:cancel',
    reviewDocuments: 'edr_freight_app:bookings:review_documents',
    uploadClearanceOutput: 'edr_freight_app:bookings:upload_clearance_output',
    finalizeClearance: 'edr_freight_app:bookings:finalize_clearance',
    docReviewAlert: 'edr_freight_app:bookings:doc_review_alert',
  },
  contracts: {
    view: 'edr_freight_app:contracts:view',
    staffAccept: {
      bulk: 'edr_freight_app:contracts:staff_accept:bulk',
      container: 'edr_freight_app:contracts:staff_accept:container',
    },
    requestChanges: {
      bulk: 'edr_freight_app:contracts:request_changes:bulk',
      container: 'edr_freight_app:contracts:request_changes:container',
    },
    reject: {
      bulk: 'edr_freight_app:contracts:reject:bulk',
      container: 'edr_freight_app:contracts:reject:container',
    },
    approveLineStaff: 'edr_freight_app:contracts:approve_line_staff',
    approveDirector: 'edr_freight_app:contracts:approve_director',
    approveCeo: 'edr_freight_app:contracts:approve_ceo',
    hazardousApprovalOne: 'edr_freight_app:contracts:hazardous_approval_one',
    hazardousApprovalTwo: 'edr_freight_app:contracts:hazardous_approval_two',
    generateContract: 'edr_freight_app:contracts:generate_contract',
    signStaff: {
      bulk: 'edr_freight_app:contracts:sign_staff:bulk',
      container: 'edr_freight_app:contracts:sign_staff:container',
    },
    clearanceReview: 'edr_freight_app:contracts:clearance_review',
    finalizeClearance: 'edr_freight_app:contracts:finalize_clearance',
    createBooking: 'edr_freight_app:contracts:create_booking',
    opsClearanceReview: 'edr_freight_app:contracts:ops_clearance_review',
    clearanceEtActions: 'edr_freight_app:contracts:clearance_et_actions',
    clearanceDjActions: 'edr_freight_app:contracts:clearance_dj_actions',
    clearanceDutyAdvise: 'edr_freight_app:contracts:clearance_duty_advise',
  },
  trainScheduling: {
    view: 'edr_freight_app:train_scheduling:view',
    create: 'edr_freight_app:train_scheduling:create',
    update: 'edr_freight_app:train_scheduling:update',
    cancel: 'edr_freight_app:train_scheduling:cancel',
    reschedule: 'edr_freight_app:train_scheduling:reschedule',
    rulesManage: 'edr_freight_app:train_scheduling:rules_manage',
  },
  fleet: {
    view: 'edr_freight_app:fleet:view',
    manage: 'edr_freight_app:fleet:manage',
  },
  admin: 'edr_freight_app:admin',
  ruleEngine: {
    view: (slug: RuleEngineResourceSlug) =>
      `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:view`,
    create: (slug: RuleEngineResourceSlug) =>
      `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:create`,
    update: (slug: RuleEngineResourceSlug) =>
      `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:update`,
    delete: (slug: RuleEngineResourceSlug) =>
      `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:delete`,
    approve: (slug: RuleEngineApprovableSlug) =>
      `edr_freight_app:rule_engine:${slugToResourceKey(slug)}:approve`,
  },
  allocation: {
    manage: 'edr_freight_app:allocation:manage',
  },
  customers: {
    view: 'edr_freight_app:customers:view',
    create: 'edr_freight_app:customers:create',
    update: 'edr_freight_app:customers:update',
    deactivate: 'edr_freight_app:customers:deactivate',
    verify: 'edr_freight_app:customers:verify',
    resetPassword: 'edr_freight_app:customers:reset-password',
  },
  payments: {
    view: 'edr_freight_app:payments:view',
    verify: 'edr_freight_app:payments:verify',
    refund: 'edr_freight_app:payments:refund',
  },
  invoices: {
    view: 'edr_freight_app:invoices:view',
    create: 'edr_freight_app:invoices:create',
    cancel: 'edr_freight_app:invoices:cancel',
    export: 'edr_freight_app:invoices:export',
  },
  firstMile: {
    view: 'edr_freight_app:first_mile:view',
    accept: 'edr_freight_app:first_mile:accept',
    create: 'edr_freight_app:first_mile:create',
    update: 'edr_freight_app:first_mile:update',
    delete: 'edr_freight_app:first_mile:delete',
    assignVehicles: 'edr_freight_app:first_mile:assign_vehicles',
    setDistances: 'edr_freight_app:first_mile:set_distances',
    generateInvoice: 'edr_freight_app:first_mile:generate_invoice',
  },
  lastMile: {
    view: 'edr_freight_app:last_mile:view',
    accept: 'edr_freight_app:last_mile:accept',
    create: 'edr_freight_app:last_mile:create',
    update: 'edr_freight_app:last_mile:update',
    delete: 'edr_freight_app:last_mile:delete',
    assignVehicles: 'edr_freight_app:last_mile:assign_vehicles',
    setDistances: 'edr_freight_app:last_mile:set_distances',
    generateInvoice: 'edr_freight_app:last_mile:generate_invoice',
  },
  locomotives: {
    view: 'edr_freight_app:locomotives:view',
    create: 'edr_freight_app:locomotives:create',
    update: 'edr_freight_app:locomotives:update',
    delete: 'edr_freight_app:locomotives:delete',
  },
  wagons: {
    view: 'edr_freight_app:wagons:view',
    create: 'edr_freight_app:wagons:create',
    update: 'edr_freight_app:wagons:update',
    delete: 'edr_freight_app:wagons:delete',
    // Requester creates a transfer request; OCC fulfils it (picks the wagons and
    // executes the move). Distinct keys so OCC can hold fulfil without request.
    transferRequest: 'edr_freight_app:wagons:transfer_request',
    transferFulfill: 'edr_freight_app:wagons:transfer_fulfill',
    /** Open the transfer-requests desk (list + detail). */
    transferView: 'edr_freight_app:wagons:transfer_view',
    /** Withdraw a request that has not moved any wagon yet. */
    transferCancel: 'edr_freight_app:wagons:transfer_cancel',
    /** End a request short — anyone who can fulfil may also do this. */
    transferCloseShort: 'edr_freight_app:wagons:transfer_close_short',
    // Admin: read every staffer's transfer history. Without it, a user only sees
    // their own (the /history endpoint uses the caller id, backend-enforced).
    transferHistoryAll: 'edr_freight_app:wagons:transfer_history_all',
  },
  trains: {
    view: 'edr_freight_app:trains:view',
    create: 'edr_freight_app:trains:create',
    update: 'edr_freight_app:trains:update',
    delete: 'edr_freight_app:trains:delete',
    assignWagons: 'edr_freight_app:trains:assign_wagons',
  },
  routes: {
    view: 'edr_freight_app:routes:view',
    create: 'edr_freight_app:routes:create',
    update: 'edr_freight_app:routes:update',
    delete: 'edr_freight_app:routes:delete',
  },
  containers: {
    view: 'edr_freight_app:containers:view',
    create: 'edr_freight_app:containers:create',
    update: 'edr_freight_app:containers:update',
    delete: 'edr_freight_app:containers:delete',
  },
  cargoes: {
    view: 'edr_freight_app:cargoes:view',
    create: 'edr_freight_app:cargoes:create',
    update: 'edr_freight_app:cargoes:update',
    delete: 'edr_freight_app:cargoes:delete',
  },
  consignments: {
    view: 'edr_freight_app:consignments:view',
    create: 'edr_freight_app:consignments:create',
  },
  vehicles: {
    view: 'edr_freight_app:vehicles:view',
    create: 'edr_freight_app:vehicles:create',
    update: 'edr_freight_app:vehicles:update',
    delete: 'edr_freight_app:vehicles:delete',
  },
  drivers: {
    view: 'edr_freight_app:drivers:view',
    create: 'edr_freight_app:drivers:create',
    update: 'edr_freight_app:drivers:update',
    delete: 'edr_freight_app:drivers:delete',
  },
  tracking: {
    view: 'edr_freight_app:tracking:view',
    manage: 'edr_freight_app:tracking:manage',
  },
  fuel: {
    view: 'edr_freight_app:fuel:view',
    create: 'edr_freight_app:fuel:create',
    update: 'edr_freight_app:fuel:update',
    delete: 'edr_freight_app:fuel:delete',
    approve: 'edr_freight_app:fuel:approve',
  },
  maintenance: {
    view: 'edr_freight_app:maintenance:view',
    create: 'edr_freight_app:maintenance:create',
    update: 'edr_freight_app:maintenance:update',
    delete: 'edr_freight_app:maintenance:delete',
    complete: 'edr_freight_app:maintenance:complete',
  },
  fleetReports: {
    view: 'edr_freight_app:fleet_reports:view',
    export: 'edr_freight_app:fleet_reports:export',
  },
  fleetDashboard: {
    view: 'edr_freight_app:fleet_dashboard:view',
  },
  warehouseDashboard: {
    view: 'edr_freight_app:warehouse_dashboard:view',
  },
  warehouses: {
    view: 'edr_freight_app:warehouses:view',
    create: 'edr_freight_app:warehouses:create',
    update: 'edr_freight_app:warehouses:update',
    delete: 'edr_freight_app:warehouses:delete',
  },
  warehouseYards: {
    view: 'edr_freight_app:warehouse_yards:view',
    create: 'edr_freight_app:warehouse_yards:create',
    update: 'edr_freight_app:warehouse_yards:update',
    delete: 'edr_freight_app:warehouse_yards:delete',
  },
  warehouseZones: {
    view: 'edr_freight_app:warehouse_zones:view',
    create: 'edr_freight_app:warehouse_zones:create',
    update: 'edr_freight_app:warehouse_zones:update',
  },
  warehouseAllocationRules: {
    view: 'edr_freight_app:warehouse_allocation_rules:view',
    create: 'edr_freight_app:warehouse_allocation_rules:create',
    update: 'edr_freight_app:warehouse_allocation_rules:update',
    delete: 'edr_freight_app:warehouse_allocation_rules:delete',
  },
  warehouseFeeRules: {
    view: 'edr_freight_app:warehouse_fee_rules:view',
    create: 'edr_freight_app:warehouse_fee_rules:create',
    update: 'edr_freight_app:warehouse_fee_rules:update',
    delete: 'edr_freight_app:warehouse_fee_rules:delete',
  },
  warehouseInspectionReports: {
    view: 'edr_freight_app:warehouse_inspection_reports:view',
    create: 'edr_freight_app:warehouse_inspection_reports:create',
    update: 'edr_freight_app:warehouse_inspection_reports:update',
  },
  warehouseInventory: {
    view: 'edr_freight_app:warehouse_inventory:view',
    receive: 'edr_freight_app:warehouse_inventory:receive',
    move: 'edr_freight_app:warehouse_inventory:move',
    load: 'edr_freight_app:warehouse_inventory:load',
    unload: 'edr_freight_app:warehouse_inventory:unload',
    dispatch: 'edr_freight_app:warehouse_inventory:dispatch',
    gatePass: 'edr_freight_app:warehouse_inventory:gate_pass',
    release: 'edr_freight_app:warehouse_inventory:release',
    deliver: 'edr_freight_app:warehouse_inventory:deliver',
    inspect: 'edr_freight_app:warehouse_inventory:inspect',
  },
  interchangeDocuments: {
    view: 'edr_freight_app:interchange_documents:view',
    generate: 'edr_freight_app:interchange_documents:generate',
    acknowledge: 'edr_freight_app:interchange_documents:acknowledge',
    dispute: 'edr_freight_app:interchange_documents:dispute',
    cancel: 'edr_freight_app:interchange_documents:cancel',
  },
  warehouseFeeInvoices: {
    view: 'edr_freight_app:warehouse_fee_invoices:view',
    generate: 'edr_freight_app:warehouse_fee_invoices:generate',
    cancel: 'edr_freight_app:warehouse_fee_invoices:cancel',
    pay: 'edr_freight_app:warehouse_fee_invoices:pay',
  },
  settings: {
    fileUpload: {
      view: 'edr_freight_app:settings:file_upload:view',
      manage: 'edr_freight_app:settings:file_upload:manage',
    },
    dropdown: {
      view: 'edr_freight_app:settings:dropdown:view',
      manage: 'edr_freight_app:settings:dropdown:manage',
    },
  },
  staff: {
    roles: {
      view: 'edr_freight_app:staff:roles:view',
      create: 'edr_freight_app:staff:roles:create',
      update: 'edr_freight_app:staff:roles:update',
      delete: 'edr_freight_app:staff:roles:delete',
    },
    permissions: {
      view: 'edr_freight_app:staff:permissions:view',
      assign: 'edr_freight_app:staff:permissions:assign',
    },
    // Seeded in edr-freight.seed.ts (EDR_FREIGHT_PERMISSIONS) — surfaced here for gating.
    employeeRegistration: {
      view: 'edr_freight_app:employee_registration:view',
      create: 'edr_freight_app:employee_registration:create',
      update: 'edr_freight_app:employee_registration:update',
      activate: 'edr_freight_app:employee_registration:activate',
      deactivate: 'edr_freight_app:employee_registration:deactivate',
    },
    roleAssignment: {
      view: 'edr_freight_app:role_assignment:view',
      assign: 'edr_freight_app:role_assignment:assign',
      replace: 'edr_freight_app:role_assignment:replace',
    },
    hierarchyUnits: {
      view: 'edr_freight_app:hierarchy_units:view',
      create: 'edr_freight_app:hierarchy_units:create',
      update: 'edr_freight_app:hierarchy_units:update',
      delete: 'edr_freight_app:hierarchy_units:delete',
    },
    hierarchyPositions: {
      view: 'edr_freight_app:hierarchy_positions:view',
      create: 'edr_freight_app:hierarchy_positions:create',
      update: 'edr_freight_app:hierarchy_positions:update',
      delete: 'edr_freight_app:hierarchy_positions:delete',
      changeParent: 'edr_freight_app:hierarchy_positions:change_parent',
    },
    hierarchyEmployeeAssignment: {
      view: 'edr_freight_app:hierarchy_employee_assignment:view',
      invite: 'edr_freight_app:hierarchy_employee_assignment:invite',
      assign: 'edr_freight_app:hierarchy_employee_assignment:assign',
    },
    positionTypes: {
      view: 'edr_freight_app:position_types:view',
      create: 'edr_freight_app:position_types:create',
      update: 'edr_freight_app:position_types:update',
      delete: 'edr_freight_app:position_types:delete',
    },
  },
} as const;

/** Both arms of a freight-type-split permission (for one-of route guards). */
export const bothFreightTypes = (p: { bulk: string; container: string }): string[] => [
  p.bulk,
  p.container,
];

/** The arm of a freight-type-split permission matching a contract's freightType. */
export const forFreightType = (
  p: { bulk: string; container: string },
  freightType: string,
): string => (freightType === 'BULK' ? p.bulk : p.container);

const allRuleEngineViewKeys = () =>
  RULE_ENGINE_RESOURCE_SLUGS.map((s) => FREIGHT_PERMS.ruleEngine.view(s));

/**
 * Granular equivalents of the legacy fleet:view + fleet:manage pair.
 * Deliberately excludes the wagon-transfer keys — those were always separate
 * grants (requester vs OCC vs admin history), not part of fleet:manage.
 */
const FLEET_GRANULAR_KEYS: string[] = [
  FREIGHT_PERMS.locomotives.view,
  FREIGHT_PERMS.locomotives.create,
  FREIGHT_PERMS.locomotives.update,
  FREIGHT_PERMS.locomotives.delete,
  FREIGHT_PERMS.wagons.view,
  FREIGHT_PERMS.wagons.create,
  FREIGHT_PERMS.wagons.update,
  FREIGHT_PERMS.wagons.delete,
  FREIGHT_PERMS.trains.view,
  FREIGHT_PERMS.trains.create,
  FREIGHT_PERMS.trains.update,
  FREIGHT_PERMS.trains.delete,
  FREIGHT_PERMS.trains.assignWagons,
  FREIGHT_PERMS.routes.view,
  FREIGHT_PERMS.routes.create,
  FREIGHT_PERMS.routes.update,
  FREIGHT_PERMS.routes.delete,
  FREIGHT_PERMS.containers.view,
  FREIGHT_PERMS.containers.create,
  FREIGHT_PERMS.containers.update,
  FREIGHT_PERMS.containers.delete,
  FREIGHT_PERMS.cargoes.view,
  FREIGHT_PERMS.cargoes.create,
  FREIGHT_PERMS.cargoes.update,
  FREIGHT_PERMS.cargoes.delete,
  FREIGHT_PERMS.consignments.view,
  FREIGHT_PERMS.consignments.create,
];

export const ROLE_PERMISSION_PRESETS = {
  // Marketing / line staff: drives a booking from intake through line-staff
  // approval and contract generation/signing — i.e. until the contract is ready
  // and signed. No director/CEO approval, no scheduling, no operations.
  lineStaff: [
    FREIGHT_PERMS.bookings.view,
    FREIGHT_PERMS.bookings.staffAccept,
    FREIGHT_PERMS.bookings.requestChanges,
    FREIGHT_PERMS.bookings.reject,
    FREIGHT_PERMS.bookings.approveLineStaff,
    FREIGHT_PERMS.bookings.rejectApproval,
    FREIGHT_PERMS.bookings.cancel,
    FREIGHT_PERMS.contracts.view,
    ...bothFreightTypes(FREIGHT_PERMS.contracts.staffAccept),
    ...bothFreightTypes(FREIGHT_PERMS.contracts.requestChanges),
    ...bothFreightTypes(FREIGHT_PERMS.contracts.reject),
    FREIGHT_PERMS.contracts.approveLineStaff,
    ...allRuleEngineViewKeys(),
  ],
  // Operations Officer: train scheduling + wagon allocation + transit/complete
  // + fleet management (wagons, trains, locomotives, routes, containers, cargo).
  operationsOfficer: [
    FREIGHT_PERMS.bookings.view,
    FREIGHT_PERMS.bookings.operations,
    // They are the ones who accept/reject operation requests, so they are the
    // ones the doc-review countdown is for.
    FREIGHT_PERMS.bookings.docReviewAlert,
    FREIGHT_PERMS.trainScheduling.view,
    FREIGHT_PERMS.trainScheduling.create,
    FREIGHT_PERMS.trainScheduling.update,
    FREIGHT_PERMS.trainScheduling.cancel,
    FREIGHT_PERMS.trainScheduling.reschedule,
    FREIGHT_PERMS.trainScheduling.rulesManage,
    FREIGHT_PERMS.fleet.view,
    FREIGHT_PERMS.fleet.manage,
    ...FLEET_GRANULAR_KEYS,
    // Path A (no customs): Operations reviews the customer's self-clearance docs
    // — on the contract for ONE_TIME contracts, and PER BOOKING for GENERAL
    // contracts (booking-level document review → finalize → CLEARANCE_READY).
    FREIGHT_PERMS.contracts.view,
    FREIGHT_PERMS.contracts.opsClearanceReview,
    FREIGHT_PERMS.bookings.clearanceView,
    FREIGHT_PERMS.bookings.reviewDocuments,
    FREIGHT_PERMS.bookings.finalizeClearance,
    ...allRuleEngineViewKeys(),
  ],
  director: [
    FREIGHT_PERMS.bookings.view,
    FREIGHT_PERMS.bookings.approveDirector,
    FREIGHT_PERMS.bookings.rejectApproval,
    FREIGHT_PERMS.bookings.generateContract,
    FREIGHT_PERMS.contracts.view,
    FREIGHT_PERMS.contracts.approveDirector,
    FREIGHT_PERMS.contracts.generateContract,
    ...allRuleEngineViewKeys(),
  ],
  ceo: [
    FREIGHT_PERMS.bookings.view,
    FREIGHT_PERMS.bookings.approveCeo,
    FREIGHT_PERMS.bookings.rejectApproval,
    FREIGHT_PERMS.contracts.view,
    FREIGHT_PERMS.contracts.approveCeo,
    ...allRuleEngineViewKeys(),
  ],
  finance: [FREIGHT_PERMS.bookings.view],
  // Global Logistics: manages ONLY the customs-clearance queue. Scoped out of
  // the general booking-request list (no bookings:view) — instead a dedicated
  // clearance:view permission lists the clearance bookings. Reviews customer
  // clearance documents, uploads customs output documents, and finalizes the
  // clearance gate.
  // GL Ethiopia (edr_gl_ethiopia): reviews pre-booking clearance docs on the
  // contract, uploads ET output docs, finalizes clearance, and EXCLUSIVELY creates
  // the booking under a customs contract (Path B). Also runs post-booking ET
  // milestones + the legacy booking-clearance permissions during migration.
  glEthiopia: [
    FREIGHT_PERMS.contracts.view,
    FREIGHT_PERMS.contracts.clearanceReview,
    FREIGHT_PERMS.contracts.finalizeClearance,
    FREIGHT_PERMS.contracts.createBooking,
    FREIGHT_PERMS.contracts.clearanceEtActions,
    FREIGHT_PERMS.contracts.clearanceDutyAdvise,
    FREIGHT_PERMS.bookings.clearanceView,
    FREIGHT_PERMS.bookings.reviewDocuments,
    FREIGHT_PERMS.bookings.uploadClearanceOutput,
    FREIGHT_PERMS.bookings.finalizeClearance,
    FREIGHT_PERMS.bookings.operations,
  ],
  // GL Djibouti (edr_gl_djibouti): DO/RO collection, gatepass, loading milestones,
  // damage reports. Read-only on the contract; no booking creation.
  glDjibouti: [
    FREIGHT_PERMS.contracts.view,
    FREIGHT_PERMS.contracts.clearanceDjActions,
    FREIGHT_PERMS.bookings.clearanceView,
    FREIGHT_PERMS.bookings.uploadClearanceOutput,
    FREIGHT_PERMS.bookings.operations,
  ],
  // Marketing handles intake through contract (same as line staff here) and,
  // for non-customs bookings, reviews/finalizes the customer's clearance
  // documents from the booking detail (customs bookings go to Global Logistics).
  marketing: [
    FREIGHT_PERMS.bookings.view,
    FREIGHT_PERMS.bookings.staffAccept,
    FREIGHT_PERMS.bookings.requestChanges,
    FREIGHT_PERMS.bookings.reject,
    FREIGHT_PERMS.bookings.approveLineStaff,
    FREIGHT_PERMS.bookings.rejectApproval,
    FREIGHT_PERMS.bookings.cancel,
    FREIGHT_PERMS.bookings.generateContract,
    FREIGHT_PERMS.bookings.signStaff,
    FREIGHT_PERMS.bookings.reviewDocuments,
    FREIGHT_PERMS.bookings.finalizeClearance,
    FREIGHT_PERMS.contracts.view,
    ...bothFreightTypes(FREIGHT_PERMS.contracts.staffAccept),
    ...bothFreightTypes(FREIGHT_PERMS.contracts.requestChanges),
    ...bothFreightTypes(FREIGHT_PERMS.contracts.reject),
    FREIGHT_PERMS.contracts.approveLineStaff,
    FREIGHT_PERMS.contracts.generateContract,
    ...bothFreightTypes(FREIGHT_PERMS.contracts.signStaff),
  ],
  orgManager: [...BOOKING_RULE_ENGINE_PERMISSION_KEYS],
} as const;

/**
 * Position permission presets (positions-as-roles). Grants flow to users via
 * Position → PositionPermission (NOT Role/RolePermission). Each reuses the
 * matching ROLE_PERMISSION_PRESETS key-array as a building block and adds the
 * gap-controller keys the position needs. Deduped via Set.
 */
const dedupe = (keys: string[]): string[] => [...new Set(keys)];

export const POSITION_PERMISSION_PRESETS = {
  // Chief: senior operational role — intake/line-staff approval + director
  // approval + scheduling/ops, plus container allocation.
  chief: dedupe([
    ...ROLE_PERMISSION_PRESETS.lineStaff,
    ...ROLE_PERMISSION_PRESETS.director,
    ...ROLE_PERMISSION_PRESETS.operationsOfficer,
    FREIGHT_PERMS.allocation.manage,
    // Customer desk: onboarding intake lands on the chief — open the customer
    // list and approve/suspend a submitted profile. Deliberately NOT granted:
    // create, update and password reset, which stay with the customer admins.
    FREIGHT_PERMS.customers.view,
    FREIGHT_PERMS.customers.verify,
    FREIGHT_PERMS.customers.deactivate,
  ]),
  director: dedupe([...ROLE_PERMISSION_PRESETS.director]),
  ceo: dedupe([...ROLE_PERMISSION_PRESETS.ceo]),
  ethiopianGl: dedupe([...ROLE_PERMISSION_PRESETS.glEthiopia]),
  djiboutiGl: dedupe([...ROLE_PERMISSION_PRESETS.glDjibouti]),
  marketer: dedupe([...ROLE_PERMISSION_PRESETS.marketing]),
  operation: dedupe([
    ...ROLE_PERMISSION_PRESETS.operationsOfficer,
    FREIGHT_PERMS.allocation.manage,
  ]),
  // Operations Chief: full operational authority — the entire freight
  // permission catalog (all CRUD across bookings, contracts, scheduling,
  // fleet, warehouse, mile, finance, settings, staff).
  operationsChief: dedupe([...BOOKING_RULE_ENGINE_PERMISSION_KEYS]),
  // Dispatcher: full CRUD on warehouse management (incl. import/export/intercity
  // inventory flows) and fleet management, plus truck dispatch on the mile legs
  // and operational context. The ONE carve-out: allocation & fee rules stay
  // VIEW-ONLY — a dispatcher never creates/updates/deletes those rules.
  dispatcher: dedupe([
    // Warehouse management — full CRUD.
    FREIGHT_PERMS.warehouseDashboard.view,
    ...Object.values(FREIGHT_PERMS.warehouses),
    ...Object.values(FREIGHT_PERMS.warehouseYards),
    ...Object.values(FREIGHT_PERMS.warehouseZones),
    ...Object.values(FREIGHT_PERMS.warehouseInventory),
    ...Object.values(FREIGHT_PERMS.warehouseInspectionReports),
    ...Object.values(FREIGHT_PERMS.interchangeDocuments),
    ...Object.values(FREIGHT_PERMS.warehouseFeeInvoices),
    // View-only on the rules that govern allocation and fees.
    FREIGHT_PERMS.warehouseAllocationRules.view,
    FREIGHT_PERMS.warehouseFeeRules.view,
    // Fleet management — full CRUD.
    ...Object.values(FREIGHT_PERMS.fleet),
    FREIGHT_PERMS.fleetDashboard.view,
    ...Object.values(FREIGHT_PERMS.fleetReports),
    ...Object.values(FREIGHT_PERMS.vehicles),
    ...Object.values(FREIGHT_PERMS.drivers),
    ...Object.values(FREIGHT_PERMS.tracking),
    ...Object.values(FREIGHT_PERMS.fuel),
    ...Object.values(FREIGHT_PERMS.maintenance),
    ...Object.values(FREIGHT_PERMS.locomotives),
    ...Object.values(FREIGHT_PERMS.wagons),
    ...Object.values(FREIGHT_PERMS.trains),
    ...Object.values(FREIGHT_PERMS.routes),
    ...Object.values(FREIGHT_PERMS.containers),
    ...Object.values(FREIGHT_PERMS.cargoes),
    // Truck dispatch on the EDR mile legs + operational context.
    ...Object.values(FREIGHT_PERMS.firstMile),
    ...Object.values(FREIGHT_PERMS.lastMile),
    FREIGHT_PERMS.trainScheduling.view,
    FREIGHT_PERMS.bookings.operations,
  ]),
} as const;

/** Derive the module bucket from the resource segment of a permission key. */
const moduleOf = (key: string): string => key.split(':')[1] ?? 'other';

export const PERMISSIONS_CATALOG = BOOKING_RULE_ENGINE_PERMISSIONS.map((p) => ({
  key: p.key,
  label: p.name.en,
  module: moduleOf(p.key),
}));
