/**
 * Catálogo de permisos y matriz de roles: fuente única de verdad.
 *
 * - El código autoriza por PERMISO, no por rol (`requirePermission("leads.update")`).
 * - Los permisos con sufijo ".own" limitan el alcance a los registros asignados al usuario.
 * - El seed sincroniza esta matriz con las tablas roles / permissions / role_permissions.
 */

export const PERMISSIONS = {
  // Dashboard
  "dashboard.read": { module: "dashboard", description: "Ver dashboard global" },
  "dashboard.read.own": { module: "dashboard", description: "Ver dashboard con sus propios KPIs" },
  // Vehículos
  "vehicles.read": { module: "vehicles", description: "Ver inventario" },
  "vehicles.write": {
    module: "vehicles",
    description: "Crear y editar vehículos, fotos y estados",
  },
  "vehicles.delete": { module: "vehicles", description: "Eliminar (soft delete) vehículos" },
  // Leads
  "leads.read": { module: "leads", description: "Ver todos los leads" },
  "leads.read.own": { module: "leads", description: "Ver solo sus leads asignados" },
  "leads.update": { module: "leads", description: "Editar cualquier lead" },
  "leads.update.own": { module: "leads", description: "Editar sus leads (estado, notas)" },
  "leads.assign": { module: "leads", description: "Asignar y reasignar leads" },
  // Clientes
  "customers.read": { module: "customers", description: "Ver todos los clientes" },
  "customers.read.own": { module: "customers", description: "Ver clientes de sus leads" },
  "customers.write": { module: "customers", description: "Editar cualquier cliente" },
  "customers.write.own": { module: "customers", description: "Editar clientes de sus leads" },
  // Citas
  "appointments.read": { module: "appointments", description: "Ver todas las citas" },
  "appointments.read.own": { module: "appointments", description: "Ver sus citas" },
  "appointments.write": { module: "appointments", description: "Gestionar cualquier cita" },
  "appointments.write.own": { module: "appointments", description: "Gestionar sus citas" },
  // Consignaciones
  "consignments.read": { module: "consignments", description: "Ver todas las consignaciones" },
  "consignments.read.own": { module: "consignments", description: "Ver consignaciones asignadas" },
  "consignments.write": { module: "consignments", description: "Gestionar cualquier consignación" },
  "consignments.write.own": { module: "consignments", description: "Gestionar sus consignaciones" },
  "consignments.assign": { module: "consignments", description: "Asignar asesor a consignaciones" },
  // Reservas
  "reservations.write": { module: "sales", description: "Reservar y liberar cualquier vehículo" },
  "reservations.write.own": { module: "sales", description: "Reservar sobre sus leads" },
  // Ventas
  "sales.read": { module: "sales", description: "Ver todas las ventas" },
  "sales.read.own": { module: "sales", description: "Ver sus ventas" },
  "sales.create": { module: "sales", description: "Registrar ventas" },
  "sales.create.own": {
    module: "sales",
    description: "Registrar ventas de sus leads (sin aprobación)",
  },
  "sales.annul": { module: "sales", description: "Anular ventas (sin borrado físico)" },
  "sales.commission.override": {
    module: "sales",
    description: "Modificar la comisión del asesor en una venta",
  },
  // Comisiones
  "commissions.read": {
    module: "commissions",
    description: "Ver comisiones de todos los asesores",
  },
  "commissions.read.own": { module: "commissions", description: "Ver sus comisiones" },
  "commissions.pay": {
    module: "commissions",
    description: "Marcar comisiones y liquidaciones como pagadas",
  },
  // Asesores, reportes
  "advisors.read": { module: "advisors", description: "Ver rendimiento de asesores" },
  "reports.read": { module: "reports", description: "Ver reportes" },
  "reports.export": { module: "reports", description: "Exportar reportes CSV/Excel" },
  // Usuarios
  "users.read": { module: "users", description: "Ver usuarios" },
  "users.write": { module: "users", description: "Crear y editar SUPERVISOR y ADVISOR" },
  "users.write.admins": { module: "users", description: "Crear y editar ADMIN" },
  // Configuración y auditoría
  "settings.read": { module: "settings", description: "Ver configuración" },
  "settings.write.company": {
    module: "settings",
    description: "Editar datos de empresa y WhatsApp",
  },
  "settings.write": { module: "settings", description: "Editar toda la configuración" },
  "audit.read": { module: "audit", description: "Ver auditoría" },
  "records.restore": { module: "audit", description: "Restaurar registros borrados" },
} as const satisfies Record<string, { module: string; description: string }>;

