/**
 * Role-Based Access Control (RBAC)
 * -----------------------------------
 * Defines roles, what each role can do, and helper functions
 * to check permissions.
 *
 * Roles (highest → lowest):
 *   owner  — full control, can delete org, manage billing
 *   admin  — can manage settings, integrations, members
 *   member — can use all features, create content, manage brands
 *   viewer — read-only access, cannot create or modify anything
 *
 * How to use:
 *   import { canAccess, requireRole } from "@/lib/permissions";
 *
 *   // Check if a role can do something:
 *   canAccess("viewer", "billing")     → false
 *   canAccess("admin", "billing")      → true
 *
 *   // In an API route, get the role and check:
 *   const role = getUserRole(user, orgId);
 *   if (!canAccess(role, "billing")) return 403;
 */

// ─── Role hierarchy ─────────────────────────────────────────────────────────

export type Role = "owner" | "admin" | "member" | "viewer";

/**
 * Numeric level for each role. Higher = more permissions.
 * Used for "at least this role" checks.
 */
const ROLE_LEVEL: Record<Role, number> = {
  viewer: 0,
  member: 1,
  admin: 2,
  owner: 3,
};

/**
 * Check if roleA is at least as powerful as roleB.
 * Example: isAtLeast("admin", "member") → true
 */
export function isAtLeast(userRole: string, requiredRole: Role): boolean {
  const level = ROLE_LEVEL[userRole as Role];
  if (level === undefined) return false;
  return level >= ROLE_LEVEL[requiredRole];
}

// ─── Permission map ──────────────────────────────────────────────────────────

/**
 * Each "permission" is a named action or route area.
 * The value is the MINIMUM role required to access it.
 */
const PERMISSION_MAP: Record<string, Role> = {
  // ── Restricted to owner/admin ──
  billing:              "admin",
  settings:             "admin",
  integrations:         "admin",
  manage_members:       "admin",
  delete_organization:  "owner",

  // ── Restricted to members+ (no viewers) ──
  create_brand:         "member",
  edit_brand:           "member",
  create_task:          "member",
  edit_task:            "member",
  create_content:       "member",
  create_page:          "member",
  manage_site_tag:      "member",
  use_ai_avatar:        "member",

  // ── Available to everyone including viewers ──
  view_dashboard:       "viewer",
  view_reports:         "viewer",
  view_competitors:     "viewer",
  view_audit:           "viewer",
  view_signals:         "viewer",
  view_conversions:     "viewer",
};

/**
 * Check if a role has permission for a given action.
 * Returns true if the role meets or exceeds the required level.
 *
 * Example:
 *   canAccess("viewer", "billing")     → false (needs admin)
 *   canAccess("admin", "billing")      → true
 *   canAccess("viewer", "view_dashboard") → true
 */
export function canAccess(userRole: string, permission: string): boolean {
  const required = PERMISSION_MAP[permission];
  if (!required) return true; // Unknown permission = allow (safe default for new features)
  return isAtLeast(userRole, required);
}

// ─── Route-level permission map ──────────────────────────────────────────────

/**
 * Maps API route prefixes to the permission they require.
 * Used by the requireRouteAccess() helper.
 */
const ROUTE_PERMISSIONS: Record<string, string> = {
  "/api/billing":       "billing",
  "/api/integrations":  "integrations",
  "/api/organizations/members": "manage_members",
};

/**
 * Given a route path and the user's role, check if access is allowed.
 * Returns { allowed: true } or { allowed: false, requiredRole: "admin" }.
 */
export function checkRouteAccess(
  routePath: string,
  userRole: string
): { allowed: boolean; requiredRole?: Role } {
  // Find the longest matching route prefix
  const matchKey = Object.keys(ROUTE_PERMISSIONS)
    .filter(prefix => routePath.startsWith(prefix))
    .sort((a, b) => b.length - a.length)[0];

  if (!matchKey) return { allowed: true }; // No restriction on this route

  const permission = ROUTE_PERMISSIONS[matchKey];
  const required = PERMISSION_MAP[permission];
  if (!required) return { allowed: true };

  if (isAtLeast(userRole, required)) {
    return { allowed: true };
  }

  return { allowed: false, requiredRole: required };
}

// ─── Sidebar visibility ──────────────────────────────────────────────────────

/**
 * Returns which sidebar sections should be visible for a given role.
 * Used by the frontend to hide/show nav items.
 */
export function getVisibleSections(userRole: string): Record<string, boolean> {
  return {
    billing:      canAccess(userRole, "billing"),
    settings:     canAccess(userRole, "settings"),
    integrations: canAccess(userRole, "integrations"),
    siteTag:      canAccess(userRole, "manage_site_tag"),
    aiAvatar:     canAccess(userRole, "use_ai_avatar"),
    createBrand:  canAccess(userRole, "create_brand"),
    createTask:   canAccess(userRole, "create_task"),
    // All roles can view these
    dashboard:    true,
    reports:      true,
    competitors:  true,
    audit:        true,
  };
}

// ─── Role labels for UI ──────────────────────────────────────────────────────

export const ROLE_OPTIONS: Array<{ value: Role; label: string; description: string }> = [
  { value: "owner",  label: "Owner",  description: "Full control — billing, settings, members, and all features" },
  { value: "admin",  label: "Admin",  description: "Manage settings, integrations, and members" },
  { value: "member", label: "Member", description: "Use all features, create brands, tasks, and content" },
  { value: "viewer", label: "Viewer", description: "Read-only access — can view but not create or modify" },
];
