import type { UserRole } from "@/types/auth";

/**
 * Fine-grained permission keys — the FIXED set the backend seeds (17 permissions
 * across 6 groups). These are the `Permission.name` values the backend's
 * permission guard checks, and the strings the frontend gates UI on. There is no
 * create-permission API, so this union is the complete, authoritative list — if
 * the backend adds a permission to its seed, add it here too.
 *
 * @see 00_code/backend/prisma/seed.ts (permissionsData)
 */
export type Permission =
  // BOOKINGS
  | "booking-create"
  | "booking-read"
  | "booking-update"
  | "booking-assign-tech"
  | "booking-cancel"
  // PROVIDERS
  | "provider-read"
  | "provider-update"
  | "provider-status-update"
  | "provider-verify"
  // CATALOG
  | "catalog-read"
  | "catalog-update"
  // USERS
  | "user-read"
  | "user-update"
  | "user-delete"
  // AUDIT-LOGS
  | "auditlog-read"
  // DASHBOARD
  | "dashboard-read"
  | "report-read";

/** Permission category — the backend's `Permission.group` column. */
export type PermissionGroup =
  "BOOKINGS" | "PROVIDERS" | "CATALOG" | "USERS" | "AUDIT-LOGS" | "DASHBOARD";

/**
 * Which panel a user belongs to. The backend returns this on login/profile
 * (derived from the role enum); the frontend also derives it locally as a
 * fallback via `rolePanelAccess`.
 */
export type PanelAccess = "ADMIN" | "PROVIDER";

/**
 * A declarative access check, shared by `<Can>`, `<RouteGuard>`, `useCan`, and
 * nav items. Fields compose with AND; within `anyOf` the check is OR:
 *  - `permission` / `allOf` — the user must have ALL listed permissions
 *  - `anyOf` — the user must have AT LEAST ONE listed permission
 *  - `role` — the user's role must be one of these
 *  - `panel` — the user must belong to this panel
 *
 * An empty check (no fields set) means "always allowed" — i.e. any authenticated
 * user passes. `ADMIN_SUPER` passes every permission check (backend parity).
 */
export interface AccessCheck {
  permission?: Permission;
  allOf?: Permission[];
  anyOf?: Permission[];
  role?: UserRole | UserRole[];
  panel?: PanelAccess;
}