export type Permission = keyof typeof PERMISSIONS;

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

export const ROLE_KEYS = ["SUPER_ADMIN", "ADMIN", "SUPERVISOR", "ADVISOR"] as const;
export type RoleKey = (typeof ROLE_KEYS)[number];

export const ROLE_DEFINITIONS: Record<
  RoleKey,
  { name: string; description: string; permissions: readonly Permission[] }
> = {
  SUPER_ADMIN: {
    name: "Super administrador",
    description:
      "Acceso total, incluida la gestión de administradores y la restauración de registros.",
    permissions: ALL_PERMISSIONS,
  },
  ADMIN: {
    name: "Administrador",
    description: "Gestiona inventario, CRM, ventas, reportes y usuarios no administradores.",
    permissions: [
      "dashboard.read",
      "vehicles.read",
      "vehicles.write",
      "vehicles.delete",
      "leads.read",
      "leads.update",
      "leads.assign",
      "customers.read",
      "customers.write",
      "appointments.read",
      "appointments.write",
      "consignments.read",
      "consignments.write",
      "consignments.assign",
      "reservations.write",
      "sales.read",
      "sales.create",
      "sales.annul",
      "sales.commission.override",
      "commissions.read",
      "commissions.pay",
      "advisors.read",
      "reports.read",
      "reports.export",
      "users.read",
      "users.write",
      "settings.read",
      "settings.write.company",
      "audit.read",
    ],
  },
  SUPERVISOR: {
    name: "Supervisor",
    description: "Supervisa leads, clientes, citas y reportes; reasigna leads.",
    permissions: [
      "dashboard.read",
      "vehicles.read",
      "leads.read",
      "leads.update",
      "leads.assign",
      "customers.read",
      "customers.write",
      "appointments.read",
      "appointments.write",
      "consignments.read",
      "consignments.assign",
      "sales.read",
      "commissions.read",
      "advisors.read",
      "reports.read",
      "reports.export",
    ],
  },
  ADVISOR: {
    name: "Asesor",
    description: "Gestiona sus leads, clientes, citas y ventas.",
    permissions: [
      "dashboard.read.own",
      "vehicles.read",
      "leads.read.own",
      "leads.update.own",
      "customers.read.own",
      "customers.write.own",
      "appointments.read.own",
      "appointments.write.own",
      "consignments.read.own",
      "consignments.write.own",
      "reservations.write.own",
      "sales.read.own",
      "sales.create.own",
      "commissions.read.own",
    ],
  },
};

export function isPermission(value: string): value is Permission {
  return Object.hasOwn(PERMISSIONS, value);
}

export function hasPermission(granted: ReadonlySet<string>, permission: Permission): boolean {
  return granted.has(permission);
}

/** Permisos base que admiten alcance: "leads.read" ⇄ "leads.read.own". */
type ScopedBase = {
  [P in Permission]: P extends `${infer Base}.own`
    ? Base extends Permission
      ? Base
      : never
    : never;
}[Permission];

export type AccessScope = "all" | "own" | "none";

/**
 * Resuelve el alcance de un permiso con variante ".own".
 * "all" si tiene el permiso completo, "own" si solo tiene la variante propia, "none" si ninguno.
 */
export function resolveScope(granted: ReadonlySet<string>, base: ScopedBase): AccessScope {
  if (granted.has(base)) return "all";
  if (granted.has(`${base}.own`)) return "own";
  return "none";
}
