/**
 * Reporting RBAC (F-142 §9).
 *
 * The codebase has no permission table, so permissions are a role -> permission
 * map. The `requireReportingPermission(user, perm)` call-site signature is the
 * single seam a future `backoffice_permissions` migration must preserve.
 */
import type { CurrentUser, Role } from '../../../shared/auth.js';
import { AppError } from '../../../shared/errors.js';

export type ReportingPermission =
  | 'REPORTING_VIEW'
  | 'REPORTING_SALES'
  | 'REPORTING_PRODUCTS'
  | 'REPORTING_CUSTOMERS'
  | 'REPORTING_INVENTORY'
  | 'REPORTING_PAYMENTS'
  | 'REPORTING_CASH'
  | 'REPORTING_DISCOUNTS'
  | 'REPORTING_REFUNDS'
  | 'REPORTING_TAXES'
  | 'REPORTING_FINANCIAL'
  | 'REPORTING_EXPORT'
  | 'REPORTING_ADMIN';

/** Permissions granted to every authenticated report reader. */
const REPORTING_VIEW_BASE: ReportingPermission[] = [
  'REPORTING_VIEW',
  'REPORTING_SALES',
  'REPORTING_PRODUCTS',
  'REPORTING_CUSTOMERS',
  'REPORTING_INVENTORY',
  'REPORTING_DISCOUNTS',
  'REPORTING_REFUNDS',
  'REPORTING_TAXES',
];

/** Role -> granted reporting permissions ("compatibilidad inicial", F-142 §9). */
export const REPORTING_ROLE_PERMISSIONS: Record<Role, ReportingPermission[]> = {
  admin: [
    ...REPORTING_VIEW_BASE,
    'REPORTING_PAYMENTS',
    'REPORTING_CASH',
    'REPORTING_FINANCIAL',
    'REPORTING_EXPORT',
    'REPORTING_ADMIN',
  ],
  editor: [...REPORTING_VIEW_BASE, 'REPORTING_EXPORT'],
  pos_manager: [
    'REPORTING_VIEW',
    'REPORTING_SALES',
    'REPORTING_PAYMENTS',
    'REPORTING_CASH',
  ],
  pos_cashier: ['REPORTING_VIEW', 'REPORTING_SALES'],
  customer: [],
};

/** Permissions granted to a current user under the reporting RBAC matrix. */
export function userReportingPermissions(user: CurrentUser): ReportingPermission[] {
  return REPORTING_ROLE_PERMISSIONS[user.role] ?? [];
}

/** Throws AppError(403) unless the user holds the given reporting permission. */
export function requireReportingPermission(
  user: CurrentUser,
  permission: ReportingPermission,
): void {
  if (!userReportingPermissions(user).includes(permission)) {
    throw new AppError(403, 'FORBIDDEN', 'Insufficient reporting permission');
  }
}
