/** Tab permissions — keep in sync with prisma seed and AuthService ALL_PERMISSIONS */
export const ALL_TAB_PERMISSIONS = [
  'TAB_TODAY_READ',
  'TAB_TODAY_EDIT',
  'TAB_STAFF_READ',
  'TAB_STAFF_EDIT',
  'TAB_ORGANIZATIONS_READ',
  'TAB_ORGANIZATIONS_EDIT',
  'TAB_PATIENTS_READ',
  'TAB_PATIENTS_EDIT',
  'TAB_APPOINTMENTS_READ',
  'TAB_APPOINTMENTS_EDIT',
  'TAB_TREATMENT_READ',
  'TAB_TREATMENT_EDIT',
  'TAB_CASES_READ',
  'TAB_CASES_EDIT',
  'TAB_TASKS_READ',
  'TAB_TASKS_EDIT',
  'TAB_BILLING_READ',
  'TAB_BILLING_EDIT',
  'TAB_REPORTS_READ',
  'TAB_REPORTS_EDIT',
] as const;

export type TabPermission = (typeof ALL_TAB_PERMISSIONS)[number];

const ALL_TAB_SET = new Set<string>(ALL_TAB_PERMISSIONS);
const TAB_ORDER_INDEX = new Map<string, number>(
  ALL_TAB_PERMISSIONS.map((p, i) => [p, i]),
);

/** Enterprise / unlimited seat plans use this sentinel in seed data */
export const SEAT_UNLIMITED_THRESHOLD = 999999;

export function isUnlimitedSeats(maxUsers: number): boolean {
  return maxUsers >= SEAT_UNLIMITED_THRESHOLD;
}

/** EDIT implies READ for the same feature tab */
const EDIT_TO_READ: Record<string, string> = {
  TAB_TODAY_EDIT: 'TAB_TODAY_READ',
  TAB_PATIENTS_EDIT: 'TAB_PATIENTS_READ',
  TAB_APPOINTMENTS_EDIT: 'TAB_APPOINTMENTS_READ',
  TAB_STAFF_EDIT: 'TAB_STAFF_READ',
  TAB_ORGANIZATIONS_EDIT: 'TAB_ORGANIZATIONS_READ',
  TAB_TREATMENT_EDIT: 'TAB_TREATMENT_READ',
  TAB_CASES_EDIT: 'TAB_CASES_READ',
  TAB_TASKS_EDIT: 'TAB_TASKS_READ',
  TAB_BILLING_EDIT: 'TAB_BILLING_READ',
  TAB_REPORTS_EDIT: 'TAB_REPORTS_READ',
};

/**
 * Dedupe, drop unknown strings, and add implied READ permissions for each EDIT.
 */
export function normalizeTabPermissions(names: string[]): string[] {
  const out = new Set<string>();
  for (const raw of names) {
    const n = typeof raw === 'string' ? raw.trim() : '';
    if (!n || !ALL_TAB_SET.has(n)) continue;
    out.add(n);
    const read = EDIT_TO_READ[n];
    if (read) out.add(read);
  }
  return [...out].sort((a, b) => (TAB_ORDER_INDEX.get(a) ?? 0) - (TAB_ORDER_INDEX.get(b) ?? 0));
}
