const ROLE_KEYS = Object.freeze({
  admin: "admins",
  mod: "mods",
  user: "users"
});

function roleOf(user, roleHint = null) {
  if (["admin", "mod", "user"].includes(roleHint)) return roleHint;
  if (user?.isAdmin) return "admin";
  if (user?.isMod) return "mod";
  return user?.id ? "user" : "anonymous";
}

function canUseAssistant({
  user,
  config = {},
  origin = "webui",
  platform = origin,
  requestedSurface = "webui_panel",
  roleHint = null,
  roleSource = null
}) {
  const normalizedRole = roleOf(user, roleHint);
  const isCommand = requestedSurface === "command";
  const visibilitySettings = isCommand
    ? { ...(config.commands?.roles || {}) }
    : { ...(config.assistant_visibility || {}) };
  const roleKey = ROLE_KEYS[normalizedRole] || null;
  const roleAllowed = Boolean(roleKey && visibilitySettings[roleKey]);
  const platformAllowed = !isCommand || Boolean(config.commands?.platforms?.[platform]);
  const featureEnabled = Boolean(config.enabled && config.assistant_enabled !== false);
  const commandEnabled = !isCommand || Boolean(config.commands?.enabled);

  let reason = null;
  if (normalizedRole === "anonymous") reason = "anonymous";
  else if (!featureEnabled) reason = "assistant_disabled";
  else if (!commandEnabled) reason = "command_disabled";
  else if (!platformAllowed) reason = "platform_forbidden";
  else if (!roleAllowed) reason = "role_forbidden";

  const allowedRoles = Object.entries(ROLE_KEYS)
    .filter(([, key]) => Boolean(visibilitySettings[key]))
    .map(([role]) => role);

  return {
    allowed: reason === null,
    reason,
    normalized_role: normalizedRole,
    visibility_settings: visibilitySettings,
    debug_details: {
      resolved_user_id: user?.id || null,
      normalized_role: normalizedRole,
      role_source: roleSource || (roleHint ? "origin_context" : "session_auth"),
      role_allowed: roleAllowed,
      allowed_roles: allowedRoles,
      origin,
      platform,
      requested_surface: requestedSurface
    }
  };
}

module.exports = { ROLE_KEYS, roleOf, canUseAssistant };
