const express = require("express");
const path = require("path");
const crypto = require("crypto");
const fs = require("fs");
const { Permissions } = require("discord.js");
let multer = null;
try {
  multer = require("multer");
} catch {
  multer = null;
}
const session = require("express-session");
const BetterSqlite3Store = require("better-sqlite3-session-store")(session);

const { db } = require("../services/db");
const { getSetting, setSetting, getAllSettings } = require("../services/settings");
const {
  deleteCustomTheme,
  duplicateTheme,
  FONT_STACKS,
  getActiveTheme,
  getThemeById,
  listThemes,
  renameCustomTheme,
  saveCustomTheme,
  setActiveTheme,
  valuesFromRequest
} = require("../services/themes");
const { getRoleFlags, hasAccess } = require("../services/rbac");
const { createWebAuth } = require("../services/web-auth");
const { createWebUpgradeRegistry } = require("../services/web-upgrades");
const {
  cleanupUploadedFiles,
  safeDownloadFilename,
  validateUploadedFile,
  validateUploadedFiles
} = require("../services/upload-security");
const {
  buildDiscordAuthUrl,
  exchangeDiscordCode,
  fetchDiscordUser,
  fetchDiscordGuildMember,
  buildTwitchAuthUrl,
  buildTwitchEventAuthUrl,
  exchangeTwitchCode,
  fetchTwitchUser,
  buildYouTubeAuthUrl,
  exchangeYouTubeCode,
  fetchYouTubeChannel
} = require("../services/auth");
const { getPluginProfileStats, getAdminDashboardSections } = require("../services/plugin-stats");
const {
  getLeaderboardSections,
  getTopCommandOptions
} = require("../services/top");
const {
  DEFAULT_MAX_AGE_DAYS,
  DEFAULT_MAX_ENTRIES,
  cleanupLogs,
  createLogger,
  listLogFacets,
  listLogs,
  log,
  summarizeLogs,
  withLogContext
} = require("../services/logger");
const { createWebhookService } = require("../services/webhooks");
const {
  getPlatformStatus,
  getEnabledPlatformIds,
  getLoginPlatforms,
  getLinkPlatforms,
  getPlatformLabel,
  getPlatformBadge,
  isPlatformEnabled,
  isPlatformConfigured,
  normalizePlatformSelection,
  serializePlatformSelection
} = require("../services/platforms");
const { getClient: getTwitchClient } = require("../services/twitch");
const { twitchEventSubManager } = require("../services/twitch-eventsub");
const { eventHooksApi } = require("../services/overlay-event-hooks");
const { getClient: getYouTubeClient } = require("../services/youtube");
const {
  conditionalRepliesFromBody,
  normalizeConditionalReplies,
  normalizeConditionalReplyRows
} = require("../services/command-conditional");
const {
  createGroup: createCommandGroup,
  customCommandKey,
  deleteGroup: deleteCommandGroup,
  getCommandPolicy,
  labelRequirement,
  listGroups: listCommandGroups,
  normalizeStoredPolicy,
  resolvePolicy,
  saveCommandPolicy,
  saveCommandPolicies,
  updateGroup: updateCommandGroup
} = require("../services/command-policies");
const {
  ensureUserForIdentity,
  linkIdentityToUser,
  getUserProfileById,
  getUserIdentities,
  updateInternalUsername,
  listUsersWithIdentities,
  searchKnownUsers
} = require("../services/users");
const {
  getPlugins,
  syncPluginRegistry,
  setPluginEnabled,
  removePlugin,
  installFromGit,
  updatePluginFromGit,
  createLocalPlugin
} = require("../services/plugins");
const { requestRestart } = require("../services/updater");
const {
  applyBotUpdate,
  applyPluginUpdate,
  getSnapshotRetention,
  listSnapshots,
  setSnapshotRetention
} = require("../services/update-manager");
const { getUpdateStatus } = require("../services/update-index");
const {
  applyCoreUpdate,
  deployCoreBranch,
  applyPluginUpdateFromRepo,
  revertCoreSnapshot,
  revertPluginSnapshot,
  disablePluginForRecovery
} = require("../services/repo-update");
const {
  listDeploymentBranches,
  normalizeDeploymentBranch,
  readUpdateState
} = require("../services/update-repository");
const {
  safeModeStatus,
  clearRecoveryMarker,
  updateRecoveryMarker
} = require("../services/recovery-mode");
const {
  auditDiagnosticRequest,
  authenticateDiagnosticsRequest,
  diagnosticsAccessStatus,
  diagnosticsRequestProtocol,
  issueDiagnosticsAccessKey,
  recentDiagnosticAudit,
  revokeDiagnosticsAccess,
  runDiagnosticCheck
} = require("../services/production-diagnostics");
const {
  generateCommandPreview,
  previewParts
} = require("../services/command-preview");
const {
  normalizeRandomReplies,
  parseRandomRepliesFromBody,
  selectRandomReply,
  validateRandomConfig
} = require("../services/command-random");
const {
  isDestructivePath,
  issueConfirmation,
  consumeConfirmation,
  normalizeAction
} = require("../services/destructive-confirm");
const {
  publishWebEvent,
  subscribeWebEvents
} = require("../services/web-events");
const {
  registerOverlayAdminRoutes,
  registerPublicOverlayRoutes
} = require("../services/overlay-routes");
const { frameworkApi: createContentLibraryFramework } = require("../services/content-library");
const {
  registerContentAdminRoutes,
  registerPublicContentRoutes
} = require("../services/content-routes");
const { registerOverlayModuleType } = require("../services/overlay-modules");
const { registerOverlayAccessProvider } = require("../services/overlay-permissions");
const { registerOverlayConnectorProvider } = require("../services/overlay-connectors");
const placeholders = require("../services/placeholders");
const {
  addSubmitterComment,
  adminUpdateFeedback,
  buildFeedbackJobExport,
  cleanupFeedback,
  createFeedback,
  deleteFeedback,
  findSimilarFeedback,
  feedbackOptions,
  getFeedbackForSubmitter,
  getFeedbackForAdmin,
  getFeedbackAttachment,
  getFeedbackForViewer,
  listFeedbackForAdmin,
  listMyFeedback,
  listPublicFeedback,
  markFeedbackViewed,
  mergeFeedback,
  notificationSummary,
  supportFeedback,
  unmergeFeedback
} = require("../services/feedback");

function ensureSessionSecret() {
  let secret = getSetting("session_secret");
  if (!secret) {
    secret = crypto.randomBytes(32).toString("hex");
    setSetting("session_secret", secret);
  }
  return secret;
}

const webAuth = createWebAuth();
const {
  isConfigured,
  isLocalhostLoginAvailable,
  getLocalhostLoginPlatform,
  getLoginRedirectPath,
  requireConfigured,
  requireAuth
} = webAuth;

function trackModRole(db, user) {
  if (!user?.id) {
    return;
  }
  const isMod = Boolean(user.isAdmin || user.isMod);
  const active = db
    .prepare(
      "SELECT id FROM mod_role_periods WHERE user_id = ? AND end_at IS NULL"
    )
    .get(user.id);
  if (isMod && !active) {
    db.prepare(
      "INSERT INTO mod_role_periods (user_id, start_at, end_at) VALUES (?, ?, NULL)"
    ).run(user.id, Date.now());
  } else if (!isMod && active) {
    db.prepare("UPDATE mod_role_periods SET end_at = ? WHERE id = ?").run(
      Date.now(),
      active.id
    );
  }
}

function formatDuration(totalMs) {
  const totalSeconds = Math.max(0, Math.floor(totalMs / 1000));
  const days = Math.floor(totalSeconds / 86400);
  const hours = Math.floor((totalSeconds % 86400) / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  if (days > 0) {
    return `${days}d ${hours}h`;
  }
  if (hours > 0) {
    return `${hours}h ${minutes}m`;
  }
  return `${minutes}m`;
}

function requireRole(role) {
  return (req, res, next) => {
    if (!req.session.user) {
      return res.redirect(getLoginRedirectPath(req));
    }
    if (!hasAccess(req.session.user, role)) {
      return res.status(403).render("error", {
        title: "Access denied",
        message: "You do not have access to that page."
      });
    }
    next();
  };
}

function formatPlaceholderErrors(errors = []) {
  const tokens = errors
    .map((error) => error.token || error.id || error.reason)
    .filter(Boolean)
    .slice(0, 5);
  return tokens.length
    ? `Unavailable or unauthorized placeholder(s): ${tokens.join(", ")}.`
    : "Unavailable or unauthorized placeholder.";
}

function storeDiscordUser(user) {
  const avatar = user.avatar
    ? `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png?size=128`
    : null;
  const displayName = user.global_name || user.username;
  return ensureUserForIdentity({
    provider: "discord",
    providerUserId: user.id,
    displayName,
    avatar
  });
}

async function fetchDiscordRolesForUser(discordUserId) {
  const guildId = getSetting("discord_guild_id");
  const botToken = getSetting("discord_bot_token");
  if (!guildId || !botToken || !discordUserId) {
    return [];
  }
  try {
    const response = await fetch(
      `https://discord.com/api/guilds/${guildId}/members/${discordUserId}`,
      { headers: { Authorization: `Bot ${botToken}` } }
    );
    if (!response.ok) {
      return [];
    }
    const member = await response.json();
    return member?.roles || [];
  } catch {
    return [];
  }
}

function getPreferredAvatar(userId) {
  if (!userId) {
    return null;
  }
  const identities = db
    .prepare("SELECT provider, avatar FROM user_identities WHERE user_id = ?")
    .all(userId);
  const preferredOrder = ["discord", "twitch", "youtube"];
  for (const provider of preferredOrder) {
    const match = identities.find((identity) => identity.provider === provider);
    if (match?.avatar) {
      return match.avatar;
    }
  }
  const fallback = identities.find((identity) => identity.avatar);
  return fallback?.avatar || null;
}

function hasExpressionTables() {
  const row = db
    .prepare(
      "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'expression_user_stats'"
    )
    .get();
  return Boolean(row);
}

function getExpressionUserSummary(userId) {
  if (!hasExpressionTables()) {
    return null;
  }
  const rows = db
    .prepare(
      "SELECT action, given_count, received_count FROM expression_user_stats WHERE user_id = ?"
    )
    .all(userId);
  const totals = rows.reduce(
    (acc, row) => {
      acc.given += row.given_count;
      acc.received += row.received_count;
      return acc;
    },
    { given: 0, received: 0 }
  );
  return { totals };
}

function buildUserStatsPayload(userId) {
  if (!userId) {
    return { stats: null, expression: null, pluginStats: [] };
  }
  const stats = db
    .prepare("SELECT * FROM stats WHERE user_id = ?")
    .get(userId);
  return {
    stats,
    expression: getExpressionUserSummary(userId),
    pluginStats: getPluginProfileStats(userId)
  };
}

function buildCompareRows(leftStats, rightStats) {
  const rows = [];
  const pushSection = (section, leftList, rightList) => {
    const leftMap = new Map((leftList || []).map((item) => [item.label, item.value]));
    const rightMap = new Map((rightList || []).map((item) => [item.label, item.value]));
    const labels = [];
    for (const label of leftMap.keys()) {
      labels.push(label);
    }
    for (const label of rightMap.keys()) {
      if (!leftMap.has(label)) {
        labels.push(label);
      }
    }
    labels.forEach((label) => {
      rows.push({
        section,
        label,
        left: leftMap.has(label) ? leftMap.get(label) : null,
        right: rightMap.has(label) ? rightMap.get(label) : null
      });
    });
  };

  const leftCommunity = [
    { label: "Messages", value: leftStats.stats?.messages ?? 0 },
    { label: "Commands", value: leftStats.stats?.commands ?? 0 }
  ];
  const rightCommunity = [
    { label: "Messages", value: rightStats.stats?.messages ?? 0 },
    { label: "Commands", value: rightStats.stats?.commands ?? 0 }
  ];
  pushSection("Community Interaction", leftCommunity, rightCommunity);

  if (leftStats.expression || rightStats.expression) {
    const leftExpression = leftStats.expression
      ? [
          { label: "Actions given", value: leftStats.expression.totals.given },
          { label: "Actions received", value: leftStats.expression.totals.received }
        ]
      : [];
    const rightExpression = rightStats.expression
      ? [
          { label: "Actions given", value: rightStats.expression.totals.given },
          { label: "Actions received", value: rightStats.expression.totals.received }
        ]
      : [];
    pushSection("Expression Interaction", leftExpression, rightExpression);
  }

  const pluginSections = new Map();
  leftStats.pluginStats.forEach((section) => {
    pluginSections.set(section.title, {
      left: section.stats || [],
      right: []
    });
  });
  rightStats.pluginStats.forEach((section) => {
    const entry = pluginSections.get(section.title) || { left: [], right: [] };
    entry.right = section.stats || [];
    pluginSections.set(section.title, entry);
  });
  for (const [title, lists] of pluginSections.entries()) {
    pushSection(title, lists.left, lists.right);
  }

  return rows;
}

function getExpressionLeaderboards(limit = 10) {
  if (!hasExpressionTables()) {
    return null;
  }
  const given = db
    .prepare(
      "SELECT user_profiles.internal_username AS username, SUM(expression_user_stats.given_count) AS total " +
        "FROM expression_user_stats " +
        "JOIN user_profiles ON user_profiles.id = expression_user_stats.user_id " +
        "GROUP BY expression_user_stats.user_id " +
        "ORDER BY total DESC LIMIT ?"
    )
    .all(limit);
  const received = db
    .prepare(
      "SELECT user_profiles.internal_username AS username, SUM(expression_user_stats.received_count) AS total " +
        "FROM expression_user_stats " +
        "JOIN user_profiles ON user_profiles.id = expression_user_stats.user_id " +
        "GROUP BY expression_user_stats.user_id " +
        "ORDER BY total DESC LIMIT ?"
    )
    .all(limit);
  return { given, received };
}

const DISCORD_PERMISSION_DETAILS = {
  CREATE_INSTANT_INVITE: {
    label: "Create instant invites",
    description: "Create invitations to the server."
  },
  KICK_MEMBERS: {
    label: "Kick members",
    description: "Kick members from the server."
  },
  BAN_MEMBERS: {
    label: "Ban members",
    description: "Ban or unban members from the server."
  },
  ADMINISTRATOR: {
    label: "Administrator",
    description: "Bypasses all permission checks and grants every permission."
  },
  MANAGE_CHANNELS: {
    label: "Manage channels",
    description: "Create, edit, or delete channels."
  },
  MANAGE_GUILD: {
    label: "Manage server",
    description: "Edit server settings and features."
  },
  ADD_REACTIONS: {
    label: "Add reactions",
    description: "Add new reactions to messages."
  },
  VIEW_AUDIT_LOG: {
    label: "View audit log",
    description: "View the server audit log."
  },
  PRIORITY_SPEAKER: {
    label: "Priority speaker",
    description: "Use priority speaker in voice channels."
  },
  STREAM: {
    label: "Stream",
    description: "Stream video in voice channels."
  },
  VIEW_CHANNEL: {
    label: "View channels",
    description: "View channels and read messages."
  },
  SEND_MESSAGES: {
    label: "Send messages",
    description: "Send messages in text channels."
  },
  SEND_TTS_MESSAGES: {
    label: "Send TTS messages",
    description: "Send text-to-speech messages."
  },
  MANAGE_MESSAGES: {
    label: "Manage messages",
    description: "Delete messages and manage pins."
  },
  EMBED_LINKS: {
    label: "Embed links",
    description: "Send embedded link previews."
  },
  ATTACH_FILES: {
    label: "Attach files",
    description: "Attach files and media."
  },
  READ_MESSAGE_HISTORY: {
    label: "Read message history",
    description: "Read messages posted before the bot joined the channel."
  },
  MENTION_EVERYONE: {
    label: "Mention everyone",
    description: "Use @everyone, @here, and role mentions."
  },
  USE_EXTERNAL_EMOJIS: {
    label: "Use external emojis",
    description: "Use emojis from other servers."
  },
  VIEW_GUILD_INSIGHTS: {
    label: "View server insights",
    description: "Access server insights."
  },
  CONNECT: {
    label: "Connect to voice",
    description: "Join voice channels."
  },
  SPEAK: {
    label: "Speak in voice",
    description: "Speak in voice channels."
  },
  MUTE_MEMBERS: {
    label: "Mute members",
    description: "Server mute members in voice."
  },
  DEAFEN_MEMBERS: {
    label: "Deafen members",
    description: "Server deafen members in voice."
  },
  MOVE_MEMBERS: {
    label: "Move members",
    description: "Move members between voice channels."
  },
  USE_VAD: {
    label: "Use voice activity detection",
    description: "Use voice activity detection."
  },
  CHANGE_NICKNAME: {
    label: "Change nickname",
    description: "Change the bot's nickname."
  },
  MANAGE_NICKNAMES: {
    label: "Manage nicknames",
    description: "Change other members' nicknames."
  },
  MANAGE_ROLES: {
    label: "Manage roles",
    description: "Create, edit, and assign roles."
  },
  MANAGE_WEBHOOKS: {
    label: "Manage webhooks",
    description: "Create, edit, and delete webhooks."
  },
  MANAGE_EMOJIS_AND_STICKERS: {
    label: "Manage emojis and stickers",
    description: "Create, edit, and delete emojis or stickers."
  },
  USE_APPLICATION_COMMANDS: {
    label: "Use application commands",
    description: "Use slash commands and context menu commands."
  },
  REQUEST_TO_SPEAK: {
    label: "Request to speak",
    description: "Request to speak in stage channels."
  },
  MANAGE_EVENTS: {
    label: "Manage events",
    description: "Create and manage scheduled events."
  },
  MANAGE_THREADS: {
    label: "Manage threads",
    description: "Manage threads and thread settings."
  },
  USE_PUBLIC_THREADS: {
    label: "Use public threads",
    description: "Use public threads (deprecated flag)."
  },
  CREATE_PUBLIC_THREADS: {
    label: "Create public threads",
    description: "Create public threads."
  },
  USE_PRIVATE_THREADS: {
    label: "Use private threads",
    description: "Use private threads (deprecated flag)."
  },
  CREATE_PRIVATE_THREADS: {
    label: "Create private threads",
    description: "Create private threads."
  },
  USE_EXTERNAL_STICKERS: {
    label: "Use external stickers",
    description: "Use stickers from other servers."
  },
  SEND_MESSAGES_IN_THREADS: {
    label: "Send messages in threads",
    description: "Send messages in threads."
  },
  START_EMBEDDED_ACTIVITIES: {
    label: "Start embedded activities",
    description: "Start embedded activities in voice channels."
  },
  MODERATE_MEMBERS: {
    label: "Moderate members",
    description: "Timeout members."
  },
  VIEW_CREATOR_MONETIZATION_ANALYTICS: {
    label: "View monetization analytics",
    description: "View creator monetization analytics."
  },
  USE_SOUNDBOARD: {
    label: "Use soundboard",
    description: "Use the soundboard in voice."
  },
  SEND_VOICE_MESSAGES: {
    label: "Send voice messages",
    description: "Send voice messages."
  }
};

const TWITCH_SCOPE_DEFS = [
  {
    scope: "analytics:read:extensions",
    label: "Extensions analytics",
    description: "Read analytics data for extensions."
  },
  {
    scope: "analytics:read:games",
    label: "Games analytics",
    description: "Read analytics data for games."
  },
  {
    scope: "bits:read",
    label: "Bits",
    description: "Read Bits leaderboard data."
  },
  {
    scope: "channel:bot",
    label: "Channel bot",
    description: "Act as a bot within a channel."
  },
  {
    scope: "channel:edit:commercial",
    label: "Run commercials",
    description: "Run commercials on a channel."
  },
  {
    scope: "channel:manage:ads",
    label: "Manage ads",
    description: "Manage ad settings for a channel."
  },
  {
    scope: "channel:manage:broadcast",
    label: "Manage broadcast",
    description: "Manage stream metadata and settings."
  },
  {
    scope: "channel:manage:extensions",
    label: "Manage extensions",
    description: "Manage channel extensions."
  },
  {
    scope: "channel:manage:moderators",
    label: "Manage moderators",
    description: "Add or remove moderators."
  },
  {
    scope: "channel:manage:polls",
    label: "Manage polls",
    description: "Create and manage polls."
  },
  {
    scope: "channel:manage:predictions",
    label: "Manage predictions",
    description: "Create and manage predictions."
  },
  {
    scope: "channel:manage:raids",
    label: "Manage raids",
    description: "Start and cancel channel raids from Lumi commands."
  },
  {
    scope: "channel:manage:redemptions",
    label: "Manage redemptions",
    description: "Manage channel points rewards."
  },
  {
    scope: "channel:manage:schedule",
    label: "Manage schedule",
    description: "Manage channel schedule."
  },
  {
    scope: "channel:manage:videos",
    label: "Manage videos",
    description: "Manage videos for a channel."
  },
  {
    scope: "channel:manage:vips",
    label: "Manage VIPs",
    description: "Add or remove VIPs."
  },
  {
    scope: "channel:read:ads",
    label: "Read ads",
    description: "Read ad schedule data."
  },
  {
    scope: "channel:read:charity",
    label: "Read charity",
    description: "Read charity campaign data."
  },
  {
    scope: "channel:manage:charity",
    label: "Manage charity",
    description: "Manage charity campaign settings."
  },
  {
    scope: "channel:read:editors",
    label: "Read editors",
    description: "Read channel editor list."
  },
  {
    scope: "channel:read:goals",
    label: "Read goals",
    description: "Read creator goal data."
  },
  {
    scope: "channel:read:hype_train",
    label: "Read hype train",
    description: "Read hype train data."
  },
  {
    scope: "channel:read:polls",
    label: "Read polls",
    description: "Read poll data."
  },
  {
    scope: "channel:read:predictions",
    label: "Read predictions",
    description: "Read prediction data."
  },
  {
    scope: "channel:read:redemptions",
    label: "Read redemptions",
    description: "Read channel points rewards."
  },
  {
    scope: "channel:read:stream_key",
    label: "Read stream key",
    description: "Read the channel stream key."
  },
  {
    scope: "channel:read:subscriptions",
    label: "Read subscriptions",
    description: "Read subscriber data."
  },
  {
    scope: "channel:read:vips",
    label: "Read VIPs",
    description: "Read the VIP list."
  },
  {
    scope: "channel:moderate",
    label: "Channel moderation",
    description: "Perform channel moderation actions."
  },
  {
    scope: "chat:edit",
    label: "Chat edit",
    description: "Send chat messages."
  },
  {
    scope: "chat:read",
    label: "Chat read",
    description: "Read chat messages."
  },
  {
    scope: "clips:edit",
    label: "Edit clips",
    description: "Create or edit clips."
  },
  {
    scope: "moderation:read",
    label: "Read moderation",
    description: "Read moderation data."
  },
  {
    scope: "moderator:manage:announcements",
    label: "Manage announcements",
    description: "Send announcements in chat."
  },
  {
    scope: "moderator:manage:automod",
    label: "Manage AutoMod",
    description: "Manage AutoMod actions."
  },
  {
    scope: "moderator:manage:automod_settings",
    label: "Manage AutoMod settings",
    description: "Update AutoMod settings."
  },
  {
    scope: "moderator:manage:banned_users",
    label: "Manage banned users",
    description: "Ban or unban users."
  },
  {
    scope: "moderator:manage:blocked_terms",
    label: "Manage blocked terms",
    description: "Manage blocked terms."
  },
  {
    scope: "moderator:manage:chat_messages",
    label: "Manage chat messages",
    description: "Delete or manage chat messages."
  },
  {
    scope: "moderator:manage:chat_settings",
    label: "Manage chat settings",
    description: "Update chat settings."
  },
  {
    scope: "moderator:manage:shield_mode",
    label: "Manage shield mode",
    description: "Enable or disable shield mode."
  },
  {
    scope: "moderator:manage:shoutouts",
    label: "Manage shoutouts",
    description: "Send or manage shoutouts."
  },
  {
    scope: "moderator:read:automod_settings",
    label: "Read AutoMod settings",
    description: "Read AutoMod settings."
  },
  {
    scope: "moderator:read:blocked_terms",
    label: "Read blocked terms",
    description: "Read blocked terms."
  },
  {
    scope: "moderator:read:chat_settings",
    label: "Read chat settings",
    description: "Read chat settings."
  },
  {
    scope: "moderator:read:followers",
    label: "Read followers",
    description: "Read follower list."
  },
  {
    scope: "moderator:read:shield_mode",
    label: "Read shield mode",
    description: "Read shield mode status."
  },
  {
    scope: "moderator:read:shoutouts",
    label: "Read shoutouts",
    description: "Read shoutout settings."
  },
  {
    scope: "moderator:read:vips",
    label: "Read VIPs",
    description: "Read VIP list."
  },
  {
    scope: "user:bot",
    label: "User bot",
    description: "Act as a bot on behalf of a user."
  },
  {
    scope: "user:edit",
    label: "Edit user",
    description: "Edit a user's profile."
  },
  {
    scope: "user:edit:follows",
    label: "Edit follows",
    description: "Manage follows for a user."
  },
  {
    scope: "user:manage:blocked_users",
    label: "Manage blocked users",
    description: "Block or unblock users."
  },
  {
    scope: "user:manage:chat_color",
    label: "Manage chat color",
    description: "Change chat color."
  },
  {
    scope: "user:manage:whispers",
    label: "Manage whispers",
    description: "Send and manage whispers."
  },
  {
    scope: "user:read:blocked_users",
    label: "Read blocked users",
    description: "Read blocked users list."
  },
  {
    scope: "user:read:broadcast",
    label: "Read broadcast",
    description: "Read broadcast settings."
  },
  {
    scope: "user:read:email",
    label: "Read email",
    description: "Read the user's email address."
  },
  {
    scope: "user:read:follows",
    label: "Read follows",
    description: "Read the user's follows."
  },
  {
    scope: "user:read:subscriptions",
    label: "Read subscriptions",
    description: "Read user subscription data."
  },
  {
    scope: "user:read:chat",
    label: "Read chat",
    description: "Read chat messages via API."
  },
  {
    scope: "user:write:chat",
    label: "Write chat",
    description: "Send chat messages via API."
  },
  {
    scope: "whispers:read",
    label: "Read whispers",
    description: "Read whispers."
  },
  {
    scope: "whispers:edit",
    label: "Send whispers",
    description: "Send whispers."
  }
];

function buildPrivilegeRow(id, label, description, granted) {
  const safeLabel = (label || "").toString();
  const safeDescription = (description || "").toString();
  const grantedFlag = Boolean(granted);
  return {
    id,
    label: safeLabel,
    description: safeDescription,
    granted: grantedFlag,
    search: `${safeLabel} ${safeDescription} ${grantedFlag ? "granted" : "missing"}`.trim(),
    sort: {
      label: safeLabel.toLowerCase(),
      description: safeDescription.toLowerCase(),
      status: grantedFlag ? 1 : 0
    }
  };
}

function parseChannelList(value) {
  return (value || "")
    .split(/[,\s]+/g)
    .map((entry) => entry.trim())
    .filter(Boolean);
}

async function buildDiscordPrivileges(discordClient) {
  const rows = [];
  const guildId = getSetting("discord_guild_id");
  const hasClient = Boolean(discordClient && discordClient.user);

  rows.push(
    buildPrivilegeRow(
      "discord-client-ready",
      "Client connected",
      "The Discord client is logged in and ready.",
      hasClient
    )
  );
  rows.push(
    buildPrivilegeRow(
      "discord-guild-configured",
      "Guild configured",
      "A server ID is configured in settings.",
      Boolean(guildId)
    )
  );

  let guild = null;
  if (hasClient && guildId) {
    guild = discordClient.guilds?.cache?.get(guildId) || null;
    if (!guild && typeof discordClient.guilds?.fetch === "function") {
      try {
        guild = await discordClient.guilds.fetch(guildId);
      } catch {
        guild = null;
      }
    }
  }

  rows.push(
    buildPrivilegeRow(
      "discord-guild-access",
      "Bot in guild",
      "The bot can access the configured server.",
      Boolean(guild)
    )
  );

  let permissions = null;
  if (guild && discordClient?.user?.id) {
    try {
      const cachedMember = guild.members?.cache?.get(discordClient.user.id) || null;
      const member = cachedMember || (await guild.members.fetch(discordClient.user.id));
      permissions = member?.permissions || null;
    } catch {
      permissions = null;
    }
  }

  const permissionFlags = Permissions?.FLAGS || {};
  const canCheck = Boolean(permissions && typeof permissions.has === "function");
  for (const key of Object.keys(permissionFlags)) {
    const details = DISCORD_PERMISSION_DETAILS[key] || {
      label: toTitleCase(key),
      description: "Discord permission flag."
    };
    const flag = permissionFlags[key];
    const granted = canCheck && flag ? permissions.has(flag) : false;
    rows.push(
      buildPrivilegeRow(
        `discord-perm-${key.toLowerCase()}`,
        details.label,
        details.description,
        granted
      )
    );
  }

  return {
    rows,
    guildName: guild?.name || null
  };
}

async function buildTwitchPrivileges() {
  const clientId = getSetting("twitch_client_id");
  const clientSecret = getSetting("twitch_client_secret");
  const redirectUri = getSetting("twitch_redirect_uri");
  const botUsername = getSetting("twitch_bot_username");
  const botOauth = getSetting("twitch_bot_oauth");
  const channels = parseChannelList(getSetting("twitch_channels"));
  const twitchClient = getTwitchClient();
  const connected = Boolean(twitchClient);
  const joinedChannels =
    twitchClient && typeof twitchClient.getChannels === "function"
      ? twitchClient.getChannels()
      : [];

  const rows = [
    buildPrivilegeRow(
      "twitch-client-id",
      "Client ID",
      "A Twitch app client ID is configured.",
      Boolean(clientId)
    ),
    buildPrivilegeRow(
      "twitch-client-secret",
      "Client secret",
      "A Twitch app client secret is configured.",
      Boolean(clientSecret)
    ),
    buildPrivilegeRow(
      "twitch-redirect",
      "OAuth redirect URL",
      "The OAuth redirect URL is configured.",
      Boolean(redirectUri)
    ),
    buildPrivilegeRow(
      "twitch-bot-username",
      "Bot username",
      "The chat bot username is configured.",
      Boolean(botUsername)
    ),
    buildPrivilegeRow(
      "twitch-bot-oauth",
      "Bot OAuth token",
      "The chat bot OAuth token is configured.",
      Boolean(botOauth)
    ),
    buildPrivilegeRow(
      "twitch-channels-configured",
      "Channels configured",
      "At least one channel is configured for chat.",
      channels.length > 0
    ),
    buildPrivilegeRow(
      "twitch-chat-connected",
      "Chat connected",
      "The Twitch chat client is connected.",
      connected
    ),
    buildPrivilegeRow(
      "twitch-channels-joined",
      "Channels joined",
      "The chat client has joined its configured channels.",
      joinedChannels.length > 0
    )
  ];

  let grantedScopes = [];
  if (botOauth) {
    const rawToken = botOauth.startsWith("oauth:") ? botOauth.slice(6) : botOauth;
    try {
      const response = await fetch("https://id.twitch.tv/oauth2/validate", {
        headers: { Authorization: `OAuth ${rawToken}` }
      });
      if (response.ok) {
        const data = await response.json();
        if (Array.isArray(data.scopes)) {
          grantedScopes = data.scopes;
        }
      }
    } catch {
      grantedScopes = [];
    }
  }

  const grantedSet = new Set(grantedScopes.map((scope) => scope.toLowerCase()));
  const knownScopeSet = new Set();
  const scopeRows = TWITCH_SCOPE_DEFS.map((def) => {
    const scopeKey = def.scope.toLowerCase();
    knownScopeSet.add(scopeKey);
    return buildPrivilegeRow(
      `twitch-scope-${slugify(def.scope)}`,
      def.label,
      def.description,
      grantedSet.has(scopeKey)
    );
  });

  const unknownScopes = grantedScopes.filter(
    (scope) => !knownScopeSet.has(scope.toLowerCase())
  );
  for (const scope of unknownScopes) {
    scopeRows.push(
      buildPrivilegeRow(
        `twitch-scope-${slugify(scope)}`,
        scope,
        "Granted by the token but not recognized by this version of the bot.",
        true
      )
    );
  }

  return {
    rows: [...rows, ...scopeRows],
    channelCount: channels.length
  };
}

function readJsonSafe(filePath) {
  try {
    const raw = fs.readFileSync(filePath, "utf8");
    return JSON.parse(raw);
  } catch {
    return null;
  }
}

function parseBooleanSetting(value, fallback) {
  if (value === undefined || value === null || value === "") {
    return fallback;
  }
  if (typeof value === "boolean") {
    return value;
  }
  const normalized = value.toString().toLowerCase();
  return ["1", "true", "yes", "on"].includes(normalized);
}

function getPluginSettingsMap(pluginId) {
  const rows = db
    .prepare("SELECT key, value FROM plugin_settings WHERE plugin_id = ?")
    .all(pluginId);
  return rows.reduce((acc, row) => {
    acc[row.key] = row.value;
    return acc;
  }, {});
}

function normalizeCommandTrigger(value, fallback = "") {
  const raw = (value || fallback || "").toString().trim().replace(/^!+/, "");
  if (!raw) {
    return "";
  }
  return raw.split(/\s+/)[0].toLowerCase();
}

function normalizeSubcommand(value) {
  const raw = (value || "").toString().trim().replace(/^!+/, "");
  if (!raw) {
    return "";
  }
  return raw.split(/\s+/)[0].toLowerCase();
}

function buildUsage(baseTrigger, usage) {
  const raw = (usage || baseTrigger || "").toString().trim().replace(/^!+/, "");
  return raw || baseTrigger;
}

function normalizeCustomPlatforms(value, availablePlatforms) {
  return normalizePlatformSelection(value, availablePlatforms);
}

function parsePlatformSelectionFromBody(body, availablePlatforms) {
  const raw = Array.isArray(body.platforms)
    ? body.platforms.join(",")
    : body.platforms || body.platform;
  return normalizePlatformSelection(raw, availablePlatforms);
}

function emptyCommandPreview() {
  return {
    preview_text: null,
    preview_status: null,
    preview_error: null,
    preview_generated_at: null,
    preview_dynamic_segments: "[]"
  };
}

function buildCommandPreviewPresentation(command) {
  const text = String(command.preview_text || "");
  return {
    text,
    status: command.preview_status || (text ? "ready" : "unavailable"),
    error: command.preview_error || "Run preview to generate an example output.",
    generatedAt: command.preview_generated_at || null,
    isLong: text.length > 160 || text.includes("\n"),
    parts: previewParts(text, command.preview_dynamic_segments)
  };
}

function randomCommandConfigFromBody(body = {}) {
  return validateRandomConfig({
    replies: parseRandomRepliesFromBody(body),
    rngEnabled: body.rng_enabled,
    rngMin: body.rng_min,
    rngMax: body.rng_max
  });
}

function validateRandomReplyTemplates(config, user) {
  for (const reply of config.replies) {
    const validation = placeholders.validateTemplate({
      fieldId: "core.custom_commands.static_response",
      template: reply.text,
      outputAudience: "user",
      user
    });
    if (!validation.ok) return formatPlaceholderErrors(validation.errors);
  }
  return "";
}

function buildRandomCommandPresentation(command) {
  const replies = normalizeRandomReplies(command.random_replies_json);
  try {
    const selected = selectRandomReply({
      replies,
      rngEnabled: Boolean(command.rng_enabled),
      rngMin: command.rng_min,
      rngMax: command.rng_max
    }, () => 0.424242);
    return {
      replies,
      example: selected.reply.text.replaceAll("{{core.command.rng}}", selected.rng === null ? "" : String(selected.rng)),
      rng: selected.rng,
      error: ""
    };
  } catch (error) {
    return { replies, example: "", rng: null, error: error.message };
  }
}

function buildConditionalCommandPresentation(command) {
  return { replies: normalizeConditionalReplyRows(command.conditional_replies_json) };
}

function validateConditionalReplyTemplates(config, user) {
  for (const reply of config.replies) {
    const validation = placeholders.validateTemplate({
      fieldId: "core.custom_commands.static_response",
      template: reply.response,
      outputAudience: "user",
      user
    });
    if (!validation.ok) return formatPlaceholderErrors(validation.errors);
  }
  return "";
}

function buildCustomCommandListPreview(command) {
  if (command.mode === "advanced") {
    return buildCommandPreviewPresentation(command);
  }
  if (command.mode === "random") {
    const random = buildRandomCommandPresentation(command);
    const text = String(random.example || "");
    return {
      text,
      status: text ? "ready" : "unavailable",
      error: random.error || "Preview unavailable.",
      generatedAt: null,
      isLong: text.length > 160 || text.includes("\n"),
      parts: previewParts(text, [])
    };
  }
  if (command.mode === "conditional") {
    const replies = normalizeConditionalReplies(command.conditional_replies_json);
    const text = String(command.response || `Available options: ${replies.map((entry) => entry.keyword).join(", ")}`);
    return {
      text,
      status: text ? "ready" : "unavailable",
      error: "Preview unavailable.",
      generatedAt: null,
      isLong: text.length > 160 || text.includes("\n"),
      parts: previewParts(text, [])
    };
  }
  const text = String(command.response || "");
  return {
    text,
    status: text ? "ready" : "unavailable",
    error: "Preview unavailable.",
    generatedAt: null,
    isLong: text.length > 160 || text.includes("\n"),
    parts: previewParts(text, [])
  };
}

function commandPolicyFromBody(body = {}, { allowInherit = true, prefix = "" } = {}) {
  const output = {};
  const field = (name) => body[`${prefix}${name}`];
  const mode = (name) => String(field(`${name}_mode`) || (allowInherit ? "inherit" : "off"));
  const assign = (name, value) => {
    const selected = mode(name);
    if (selected === "inherit" && allowInherit) return;
    output[name] = selected === "off" ? false : value;
  };
  assign("window", {
    uses: field("window_uses"),
    seconds: field("window_seconds"),
    scope: field("window_scope")
  });
  assign("perStream", {
    uses: field("perStream_uses"),
    scope: field("perStream_scope")
  });
  const requirementMode = mode("requirement");
  if (!(allowInherit && requirementMode === "inherit")) {
    output.requirement = requirementMode === "off" ? false : {
      role: field("requirement_role"),
      subscriberTier: field("requirement_subscriber_tier")
    };
  }
  assign("cost", { amount: field("cost_amount") });
  return normalizeStoredPolicy(output);
}

function asStringArray(value) {
  if (Array.isArray(value)) return value.map(String);
  return value === undefined || value === null || value === "" ? [] : [String(value)];
}

function commandPolicyPresentation(key, defaultPolicy = {}) {
  const resolved = resolvePolicy(key, defaultPolicy);
  const roles = [...new Set(resolved.requirements.map((item) => item.value?.role).filter(Boolean))];
  const details = [];
  if (resolved.windows.length) details.push("rate limited");
  if (resolved.perStreams.length) details.push("limited per stream");
  if (resolved.cost > 0) details.push(`costs ${resolved.cost} currency`);
  return {
    level: roles.length ? roles.map((role) => role === "subscriber" ? "subscriber/member" : role).join(" + ") : "public",
    levelHelp: details.length ? `This command is ${details.join(", ")}.` : ""
  };
}

function commandPolicyEffectivePresentation(key, defaultPolicy = {}) {
  const resolved = resolvePolicy(key, defaultPolicy);
  const inheritedWindow = resolvePolicy(key, defaultPolicy, { ignoreDirect: ["window"] });
  const inheritedStream = resolvePolicy(key, defaultPolicy, { ignoreDirect: ["perStream"] });
  const inheritedRequirement = resolvePolicy(key, defaultPolicy, { ignoreDirect: ["requirement"] });
  const inheritedCost = resolvePolicy(key, defaultPolicy, { ignoreDirect: ["cost"] });
  const formatScope = (scope) => scope === "global" ? "shared by everyone" : "per user";
  const joinRules = (rules, formatter, empty) => rules.length
    ? rules.map((rule) => `${rule.source}: ${formatter(rule.value)}`).join(" · ")
    : empty;
  const assignedGroups = resolved.groups || [];
  return {
    window: joinRules(inheritedWindow.windows, (value) => `${value.uses} use${value.uses === 1 ? "" : "s"} per ${value.seconds} seconds, ${formatScope(value.scope)}`, "No time-window limit."),
    perStream: joinRules(inheritedStream.perStreams, (value) => `${value.uses} use${value.uses === 1 ? "" : "s"} per stream, ${formatScope(value.scope)}`, "No per-stream limit."),
    requirement: inheritedRequirement.requirements.length
      ? inheritedRequirement.requirements.map((item) => `${item.source}: ${labelRequirement(item.value.role, item.value.subscriberTier)}`).join(" · ")
      : "Everyone may use it.",
    cost: inheritedCost.cost > 0 ? `${inheritedCost.cost} currency per successful run.` : "Free to use.",
    flags: {
      rate: resolved.windows.length > 0,
      stream: resolved.perStreams.length > 0,
      access: resolved.requirements.length > 0,
      cost: resolved.cost > 0,
      groups: assignedGroups.length > 0
    }
  };
}

function customPlaceholdersFromBody(body = {}) {
  const array = (value) => Array.isArray(value) ? value : value === undefined ? [] : [value];
  const names = array(body.custom_placeholder_name);
  const values = array(body.custom_placeholder_value);
  const visibilities = array(body.custom_placeholder_visibility);
  const descriptions = array(body.custom_placeholder_description);
  return names.map((name, index) => ({
    name,
    value: values[index] ?? "",
    visibility: visibilities[index] || "",
    description: descriptions[index] || ""
  })).filter((row) => String(row.name || row.value || row.description).trim());
}

function buildPlatformLabels(platforms) {
  return platforms.map((platform) => ({
    key: getPlatformBadge(platform),
    label: getPlatformLabel(platform)
  }));
}

const LOG_LEVELS = new Set(["debug", "info", "warn", "error"]);
const LOG_LIMITS = new Set([50, 100, 250, 500]);
const DEFAULT_LOG_RANGE_MS = 24 * 60 * 60 * 1000;
const DASHBOARD_SCOPES = {
  "5m": 5 * 60 * 1000,
  "24h": 24 * 60 * 60 * 1000,
  "7d": 7 * 24 * 60 * 60 * 1000
};
const memorySamples = [];
const webLog = createLogger("core:web", { category: "http" });

function normalizeLogLevel(value) {
  const normalized = (value || "").toString().trim().toLowerCase();
  return LOG_LEVELS.has(normalized) ? normalized : "";
}

function parseLogLevels(value) {
  if (!value || value === "all") {
    return [];
  }
  const raw = Array.isArray(value) ? value : value.toString().split(",");
  return raw.map(normalizeLogLevel).filter(Boolean);
}

function normalizeLogFacet(value) {
  return String(value || "").trim().toLowerCase().replace(/[^a-z0-9_.:-]+/g, "-").slice(0, 80);
}

function parseLogSearch(value) {
  return String(value || "").trim().slice(0, 200);
}

function parseLogRange(value) {
  if (value === undefined || value === null || value === "") {
    return { rangeMs: DEFAULT_LOG_RANGE_MS, rangeValue: `${DEFAULT_LOG_RANGE_MS}` };
  }
  const normalized = value.toString().trim().toLowerCase();
  if (normalized === "all") {
    return { rangeMs: null, rangeValue: "all" };
  }
  const parsed = Number(normalized);
  if (!Number.isNaN(parsed) && parsed > 0) {
    return { rangeMs: parsed, rangeValue: `${parsed}` };
  }
  return { rangeMs: DEFAULT_LOG_RANGE_MS, rangeValue: `${DEFAULT_LOG_RANGE_MS}` };
}

function parseLogLimit(value, { allowAll = false } = {}) {
  if (value === undefined || value === null || value === "") {
    return { limit: 50, limitValue: "50" };
  }
  const normalized = value.toString().trim().toLowerCase();
  if (allowAll && normalized === "all") {
    return { limit: null, limitValue: "all" };
  }
  const parsed = Number(normalized);
  if (!Number.isNaN(parsed) && LOG_LIMITS.has(parsed)) {
    return { limit: parsed, limitValue: `${parsed}` };
  }
  return { limit: 50, limitValue: "50" };
}

function parseDashboardScope(value) {
  const normalized = String(value || "5m").trim().toLowerCase();
  return DASHBOARD_SCOPES[normalized] ? normalized : "5m";
}

function recordMemorySample(memory = process.memoryUsage(), now = Date.now()) {
  const last = memorySamples[memorySamples.length - 1];
  if (!last || now - last.sampled_at >= 10 * 1000) {
    memorySamples.push({
      sampled_at: now,
      rss: memory.rss,
      heap_used: memory.heapUsed,
      heap_total: memory.heapTotal
    });
  }
  const oldest = now - DASHBOARD_SCOPES["7d"];
  while (memorySamples.length && memorySamples[0].sampled_at < oldest) {
    memorySamples.shift();
  }
}

function scopedMemorySamples(now = Date.now()) {
  return Object.fromEntries(
    Object.entries(DASHBOARD_SCOPES).map(([scope, duration]) => [
      scope,
      memorySamples.filter((sample) => sample.sampled_at >= now - duration)
    ])
  );
}

function countLogsByLevel(logs) {
  const counts = { error: 0, warn: 0, info: 0, debug: 0 };
  for (const entry of logs) {
    if (counts[entry.level] !== undefined) counts[entry.level] += 1;
  }
  return counts;
}

function countVisibleCommands() {
  const enabledPlatforms = getEnabledPlatformIds();
  const commands = [];

  const addCommand = (command) => {
    if (!command.trigger) {
      return;
    }
    commands.push({
      trigger: command.trigger,
      subcommand: command.subcommand || ""
    });
  };

  try {
    const customCommands = db
      .prepare("SELECT trigger, platform FROM custom_commands WHERE enabled = 1")
      .all();
    for (const row of customCommands) {
      const trigger = normalizeCommandTrigger(row.trigger);
      const platforms = normalizeCustomPlatforms(row.platform, enabledPlatforms);
      addCommand({ trigger, platforms });
    }
  } catch {
    return 0;
  }

  const topOptions = getTopCommandOptions();
  if (topOptions.length) {
    addCommand({ trigger: "top", platforms: enabledPlatforms });
    for (const option of topOptions) {
      const subcommand = normalizeSubcommand(option.id);
      addCommand({ trigger: "top", subcommand, platforms: enabledPlatforms });
    }
  }

  const plugins = getPlugins().filter((plugin) => plugin.enabled);
  for (const plugin of plugins) {
    const cmdsPath = path.join(plugin.path, "cmds.json");
    if (!fs.existsSync(cmdsPath)) {
      continue;
    }
    const manifest = readJsonSafe(cmdsPath);
    if (!manifest || !Array.isArray(manifest.commands)) {
      continue;
    }
    const pluginSettings = getPluginSettingsMap(plugin.id);
    const platformKeys = manifest.platformKeys || {};
    const platformFlags = {};
    for (const platform of enabledPlatforms) {
      platformFlags[platform] = platformKeys[platform]
        ? parseBooleanSetting(pluginSettings[platformKeys[platform]], true)
        : true;
    }

    for (const command of manifest.commands) {
      if (!command || !command.trigger) {
        continue;
      }
      const enabled = command.enabledKey
        ? parseBooleanSetting(pluginSettings[command.enabledKey], true)
        : true;
      if (!enabled) {
        continue;
      }
      const override = command.triggerKey ? pluginSettings[command.triggerKey] : "";
      const trigger = normalizeCommandTrigger(override, command.trigger);
      const subcommand = normalizeSubcommand(command.subcommand);
      const platforms = (Array.isArray(command.platforms) && command.platforms.length
        ? command.platforms
        : enabledPlatforms
      ).filter((platform) => platformFlags[platform] && enabledPlatforms.includes(platform));
      if (!platforms.length) {
        continue;
      }
      addCommand({ trigger, subcommand, platforms });
    }
  }

  const roots = new Set();
  const subcommandTriggers = new Set();
  let total = 0;
  for (const command of commands) {
    if (command.subcommand) {
      subcommandTriggers.add(command.trigger);
      total += 1;
    } else {
      roots.add(command.trigger);
      total += 1;
    }
  }
  for (const trigger of subcommandTriggers) {
    if (!roots.has(trigger)) {
      total += 1;
    }
  }
  return total;
}

function normalizePageFormat(value) {
  const normalized = (value || "").toString().trim().toLowerCase();
  return normalized === "markdown" ? "markdown" : "html";
}

function escapeHtml(value) {
  const map = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot;",
    "'": "&#39;"
  };
  return (value || "").toString().replace(/[&<>"']/g, (char) => map[char]);
}

function renderMarkdownInline(value) {
  let output = escapeHtml(value);
  output = output.replace(/`([^`]+)`/g, "<code>$1</code>");
  output = output.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (match, text, url) => {
    return `<a href="${url}" target="_blank" rel="noopener noreferrer">${text}</a>`;
  });
  output = output.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
  output = output.replace(/\*([^*]+)\*/g, "<em>$1</em>");
  return output;
}

function renderMarkdown(value) {
  const lines = (value || "").toString().replace(/\r\n?/g, "\n").split("\n");
  let html = "";
  let paragraph = [];
  let listType = null;
  let inCode = false;
  let codeLang = "";
  let codeLines = [];

  const flushParagraph = () => {
    if (!paragraph.length) {
      return;
    }
    html += `<p>${renderMarkdownInline(paragraph.join(" "))}</p>`;
    paragraph = [];
  };

  const closeList = () => {
    if (!listType) {
      return;
    }
    html += `</${listType}>`;
    listType = null;
  };

  lines.forEach((line) => {
    const trimmed = line.trim();
    if (inCode) {
      if (trimmed.startsWith("```")) {
        const codeBlock = escapeHtml(codeLines.join("\n"));
        const langClass = codeLang ? ` class="language-${codeLang}"` : "";
        html += `<pre><code${langClass}>${codeBlock}</code></pre>`;
        inCode = false;
        codeLang = "";
        codeLines = [];
        return;
      }
      codeLines.push(line);
      return;
    }

    if (trimmed.startsWith("```")) {
      flushParagraph();
      closeList();
      inCode = true;
      codeLang = trimmed.slice(3).trim();
      return;
    }

    if (!trimmed) {
      flushParagraph();
      closeList();
      return;
    }

    const headingMatch = trimmed.match(/^(#{1,6})\s+(.*)$/);
    if (headingMatch) {
      flushParagraph();
      closeList();
      const level = headingMatch[1].length;
      html += `<h${level}>${renderMarkdownInline(headingMatch[2])}</h${level}>`;
      return;
    }

    const listMatch = trimmed.match(/^([*-]|\d+\.)\s+(.*)$/);
    if (listMatch) {
      flushParagraph();
      const isOrdered = listMatch[1].endsWith(".");
      const nextListType = isOrdered ? "ol" : "ul";
      if (listType && listType !== nextListType) {
        closeList();
      }
      if (!listType) {
        listType = nextListType;
        html += `<${listType}>`;
      }
      html += `<li>${renderMarkdownInline(listMatch[2])}</li>`;
      return;
    }

    paragraph.push(trimmed);
  });

  if (inCode) {
    const codeBlock = escapeHtml(codeLines.join("\n"));
    const langClass = codeLang ? ` class="language-${codeLang}"` : "";
    html += `<pre><code${langClass}>${codeBlock}</code></pre>`;
  }

  flushParagraph();
  closeList();
  return html || "<p></p>";
}

function buildCustomPageSrcdoc(page, theme) {
  const content = (page?.content || "").toString();
  const css = (page?.content_css || "").toString();
  const themeCss = theme
    ? [
        ":root {",
        `  --ink: ${theme.light.text};`,
        `  --ink-soft: ${theme.light.muted};`,
        `  --sea: ${theme.light.accent};`,
        `  --sun: ${theme.light.accentAlt};`,
        `  --rose: ${theme.light.danger};`,
        `  --card: ${theme.light.surface};`,
        `  --surface-2: ${theme.light.surface2};`,
        `  --surface-3: ${theme.light.surface3};`,
        `  --border: ${theme.light.border};`,
        `  --bg-1: ${theme.light.bg1};`,
        `  --bg-2: ${theme.light.bg2};`,
        `  --bg-3: ${theme.light.bg3};`,
        `  --success: ${theme.light.success};`,
        `  --warning: ${theme.light.warning};`,
        `  --info: ${theme.light.info};`,
        `  --link: ${theme.light.link};`,
        `  --radius: ${theme.metrics.radius}px;`,
        `  --spacing-scale: ${theme.metrics.spacingScale};`,
        "}",
        "@media (prefers-color-scheme: dark) {",
        "  :root {",
        `    --ink: ${theme.dark.text};`,
        `    --ink-soft: ${theme.dark.muted};`,
        `    --sea: ${theme.dark.accent};`,
        `    --sun: ${theme.dark.accentAlt};`,
        `    --rose: ${theme.dark.danger};`,
        `    --card: ${theme.dark.surface};`,
        `    --surface-2: ${theme.dark.surface2};`,
        `    --surface-3: ${theme.dark.surface3};`,
        `    --border: ${theme.dark.border};`,
        `    --bg-1: ${theme.dark.bg1};`,
        `    --bg-2: ${theme.dark.bg2};`,
        `    --bg-3: ${theme.dark.bg3};`,
        `    --success: ${theme.dark.success};`,
        `    --warning: ${theme.dark.warning};`,
        `    --info: ${theme.dark.info};`,
        `    --link: ${theme.dark.link};`,
        "  }",
        "}"
      ].join("\n")
    : "";
  const baseCss = [
    "* { box-sizing: border-box; }",
    "html, body { margin: 0; padding: 0; }",
    "body {",
    "  font-family: \"Source Sans 3\", sans-serif;",
    "  color: var(--ink, #121518);",
    "  background: transparent;",
    "}"
  ].join("\n");
  const fullCss = [themeCss, baseCss, css].filter(Boolean).join("\n\n");

  return [
    "<!doctype html>",
    "<html lang=\"en\">",
    "<head>",
    "  <meta charset=\"utf-8\" />",
    "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />",
    "  <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&family=Source+Sans+3:wght@400;600&display=swap\" />",
    "  <style>",
    fullCss,
    "  </style>",
    "</head>",
    "<body>",
    content,
    "</body>",
    "</html>"
  ].join("\n");
}

function buildCommandUsageMap() {
  const rows = db.prepare("SELECT command_id, count FROM command_usage").all();
  const map = new Map();
  for (const row of rows) {
    map.set(row.command_id, row.count);
  }
  return map;
}

function slugify(value) {
  const raw = (value || "").toString().toLowerCase();
  const slug = raw.replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
  return slug || "command";
}

function toTitleCase(value) {
  const raw = (value || "").toString().replace(/[-_]+/g, " ").trim();
  if (!raw) {
    return "";
  }
  return raw.replace(/\b\w/g, (match) => match.toUpperCase());
}

function truncateText(value, maxLength) {
  const raw = (value || "").toString();
  if (raw.length <= maxLength) {
    return raw;
  }
  return `${raw.slice(0, Math.max(0, maxLength - 3))}...`;
}

function setFlash(req, type, message) {
  req.session.flash = { type, message };
}

function uiContentWidth(requestPath = "/") {
  const route = String(requestPath || "/");
  if (/^\/admin\/(?:overlays\/[^/]+|navigation|resources)/.test(route)) return "workspace";
  if (/^\/admin\/(?:feedback|commands|command-policies|diagnostics|logs|plugins|privileges|theming|updates|users)/.test(route)) return "wide";
  if (/^\/plugins\/(?:lumi_ai|okf|economy-framework|economy-games|moderation)/.test(route)) return "wide";
  if (/^\/(?:auth\/localhost|setup|admin\/(?:settings|discord-wizard|twitch-wizard|youtube-wizard))/.test(route)) return "form";
  if (/^\/(?:pages\/|error|missing|plugins\/moderation\/status)/.test(route)) return "prose";
  return "standard";
}

function wantsEnhancedResponse(req) {
  return req.get("X-Lumi-Enhanced") === "1" || req.get("X-Requested-With") === "XMLHttpRequest";
}

function sendEnhancedResult(res, { message = "Saved.", fieldErrors = {}, data = {}, patch = {}, redirect = null, reloadRequired = false } = {}) {
  return res.json({ ok: true, message, fieldErrors, data, patch, redirect, reloadRequired });
}

function sendEnhancedError(req, res, { message, fieldErrors = {}, redirect } = {}) {
  if (wantsEnhancedResponse(req)) {
    return res.status(422).json({
      ok: false,
      message: message || "Correct the highlighted fields and try again.",
      fieldErrors,
      data: {},
      patch: {},
      redirect: null,
      reloadRequired: false
    });
  }
  setFlash(req, "error", message);
  return res.redirect(redirect);
}

function sendCommandMutationError(req, res, message, fieldErrors = {}) {
  return sendEnhancedError(req, res, {
    message,
    fieldErrors,
    redirect: "/admin/commands"
  });
}

function sendCommandMutationSuccess(req, res, { message, data = {} }) {
  if (wantsEnhancedResponse(req)) {
    return sendEnhancedResult(res, {
      message,
      data,
      patch: { refresh: "command-list" }
    });
  }
  setFlash(req, "success", message);
  return res.redirect("/admin/commands");
}

function screenshotExtension(mime) {
  if (mime === "image/jpeg") return ".jpg";
  if (mime === "image/webp") return ".webp";
  return ".png";
}

function feedbackAttachmentExtension(file = {}) {
  const original = path.extname(file.originalname || "").slice(0, 12).toLowerCase();
  if ([".png", ".jpg", ".jpeg", ".webp", ".pdf", ".txt"].includes(original)) return original;
  if (file.mimetype === "application/pdf") return ".pdf";
  if (file.mimetype === "text/plain") return ".txt";
  return screenshotExtension(file.mimetype);
}

function normalizeFeedbackRequestBody(body = {}) {
  return {
    ...body,
    target_metadata: parseBodyJson(body.target_metadata),
    diagnostics: parseBodyJson(body.diagnostics)
  };
}

function normalizeFeedbackExportRequest(body = {}) {
  const rawIds = Array.isArray(body.ids) ? body.ids.join(",") : body.ids;
  const ids = String(rawIds || "")
    .split(",")
    .map((id) => id.trim())
    .filter(Boolean)
    .slice(0, 100);
  const tokenLimit = Number.parseInt(body.token_limit || body.tokenLimit, 10);
  return {
    all: body.mode === "all" || body.all === "1" || body.all === true,
    ids,
    useAi: body.use_ai === "1" || body.use_ai === "true" || body.useAi === true,
    tokenLimit: Number.isFinite(tokenLimit) ? tokenLimit : undefined,
    filters: {
      status: body.status || "",
      category: body.category || "",
      severity: body.severity || "",
      scope: body.scope || "",
      area: body.area || "",
      route: body.route || "",
      plugin: body.plugin || "",
      target: body.target || "",
      submitter: body.submitter || "",
      date_from: body.date_from || "",
      date_to: body.date_to || "",
      needs_action: body.needs_action || "",
      sort: body.sort || "last_activity"
    }
  };
}

function buildFeedbackCorrectionPayload(feedback, body = {}) {
  if (!feedback) {
    throw new Error("Feedback item was not found.");
  }
  const title = cleanAiTaskfileText(body.correction_title || feedback.summary || "Feedback correction", 180);
  if (!title) {
    throw new Error("Correction title is required.");
  }
  const sourceUrl = `/admin/feedback?feedback=${encodeURIComponent(feedback.id)}`;
  const correctionBody = cleanCorrectionMarkdown(body.correction_body || [
    `# ${title}`,
    "",
    "## Correction",
    cleanAiTaskfileText(feedback.expected_behavior || feedback.description || feedback.summary, 1800),
    "",
    "## Source feedback",
    `Feedback ID: ${feedback.id}`,
    `Category: ${feedback.category_label || feedback.category || "Feedback"}`,
    `Severity: ${feedback.severity_label || feedback.severity || "Unknown"}`,
    feedback.scope_label_display ? `Scope: ${cleanAiTaskfileText(feedback.scope_label_display, 400)}` : "",
    feedback.current_url ? `Route: ${feedbackCorrectionRoute(feedback.current_url)}` : "",
    "",
    "## Reported behavior",
    cleanAiTaskfileText(feedback.description || feedback.summary, 2400),
    "",
    feedback.actual_behavior ? "## Actual behavior" : "",
    feedback.actual_behavior ? cleanAiTaskfileText(feedback.actual_behavior, 1200) : "",
    "",
    feedback.steps_to_reproduce ? "## Reproduction notes" : "",
    feedback.steps_to_reproduce ? cleanAiTaskfileText(feedback.steps_to_reproduce, 1200) : ""
  ].filter(Boolean).join("\n"), feedback);
  return {
    title,
    slug: body.correction_slug || `feedback-${feedback.id}`,
    id: body.correction_id || `correction.feedback.${feedback.id}`,
    category: body.correction_category || "Feedback correction",
    visibility: body.correction_visibility || "user",
    status: body.correction_status || "active",
    priority: body.correction_priority || 100,
    tags: body.correction_tags || `feedback, correction, ${feedback.category || "feedback"}`,
    source_feedback_id: feedback.id,
    source_feedback_url: sourceUrl,
    body: correctionBody
  };
}

function cleanCorrectionMarkdown(value, feedback = {}) {
  let cleaned = String(value || "")
    .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, "[email]")
    .replace(/\b\d{1,3}(?:\.\d{1,3}){3}\b/g, "[ip]")
    .replace(/\b([a-z0-9_-]*(?:token|secret|session|password|passwd|api[_-]?key|auth)[a-z0-9_-]*)\s*[:=]\s*[^,\s;]+/gi, "$1=[redacted]")
    .replace(/\b(?:bearer|basic)\s+[a-z0-9._~+/=-]+/gi, "[auth header]")
    .replace(/!\[[^\]]*\]\([^)]+\)/g, "[image omitted]")
    .replace(/(?:[A-Za-z]:\\|\\\\)[^\s<>\"|?*]+/g, "[local path]")
    .replace(/\/(?:home|Users|mnt|var|tmp|opt|root)\/[^\s)\]}>]+/g, "[local path]")
    .replace(/\bfeedback\/(?:screenshots|attachments)\/[a-z0-9_.-]+/gi, "[attachment omitted]")
    .replace(/^\s*(?:raw\s+)?diagnostics?(?:_json)?\s*[:=].*$/gim, "[diagnostics omitted]")
    .replace(/\r\n?/g, "\n")
    .replace(/\n{4,}/g, "\n\n\n")
    .trim();
  for (const identity of [feedback.submitter_id, feedback.submitter_name]) {
    const privateValue = String(identity || "").trim();
    if (privateValue.length < 3) continue;
    cleaned = cleaned.replace(new RegExp(escapeRegExp(privateValue), "gi"), "[submitter]");
  }
  return cleaned.slice(0, 12000);
}

function feedbackCorrectionRoute(value) {
  try {
    const parsed = new URL(String(value || ""), "http://lumi.local");
    return cleanAiTaskfileText(`${parsed.pathname}${parsed.hash}`, 500);
  } catch {
    return cleanAiTaskfileText(value, 500);
  }
}

function escapeRegExp(value) {
  return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}

async function maybeAddAiFeedbackExportSummary(exportPayload, req, useAi) {
  if (!useAi) return exportPayload;
  const ai = feedbackExportAi();
  if (!isFeedbackExportAiAvailable()) {
    return {
      ...exportPayload,
      debug_export: {
        ...exportPayload.debug_export,
        ai_summary: {
          available: false,
          reason: "Lumi AI is not available."
        }
      }
    };
  }
  const promptPayload = {
    taskfile: exportPayload.taskfile
  };
  const prompt =
    "Improve this compact Lumi feedback Codex taskfile. " +
    "Return strict JSON only. Allowed top-level keys: objective and tasks. " +
    "Each task may contain only task_id, title, context, requirements, acceptance_criteria, verification, and risk_notes. " +
    "Use provided sanitized context notes, including admin replies and private admin work notes, when they clarify the task. " +
    "Keep existing task_id values. Do not add private note authors, submitter identity, emails, IPs, tokens, session data, local paths, raw diagnostics, screenshots, or invented exact repo paths. " +
    "Keep output compact and directly actionable for a coding agent. " +
    `Input JSON:\n${JSON.stringify(promptPayload)}`;
  try {
    const result = await ai.generate({
      message: prompt,
      user: req.session.user,
      sessionId: `admin-feedback-export:${req.session.user?.id || "admin"}:${Date.now()}`,
      scope: "admin_feedback_export",
      max_tokens: exportPayload.debug_export?.token_context_limit || 8000,
      allowTools: false
    });
    const text = String(result?.text || "").trim();
    const parsed = parseAiJsonObject(text);
    const improvedTaskfile = parsed
      ? mergeAiFeedbackTaskfilePatch(exportPayload.taskfile, parsed)
      : exportPayload.taskfile;
    return {
      ...exportPayload,
      taskfile: improvedTaskfile,
      debug_export: {
        ...exportPayload.debug_export,
        ai_summary: {
          available: true,
          model_id: result?.model_id || null,
          token_limit: exportPayload.debug_export?.token_context_limit || 8000,
          content: parsed || text,
          applied_to_taskfile: Boolean(parsed)
        }
      }
    };
  } catch (error) {
    return {
      ...exportPayload,
      debug_export: {
        ...exportPayload.debug_export,
        ai_summary: {
          available: false,
          reason: error.message || "AI summarization failed."
        }
      }
    };
  }
}

function mergeAiFeedbackTaskfilePatch(taskfile, patch) {
  if (!patch || typeof patch !== "object" || Array.isArray(patch)) return taskfile;
  const next = { ...taskfile };
  if (typeof patch.objective === "string" && patch.objective.trim().length >= 12) {
    next.objective = cleanAiTaskfileText(patch.objective, 260);
  }
  if (Array.isArray(patch.tasks) && Array.isArray(next.tasks)) {
    const patches = new Map(patch.tasks
      .filter((task) => task && typeof task === "object" && !Array.isArray(task))
      .map((task) => [cleanAiTaskfileText(task.task_id, 100), task])
      .filter(([taskId]) => taskId));
    next.tasks = next.tasks.map((task) => {
      const taskPatch = patches.get(task.task_id);
      if (!taskPatch) return task;
      const improved = { ...task };
      if (typeof taskPatch.title === "string" && taskPatch.title.trim()) {
        improved.title = cleanAiTaskfileText(taskPatch.title, 180);
      }
      for (const [key, maxLength, maxItems] of [
        ["context", 500, 10],
        ["requirements", 700, 14],
        ["acceptance_criteria", 600, 10],
        ["verification", 600, 10],
        ["risk_notes", 400, 6]
      ]) {
        const values = normalizeAiStringArray(taskPatch[key], maxLength).slice(0, maxItems);
        if (values.length) improved[key] = values;
      }
      return improved;
    });
  }
  return next;
}

function normalizeAiTaskfileArray(value, maxLength, textKey) {
  if (!Array.isArray(value)) return [];
  return value
    .map((item) => {
      if (typeof item === "string") return cleanAiTaskfileText(item, maxLength);
      if (!item || typeof item !== "object" || Array.isArray(item)) return null;
      const text = cleanAiTaskfileText(item[textKey] || item.text || item.value || "", maxLength);
      if (!text) return null;
      const out = { [textKey]: text };
      const feedbackId = cleanAiTaskfileText(item.feedback_id || item.feedbackId || "", 80);
      if (feedbackId) out.feedback_id = feedbackId;
      return out;
    })
    .filter(Boolean)
    .slice(0, 30);
}

function normalizeAiStringArray(value, maxLength) {
  if (!Array.isArray(value)) return [];
  return value
    .map((item) => cleanAiTaskfileText(item, maxLength))
    .filter(Boolean)
    .slice(0, 12);
}

function cleanAiTaskfileText(value, maxLength) {
  return String(value || "")
    .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, "[email]")
    .replace(/\b\d{1,3}(?:\.\d{1,3}){3}\b/g, "[ip]")
    .replace(/\b([a-z0-9_-]*(?:token|secret|session|password|passwd|api[_-]?key|auth)[a-z0-9_-]*)\s*[:=]\s*[^,\s;]+/gi, "$1=[redacted]")
    .replace(/\b(?:bearer|basic)\s+[a-z0-9._~+/=-]+/gi, "[auth header]")
    .replace(/\s+/g, " ")
    .trim()
    .slice(0, maxLength);
}

function feedbackExportAi() {
  return global.lumiFrameworks?.ai || global.lumiFrameworks?.lumi_ai || null;
}

function isFeedbackExportAiAvailable() {
  const ai = feedbackExportAi();
  if (!ai || typeof ai.generate !== "function") return false;
  try {
    const capabilities = typeof ai.capabilities === "function" ? ai.capabilities() : null;
    if (capabilities && capabilities.enabled === false) return false;
  } catch {
    return false;
  }
  return true;
}

function parseAiJsonObject(text) {
  if (!text) return null;
  const cleaned = text
    .replace(/^```(?:json)?\s*/i, "")
    .replace(/\s*```$/i, "")
    .trim();
  try {
    const parsed = JSON.parse(cleaned);
    return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
  } catch {
    return null;
  }
}

function parseBodyJson(value) {
  if (value && typeof value === "object") return value;
  try {
    const parsed = JSON.parse(String(value || "{}"));
    return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
  } catch {
    return {};
  }
}

function resolveFeedbackScreenshotPath(relativePath, screenshotDir) {
  const normalized = String(relativePath || "").replace(/\\/g, "/");
  const prefix = "feedback/screenshots/";
  if (!normalized.startsWith(prefix)) return null;
  const fileName = path.basename(normalized.slice(prefix.length));
  if (!fileName || fileName !== normalized.slice(prefix.length)) return null;
  const target = path.resolve(screenshotDir, fileName);
  const root = path.resolve(screenshotDir);
  return target.startsWith(`${root}${path.sep}`) ? target : null;
}

function resolveFeedbackAttachmentPath(relativePath, attachmentDir) {
  const normalized = String(relativePath || "").replace(/\\/g, "/");
  const prefix = "feedback/attachments/";
  if (!normalized.startsWith(prefix)) return null;
  const fileName = path.basename(normalized.slice(prefix.length));
  if (!fileName || fileName !== normalized.slice(prefix.length)) return null;
  const target = path.resolve(attachmentDir, fileName);
  const root = path.resolve(attachmentDir);
  return target.startsWith(`${root}${path.sep}`) ? target : null;
}

function getThemeSettings() {
  return getActiveTheme();
}

function parseJsonSetting(key, fallback) {
  const value = getSetting(key, fallback);
  if (Array.isArray(value)) return value;
  if (typeof value === "string" && value.trim()) {
    try {
      const parsed = JSON.parse(value);
      return Array.isArray(parsed) ? parsed : fallback;
    } catch {
      return fallback;
    }
  }
  return fallback;
}

const DISCORD_WIDGET_CACHE_MS = 5 * 60 * 1000;
const discordWidgetCache = new Map();

function safeExternalUrl(value) {
  try {
    const url = new URL(String(value || ""));
    return ["http:", "https:"].includes(url.protocol) ? url.toString() : "";
  } catch {
    return "";
  }
}

function safeHomepageLinkUrl(value) {
  const raw = String(value || "").trim();
  if (raw.startsWith("/") && !raw.startsWith("//")) {
    return raw;
  }
  return safeExternalUrl(raw);
}

function isLocalHostname(hostname) {
  return ["localhost", "127.0.0.1", "::1"].includes(String(hostname || "").toLowerCase());
}

function isDevRequest(req = null) {
  return process.env.NODE_ENV !== "production" || isLocalHostname(homepageEmbedParent(req));
}

function safeEmbedUrl(value, options = {}) {
  try {
    const url = new URL(String(value || "").trim());
    if (url.protocol === "https:") return url.toString();
    if (url.protocol === "http:" && options.allowInsecure) return url.toString();
    return "";
  } catch {
    return "";
  }
}

function parseDomainList(value) {
  return String(value || "")
    .split(",")
    .map((item) => item.trim().toLowerCase().replace(/^\*\./, ""))
    .filter(Boolean);
}

function embedDomainAllowed(embedUrl, item) {
  const domains = parseDomainList(item.allowed_domains);
  if (!domains.length) return true;
  try {
    const host = new URL(embedUrl).hostname.toLowerCase();
    return domains.some((domain) => host === domain || host.endsWith(`.${domain}`));
  } catch {
    return false;
  }
}

function isDiscordUrl(value) {
  try {
    const host = new URL(value).hostname.toLowerCase().replace(/^www\./, "");
    return host === "discord.gg" || host === "discord.com" || host.endsWith(".discord.com");
  } catch {
    return false;
  }
}

function permissionAllows(user, permission = "public") {
  const role = ["public", "user", "mod", "admin"].includes(permission) ? permission : "public";
  return role === "public" ? true : hasAccess(user, role);
}

function fallbackIconForUrl(url) {
  try {
    if (String(url || "").startsWith("/")) return "L";
    const host = new URL(url).hostname.replace(/^www\./, "");
    return host.slice(0, 1).toUpperCase();
  } catch {
    return "↗";
  }
}

function homepageLinksForUser(user) {
  return parseJsonSetting("homepage_link_buttons", [])
    .filter((item) => item && item.enabled !== false)
    .filter((item) => permissionAllows(user, item.permission))
    .map((item, index) => {
      const url = safeHomepageLinkUrl(item.url);
      if (!url) return null;
      const iconMode = String(item.icon_mode || "").trim();
      const iconUrl =
        iconMode === "manual" ? safeExternalUrl(item.icon_url) :
        iconMode === "favicon" ? safeExternalUrl(item.fetched_favicon_url) :
        iconMode === "letter" ? "" :
        safeExternalUrl(item.icon_url || item.fetched_favicon_url);
      return {
        id: String(item.id || `link-${index}`),
        label: String(item.label || item.description || "External link").slice(0, 80),
        description: String(item.description || item.label || "Open link").slice(0, 160),
        url,
        icon_url: iconUrl,
        fallback_icon: fallbackIconForUrl(url),
        permission: item.permission || "public",
        sort_order: Number(item.sort_order) || index
      };
    })
    .filter(Boolean)
    .sort((a, b) => a.sort_order - b.sort_order);
}

async function homepageHeroForUser(user, req = null) {
  const entries = parseJsonSetting("homepage_hero_entries", [])
    .filter((item) => item && item.enabled !== false)
    .filter((item) => permissionAllows(user, item.permission))
    .sort((a, b) => (Number(a.priority) || 0) - (Number(b.priority) || 0));
  for (const item of entries) {
    const runtimeItem = homepageHeroRuntimeItem(item);
    let hero = normalizeHomepageHero(runtimeItem, {
      parentHost: homepageEmbedParent(req),
      allowInsecureEmbeds: isDevRequest(req)
    });
    if (hero?.available && hero.type === "discord_server_overview") {
      hero = await enrichDiscordHero(hero, item);
    }
    if (hero?.available) return hero;
    if (hero?.render_error && hasAccess(user, "admin")) return hero;
  }
  return null;
}

function homepageHeroRuntimeItem(item) {
  if (item?.type !== "youtube_channel") return item;
  const client = getYouTubeClient();
  const configuredChannel = String(item.video_id || youtubeChannelId(item.source_url) || "").trim();
  if (!client?.channelId || configuredChannel !== String(client.channelId)) return item;
  if (!client.liveStateUpdatedAt) return item;
  return {
    ...item,
    live_now: Boolean(client.activeVideoId),
    resolved_video_id: client.activeVideoId || ""
  };
}

function normalizeHomepageHero(item, options = {}) {
  const type = String(item.type || "none");
  if (type === "none") {
    return item.fallback_behavior === "message"
      ? { type, available: true, title: item.title || "No featured content", description: item.description || "" }
      : null;
  }
  const sourceUrl = safeExternalUrl(item.source_url);
  const derivedEmbedUrl = deriveHomepageEmbedUrl(type, item, options);
  const embedUrl = ["youtube_video", "youtube_channel", "twitch_stream"].includes(type)
    ? derivedEmbedUrl
    : safeEmbedUrl(item.embed_url, { allowInsecure: options.allowInsecureEmbeds }) || derivedEmbedUrl;
  const imageUrl = safeExternalUrl(item.image_url);
  const fallback = homepageHeroFallback(item);
  const title = String(item.title || "Featured content").slice(0, 120);
  const description = String(item.description || "").slice(0, 500);
  if (type === "static_image" && imageUrl) return { type, available: true, title, description, image_url: imageUrl, source_url: sourceUrl };
  if (type === "custom_link" && sourceUrl) return { type, available: true, title, description, source_url: sourceUrl };
  if (type === "custom_embed" && embedUrl && !isDiscordUrl(embedUrl) && embedDomainAllowed(embedUrl, item)) {
    return {
      type,
      available: true,
      title,
      description,
      embed_url: embedUrl,
      source_url: sourceUrl,
      iframe_sandbox: "allow-scripts allow-same-origin allow-presentation allow-popups",
      iframe_allow: customEmbedAllow(item),
      aspect_ratio: safeAspectRatio(item.aspect_ratio),
      embed_height: safeEmbedHeight(item.embed_height),
      ...fallback
    };
  }
  if (type === "youtube_video") {
    if (item.availability_mode === "live_only" && item.live_now !== true) return null;
    const videoId = item.video_id || youtubeVideoId(item.source_url) || youtubeVideoId(sourceUrl);
    if (videoId) return {
      type,
      available: true,
      title,
      description,
      embed_url: youtubeVideoEmbedUrl(videoId, item, sourceUrl),
      secondary_embed_url: item.youtube_show_chat === true ? youtubeChatEmbedUrl(videoId, options.parentHost) : "",
      source_url: sourceUrl,
      iframe_allow: "autoplay; encrypted-media; picture-in-picture; web-share"
    };
  }
  if (type === "discord_server_overview") {
    const guildId = item.video_id || discordServerId(item.source_url) || discordServerId(sourceUrl);
    if (guildId) return { type, available: true, title, description, source_url: sourceUrl, discord_guild_id: guildId, ...fallback };
  }
  if (["youtube_channel", "twitch_stream"].includes(type) && (embedUrl || sourceUrl)) {
    if (item.availability_mode === "live_only" && item.live_now !== true) return null;
    const liveVideoId = type === "youtube_channel" ? String(item.resolved_video_id || "") : "";
    const primaryUrl = liveVideoId ? youtubeVideoEmbedUrl(liveVideoId, item, sourceUrl) : embedUrl;
    const secondaryUrl =
      type === "twitch_stream" && item.twitch_layout === "stream_with_chat"
        ? twitchChatEmbedUrl(item.video_id || twitchChannelName(sourceUrl), options.parentHost, item.additional_parent_domains)
        : type === "youtube_channel" && item.youtube_show_chat === true && liveVideoId
          ? youtubeChatEmbedUrl(liveVideoId, options.parentHost)
          : "";
    return {
      type,
      available: Boolean(primaryUrl),
      title,
      description,
      embed_url: primaryUrl,
      secondary_embed_url: secondaryUrl,
      embed_height: type === "twitch_stream" ? Math.max(400, safeEmbedHeight(item.embed_height)) : safeEmbedHeight(item.embed_height),
      source_url: sourceUrl,
      render_error: primaryUrl ? "" : heroRenderError(type)
    };
  }
  return {
    type,
    available: false,
    title,
    description,
    source_url: sourceUrl,
    ...fallback,
    render_error: heroRenderError(type)
  };
}

function youtubeVideoId(value) {
  const raw = String(value || "").trim();
  if (/^[A-Za-z0-9_-]{11}$/.test(raw)) return raw;
  try {
    const url = new URL(raw);
    if (url.hostname.includes("youtu.be")) return url.pathname.split("/").filter(Boolean)[0] || "";
    const pathMatch = url.pathname.match(/\/(?:embed|shorts|live)\/([^/?#]+)/);
    return pathMatch?.[1] || url.searchParams.get("v") || "";
  } catch {
    return "";
  }
}

function youtubeStartSeconds(value, fallbackSource = "") {
  const explicit = Number(value);
  if (Number.isFinite(explicit) && explicit > 0) return Math.floor(explicit);
  try {
    const url = new URL(fallbackSource || "");
    const raw = url.searchParams.get("start") || url.searchParams.get("t") || "";
    if (/^\d+$/.test(raw)) return Number(raw);
    const match = raw.match(/^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s?)?$/i);
    if (!match) return 0;
    return ((Number(match[1]) || 0) * 3600) + ((Number(match[2]) || 0) * 60) + (Number(match[3]) || 0);
  } catch {
    return 0;
  }
}

function youtubeVideoEmbedUrl(videoId, item = {}, sourceUrl = "") {
  const url = new URL(`https://www.youtube-nocookie.com/embed/${encodeURIComponent(videoId)}`);
  const autoplay = item.autoplay_mode && item.autoplay_mode !== "off";
  if (autoplay) {
    url.searchParams.set("autoplay", "1");
    if (item.autoplay_mode !== "sound") url.searchParams.set("mute", "1");
  }
  if (item.show_controls === false) url.searchParams.set("controls", "0");
  if (item.loop === true) {
    url.searchParams.set("loop", "1");
    url.searchParams.set("playlist", videoId);
  }
  const start = youtubeStartSeconds(item.start_seconds, sourceUrl || item.source_url);
  if (start > 0) url.searchParams.set("start", String(start));
  return url.toString();
}

function youtubeChannelId(value) {
  try {
    const url = new URL(value || "");
    const match = url.pathname.match(/\/(?:channel|c|user)\/([^/?#]+)/);
    return match?.[1] || "";
  } catch {
    return "";
  }
}

function twitchChannelName(value) {
  try {
    const url = new URL(value || "");
    const host = url.hostname.replace(/^www\./, "");
    if (!host.endsWith("twitch.tv")) return "";
    const first = url.pathname.split("/").filter(Boolean)[0] || "";
    return ["videos", "directory", "p"].includes(first) ? "" : first;
  } catch {
    return "";
  }
}

function discordServerId(value) {
  const raw = String(value || "").trim();
  if (/^\d{10,30}$/.test(raw)) return raw;
  try {
    const url = new URL(raw);
    return url.searchParams.get("id") || "";
  } catch {
    return "";
  }
}

function deriveHomepageEmbedUrl(type, item, options = {}) {
  const sourceUrl = safeExternalUrl(item.source_url);
  const parentHost = options.parentHost || "localhost";
  const allowInsecure = Boolean(options.allowInsecureEmbeds);
  if (type === "custom_embed") {
    const manual = safeEmbedUrl(item.embed_url, { allowInsecure });
    if (manual && !isDiscordUrl(manual)) return manual;
    const direct = safeEmbedUrl(item.source_url, { allowInsecure });
    if (!direct || isDiscordUrl(direct)) return "";
    const youtube = youtubeVideoId(sourceUrl);
    if (youtube) return `https://www.youtube-nocookie.com/embed/${youtube}`;
    const twitch = twitchChannelName(sourceUrl);
    if (twitch) return twitchEmbedUrl(twitch, parentHost);
    return direct;
  }
  if (type === "youtube_video") {
    const video = item.video_id || youtubeVideoId(item.source_url) || youtubeVideoId(sourceUrl);
    return video ? youtubeVideoEmbedUrl(video, item, sourceUrl) : "";
  }
  if (type === "youtube_channel") {
    const channel = item.video_id || youtubeChannelId(sourceUrl);
    return channel ? `https://www.youtube.com/embed/live_stream?channel=${encodeURIComponent(channel)}` : "";
  }
  if (type === "twitch_stream") {
    const channel = item.video_id || twitchChannelName(sourceUrl);
    return channel ? twitchEmbedUrl(channel, parentHost, item.additional_parent_domains) : "";
  }
  return "";
}

function homepageHeroFallback(item) {
  return {
    fallback_image_url: safeExternalUrl(item.fallback_image_url),
    fallback_url: safeExternalUrl(item.fallback_url) || safeExternalUrl(item.source_url),
    fallback_text: String(item.fallback_text || "").slice(0, 500),
    fallback_behavior: ["hide", "message", "link"].includes(item.fallback_behavior) ? item.fallback_behavior : "message"
  };
}

function safeAspectRatio(value) {
  const raw = String(value || "").trim();
  return /^\d+(\.\d+)?\s*\/\s*\d+(\.\d+)?$/.test(raw) ? raw.replace(/\s+/g, "") : "";
}

function safeEmbedHeight(value) {
  const number = Number(value);
  if (!Number.isFinite(number) || number <= 0) return 0;
  return Math.min(1200, Math.max(180, Math.floor(number)));
}

function customEmbedAllow(item) {
  const base = new Set(["fullscreen", "autoplay"]);
  String(item.iframe_allow || "")
    .split(";")
    .map((part) => part.trim().toLowerCase())
    .filter(Boolean)
    .forEach((part) => {
      if (["fullscreen", "autoplay", "encrypted-media", "picture-in-picture"].includes(part)) {
        base.add(part);
      }
      if (item.allow_unsafe_permissions === true && ["camera", "microphone", "clipboard-write"].includes(part)) {
        base.add(part);
      }
    });
  return Array.from(base).join("; ");
}

async function enrichDiscordHero(hero, item) {
  try {
    const widget = await fetchDiscordWidget(hero.discord_guild_id);
    return {
      ...hero,
      discord_widget: {
        name: String(widget.name || hero.title || "Discord server").slice(0, 120),
        invite_url: safeExternalUrl(widget.instant_invite) || hero.fallback_url,
        presence_count: Number(widget.presence_count) || 0,
        channels: Array.isArray(widget.channels)
          ? widget.channels.slice(0, 8).map((channel) => String(channel.name || "").slice(0, 80)).filter(Boolean)
          : [],
        members: Array.isArray(widget.members)
          ? widget.members.slice(0, 8).map((member) => ({
              username: String(member.username || "").slice(0, 80),
              status: String(member.status || "").slice(0, 30),
              avatar_url: safeExternalUrl(member.avatar_url)
            })).filter((member) => member.username)
          : []
      }
    };
  } catch (error) {
    if (hero.fallback_behavior === "hide") return { ...hero, available: false };
    return {
      ...hero,
      available: Boolean(hero.fallback_url || hero.fallback_text || hero.fallback_image_url),
      render_error: error?.message || "Discord Server Widget is unavailable. Enable the server widget in Discord or add a fallback link."
    };
  }
}

async function fetchDiscordWidget(guildId) {
  const id = String(guildId || "").trim();
  if (!/^\d{10,30}$/.test(id)) {
    throw new Error("Add a valid Discord server ID.");
  }
  const now = Date.now();
  const cached = discordWidgetCache.get(id);
  if (cached && cached.expires > now) {
    if (cached.error) throw new Error(cached.error);
    return cached.data;
  }
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), 5000);
  try {
    const response = await fetch(`https://discord.com/api/guilds/${encodeURIComponent(id)}/widget.json`, {
      headers: { Accept: "application/json" },
      signal: controller.signal
    });
    if (!response.ok) {
      const message = response.status === 403 || response.status === 404
        ? "Discord Server Widget is disabled or unavailable for this server."
        : `Discord widget request failed with HTTP ${response.status}.`;
      discordWidgetCache.set(id, { expires: now + DISCORD_WIDGET_CACHE_MS, error: message });
      throw new Error(message);
    }
    const data = await response.json();
    discordWidgetCache.set(id, { expires: now + DISCORD_WIDGET_CACHE_MS, data });
    return data;
  } catch (error) {
    const message = error?.name === "AbortError"
      ? "Discord widget request timed out."
      : error?.message || "Discord widget could not be loaded.";
    discordWidgetCache.set(id, { expires: now + Math.min(DISCORD_WIDGET_CACHE_MS, 60 * 1000), error: message });
    throw new Error(message);
  } finally {
    clearTimeout(timer);
  }
}

function homepageEmbedParent(req) {
  const host = String(req?.hostname || req?.get?.("host") || "localhost")
    .split(":")[0]
    .trim();
  return host || "localhost";
}

function twitchParentDomains(parentHost, additionalDomains = "") {
  const validHostname = /^(?:[a-z0-9](?:[a-z0-9-]{0,62})\.)*[a-z0-9](?:[a-z0-9-]{0,62})$/i;
  return Array.from(new Set([parentHost, ...parseDomainList(additionalDomains)]
    .map((domain) => String(domain || "").trim().toLowerCase())
    .filter((domain) => validHostname.test(domain))));
}

function twitchParentQuery(parentHost, additionalDomains = "") {
  const params = new URLSearchParams();
  twitchParentDomains(parentHost, additionalDomains).forEach((domain) => params.append("parent", domain));
  return params;
}

function twitchEmbedUrl(channel, parentHost, additionalDomains = "") {
  const params = twitchParentQuery(parentHost, additionalDomains);
  params.set("channel", channel);
  params.set("muted", "true");
  return `https://player.twitch.tv/?${params.toString()}`;
}

function twitchChatEmbedUrl(channel, parentHost, additionalDomains = "") {
  if (!channel) return "";
  return `https://www.twitch.tv/embed/${encodeURIComponent(channel)}/chat?${twitchParentQuery(parentHost, additionalDomains).toString()}`;
}

function youtubeChatEmbedUrl(videoId, parentHost) {
  if (!videoId || !parentHost) return "";
  const params = new URLSearchParams({ v: videoId, embed_domain: parentHost });
  return `https://www.youtube.com/live_chat?${params.toString()}`;
}

function heroRenderError(type) {
  const labels = {
    static_image: "Add an image URL before this image hero can be displayed.",
    custom_link: "Add a public link before this link hero can be displayed.",
    custom_embed: "Add a supported YouTube, Twitch, Discord, or direct embed URL before this hero can be displayed.",
    youtube_video: "Add a YouTube video URL or video ID before this hero can be displayed.",
    youtube_channel: "Add a YouTube channel URL or channel ID before this hero can be displayed.",
    twitch_stream: "Add a Twitch channel URL or channel name before this hero can be displayed.",
    discord_server_overview: "Add a Discord server widget URL or server ID before this hero can be displayed."
  };
  return labels[type] || "This hero is missing the required URL or ID.";
}

function validateHomepageHeroEntries(entries) {
  const errors = [];
  entries.forEach((item, index) => {
    if (!item || item.enabled === false) return;
    if (item.type === "custom_embed" && !String(item.title || "").trim()) {
      errors.push(`hero ${index + 1}: Add a title for this external embed.`);
      return;
    }
    const hero = normalizeHomepageHero({ ...item, availability_mode: "always" }, { parentHost: "localhost" });
    if (hero?.available) return;
    if (item.type === "none" && item.fallback_behavior !== "hide") return;
    const label = item.title || `hero ${index + 1}`;
    errors.push(`${label}: ${hero?.render_error || heroRenderError(item.type || "none")}`);
  });
  return errors;
}

function getDiscordSettings() {
  return {
    discord_client_id: getSetting("discord_client_id", ""),
    discord_client_secret: getSetting("discord_client_secret", ""),
    discord_redirect_uri: getSetting("discord_redirect_uri", ""),
    discord_bot_token: getSetting("discord_bot_token", ""),
    discord_guild_id: getSetting("discord_guild_id", ""),
    discord_admin_role_id: getSetting("discord_admin_role_id", ""),
    discord_mod_role_id: getSetting("discord_mod_role_id", "")
  };
}

function getTwitchSettings() {
  return {
    twitch_client_id: getSetting("twitch_client_id", ""),
    twitch_client_secret: getSetting("twitch_client_secret", ""),
    twitch_redirect_uri: getSetting("twitch_redirect_uri", ""),
    twitch_bot_username: getSetting("twitch_bot_username", ""),
    twitch_bot_oauth: getSetting("twitch_bot_oauth", ""),
    twitch_channels: getSetting("twitch_channels", "")
  };
}

function getYouTubeSettings() {
  return {
    youtube_client_id: getSetting("youtube_client_id", ""),
    youtube_client_secret: getSetting("youtube_client_secret", ""),
    youtube_redirect_uri: getSetting("youtube_redirect_uri", ""),
    youtube_bot_channel_id: getSetting("youtube_bot_channel_id", "")
  };
}

function saveSettingsMap(settings) {
  for (const [key, value] of Object.entries(settings)) {
    setSetting(key, value ?? "");
  }
}

function storeSnapshot(req, key, settings) {
  req.session[key] = settings;
}

function restoreSnapshot(req, key) {
  const snapshot = req.session[key];
  if (!snapshot) {
    return;
  }
  saveSettingsMap(snapshot);
  delete req.session[key];
}

function mergeSecrets(existing, incoming, secretKeys) {
  const merged = { ...existing };
  for (const [key, value] of Object.entries(incoming)) {
    const trimmed = typeof value === "string" ? value.trim() : value;
    if (secretKeys.has(key) && !trimmed) {
      continue;
    }
    merged[key] = trimmed;
  }
  return merged;
}

async function verifyDiscordSettings(settings) {
  const errors = [];
  const checks = [];
  const required = [
    "discord_client_id",
    "discord_client_secret",
    "discord_bot_token",
    "discord_guild_id"
  ];
  const missing = required.filter((field) => !settings[field]);
  if (missing.length) {
    errors.push("Client ID, Client Secret, Bot Token, and Guild ID are required.");
    return { ok: false, errors, checks };
  }

  try {
    const botResponse = await fetch("https://discord.com/api/users/@me", {
      headers: { Authorization: `Bot ${settings.discord_bot_token}` }
    });
    if (!botResponse.ok) {
      errors.push("Bot token is invalid or missing permissions.");
    } else {
      const botUser = await botResponse.json();
      checks.push(`Bot token verified (${botUser.username}).`);
    }
  } catch {
    errors.push("Unable to reach Discord to verify bot token.");
  }

  try {
    const guildResponse = await fetch(
      `https://discord.com/api/guilds/${settings.discord_guild_id}`,
      { headers: { Authorization: `Bot ${settings.discord_bot_token}` } }
    );
    if (!guildResponse.ok) {
      errors.push("Guild ID is invalid or the bot is not in the guild.");
    } else {
      const guild = await guildResponse.json();
      checks.push(`Guild verified (${guild.name}).`);
    }
  } catch {
    errors.push("Unable to verify the Discord guild.");
  }

  try {
    const body = new URLSearchParams({
      client_id: settings.discord_client_id,
      client_secret: settings.discord_client_secret,
      grant_type: "client_credentials",
      scope: "identify"
    });
    const tokenResponse = await fetch("https://discord.com/api/oauth2/token", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body
    });
    if (!tokenResponse.ok) {
      errors.push("Client ID/Secret failed verification.");
    } else {
      checks.push("Client ID and secret verified.");
    }
  } catch {
    errors.push("Unable to verify Discord client credentials.");
  }

  return { ok: errors.length === 0, errors, checks };
}

async function verifyTwitchSettings(settings) {
  const errors = [];
  const checks = [];

  if (!settings.twitch_client_id || !settings.twitch_client_secret) {
    errors.push("Twitch Client ID and Client Secret are required.");
    return { ok: false, errors, checks };
  }

  let appToken = null;
  try {
    const tokenUrl =
      "https://id.twitch.tv/oauth2/token" +
      `?client_id=${encodeURIComponent(settings.twitch_client_id)}` +
      `&client_secret=${encodeURIComponent(settings.twitch_client_secret)}` +
      "&grant_type=client_credentials";
    const tokenResponse = await fetch(tokenUrl, { method: "POST" });
    if (!tokenResponse.ok) {
      errors.push("Client ID/Secret failed verification.");
    } else {
      const data = await tokenResponse.json();
      appToken = data.access_token;
      checks.push("Client ID and secret verified.");
    }
  } catch {
    errors.push("Unable to verify Twitch client credentials.");
  }

  if (settings.twitch_bot_username || settings.twitch_bot_oauth) {
    if (!settings.twitch_bot_username || !settings.twitch_bot_oauth) {
      errors.push("Bot username and OAuth token must both be filled in.");
    } else {
      const rawToken = settings.twitch_bot_oauth.startsWith("oauth:")
        ? settings.twitch_bot_oauth.slice(6)
        : settings.twitch_bot_oauth;
      try {
        const validateResponse = await fetch(
          "https://id.twitch.tv/oauth2/validate",
          { headers: { Authorization: `OAuth ${rawToken}` } }
        );
        if (!validateResponse.ok) {
          errors.push("Bot OAuth token failed validation.");
        } else {
          const data = await validateResponse.json();
          checks.push(`Bot token verified (${data.login}).`);
          if (
            settings.twitch_bot_username &&
            data.login &&
            data.login.toLowerCase() !== settings.twitch_bot_username.toLowerCase()
          ) {
            errors.push("Bot username does not match the OAuth token.");
          }
        }
      } catch {
        errors.push("Unable to verify Twitch bot OAuth token.");
      }
    }
  }

  if (appToken && settings.twitch_bot_username) {
    try {
      const userResponse = await fetch(
        `https://api.twitch.tv/helix/users?login=${encodeURIComponent(
          settings.twitch_bot_username
        )}`,
        {
          headers: {
            "Client-Id": settings.twitch_client_id,
            Authorization: `Bearer ${appToken}`
          }
        }
      );
      if (userResponse.ok) {
        const data = await userResponse.json();
        if (data.data && data.data.length) {
          checks.push(`Bot account found (${data.data[0].display_name}).`);
        } else {
          errors.push("Bot username was not found on Twitch.");
        }
      }
    } catch {
      errors.push("Unable to verify bot username with Twitch.");
    }
  }

  return { ok: errors.length === 0, errors, checks };
}

async function verifyYouTubeSettings(settings) {
  const errors = [];
  const checks = [];

  if (!settings.youtube_client_id || !settings.youtube_client_secret) {
    errors.push("YouTube Client ID and Client Secret are required.");
    return { ok: false, errors, checks };
  }

  const refreshToken =
    settings.youtube_bot_refresh_token || getSetting("youtube_bot_refresh_token", "");
  if (!refreshToken) {
    checks.push("Bot account not connected yet.");
    return { ok: errors.length === 0, errors, checks };
  }

  try {
    const body = new URLSearchParams({
      client_id: settings.youtube_client_id,
      client_secret: settings.youtube_client_secret,
      refresh_token: refreshToken,
      grant_type: "refresh_token"
    });
    const response = await fetch("https://oauth2.googleapis.com/token", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body
    });
    if (!response.ok) {
      errors.push("Bot refresh token failed verification.");
      return { ok: false, errors, checks };
    }
    const token = await response.json();
    checks.push("Bot refresh token verified.");
    const channel = await fetchYouTubeChannel(token.access_token);
    if (channel?.snippet?.title) {
      checks.push(`Bot channel verified (${channel.snippet.title}).`);
    } else {
      checks.push("Bot channel verified.");
    }
    return { ok: errors.length === 0, errors, checks, channel };
  } catch {
    errors.push("Unable to verify YouTube bot credentials.");
    return { ok: false, errors, checks };
  }
}

function createWebServer({ loadPlugins, discordClient, commandRouter }) {
  const app = express();
  const upgradeRegistry = createWebUpgradeRegistry();
  app.locals.lumiUpgradeRegistry = upgradeRegistry;
  // Only trust forwarding headers from a reverse proxy on this machine. This
  // lets the diagnostics endpoint recognize HTTPS without trusting arbitrary
  // client-supplied X-Forwarded-Proto headers.
  app.set("trust proxy", "loopback");
  const webhooks = createWebhookService();
  placeholders.registerCorePlaceholders();
  placeholders.registerPlatformPlaceholders({
    discordClient,
    getTwitchClient,
    getYouTubeClient
  });
  if (!global.lumiFrameworks) {
    global.lumiFrameworks = {};
  }
  global.lumiFrameworks.webhooks = webhooks;
  global.lumiFrameworks.placeholders = placeholders;
  global.lumiFrameworks.events = eventHooksApi();
  global.lumiFrameworks.overlays = Object.freeze({
    registerAccessProvider: registerOverlayAccessProvider,
    registerConnectorProvider: registerOverlayConnectorProvider,
    registerModuleType: registerOverlayModuleType
  });
  const contentLibraryFramework = createContentLibraryFramework();
  global.lumiFrameworks.content = contentLibraryFramework;
  global.lumiFrameworks.resources = contentLibraryFramework;
  const assetVersion = Date.now().toString();
  const sessionStore = new BetterSqlite3Store({
    client: db
  });

  app.set("view engine", "ejs");
  app.set("views", path.join(__dirname, "views"));
  app.use("/webhooks", webhooks.router);

  const originalAppRender = app.render.bind(app);
  app.render = (view, options, callback) => {
    if (typeof options === "function") {
      callback = options;
      options = {};
    }
    const safeOptions = options || {};
    const respond = (err, html) => {
      if (!err) {
        if (typeof callback === "function") {
          return callback(null, html);
        }
        return html;
      }
      const message = err?.message || "";
      const detail = {
        view,
        message,
        stack: err?.stack || ""
      };
      const isMissing = message.includes("Failed to lookup view");
      if (!isMissing) {
        log("error", "View render failed", detail);
        if (typeof callback === "function") {
          return callback(err);
        }
        throw err;
      }
      log("warn", "Missing view fallback", detail);
      if (view === "missing-view") {
        const fallback =
          "<!doctype html><title>Content missing</title><h1>Content unavailable</h1><p>Some content could not be loaded.</p>";
        if (typeof callback === "function") {
          return callback(null, fallback);
        }
        return fallback;
      }
      return originalAppRender(
        "missing-view",
        {
          ...safeOptions,
          title: "Content missing",
          resource: "A page component failed to load. Please try again.",
          softError: "Some content could not be loaded."
        },
        callback
      );
    };
    return originalAppRender(view, safeOptions, respond);
  };

  app.use(
    session({
      secret: ensureSessionSecret(),
      resave: false,
      saveUninitialized: false,
      store: sessionStore
    })
  );
  app.use(express.urlencoded({ extended: false, limit: "1mb", parameterLimit: 20000 }));
  app.use(express.json({ limit: "1mb" }));
  app.use((req, res, next) => {
    const requestId = crypto.randomUUID();
    const startedAt = Date.now();
    const method = String(req.method || "GET").toUpperCase();
    const requestPath = String(req.path || "/");
    const pluginMatch = requestPath.match(/^\/plugins\/([^/]+)/);
    const source = pluginMatch ? `plugin:${normalizeLogFacet(pluginMatch[1])}` : "core:web";
    res.setHeader("X-Request-Id", requestId);
    return withLogContext({ source, category: "http", requestId }, () => {
      res.on("finish", () => {
        if (["/api/events", "/admin/updates/events"].includes(requestPath)) return;
        const durationMs = Date.now() - startedAt;
        const status = Number(res.statusCode) || 0;
        const mutating = !["GET", "HEAD", "OPTIONS"].includes(method);
        const slow = durationMs >= 2000;
        if (!mutating && status < 400 && !slow) return;
        const level = status >= 500 ? "error" : status >= 400 || slow ? "warn" : "info";
        const category = mutating && status < 400 ? "audit" : "http";
        const routePath = typeof req.route?.path === "string"
          ? `${req.baseUrl || ""}${req.route.path}`
          : requestPath.replace(/\b[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\b/gi, ":id");
        webLog.log(level, "HTTP request completed", {
          method,
          path: routePath,
          status,
          duration_ms: durationMs,
          user_id: req.session?.user?.id || null,
          role: req.session?.user?.isAdmin ? "admin" : req.session?.user?.isMod ? "mod" : req.session?.user ? "user" : "anonymous"
        }, {
          source,
          category,
          event: status >= 400 ? "http_error" : slow ? "slow_request" : "admin_action",
          requestId
        });
      });
      next();
    });
  });
  app.use((_req, res, next) => {
    res.setHeader("X-Content-Type-Options", "nosniff");
    next();
  });
  app.use(express.static(path.join(__dirname, "public")));

  const uploadDir = path.join(__dirname, "..", "..", "data", "uploads");
  fs.mkdirSync(uploadDir, { recursive: true });
  const navIconDir = path.join(__dirname, "..", "..", "data", "nav-icons");
  fs.mkdirSync(navIconDir, { recursive: true });
  app.use("/assets/nav-icons", express.static(navIconDir));
  const feedbackScreenshotDir = path.join(__dirname, "..", "..", "data", "feedback", "screenshots");
  fs.mkdirSync(feedbackScreenshotDir, { recursive: true });
  const feedbackAttachmentDir = path.join(__dirname, "..", "..", "data", "feedback", "attachments");
  fs.mkdirSync(feedbackAttachmentDir, { recursive: true });
  const upload = multer
    ? multer({
        dest: uploadDir,
        limits: { fileSize: 256 * 1024 * 1024, files: 1, fields: 20, parts: 24 },
        fileFilter: (_req, file, cb) => {
          const extension = path.extname(file.originalname || "").toLowerCase();
          const acceptedMime = ["application/zip", "application/x-zip-compressed", "application/octet-stream"].includes(file.mimetype);
          if (extension === ".zip" && acceptedMime) return cb(null, true);
          cb(new Error("Only ZIP archives are allowed."));
        }
      })
    : null;
  const uploadSingle = (fieldName) => {
    if (!upload) {
      return (req, _res, next) => {
        req.uploadError = "File uploads require npm install.";
        next();
      };
    }
    return (req, res, next) => upload.single(fieldName)(req, res, (error) => {
      if (error) {
        cleanupUploadedFiles([req.file, req.files]);
        req.uploadError = error.code === "LIMIT_FILE_SIZE"
          ? "The ZIP archive must be 256 MB or smaller."
          : error.message;
        return next();
      }
      try {
        if (req.file) {
          validateUploadedFile(req.file, {
            allowedTypes: ["zip"],
            maxBytes: 256 * 1024 * 1024,
            requireExtension: true,
            label: "ZIP archive"
          });
        }
      } catch (validationError) {
        cleanupUploadedFiles(req.file);
        req.file = null;
        req.uploadError = validationError.message;
      }
      next();
    });
  };
  const navIconUpload =
    multer &&
    multer({
      storage: multer.diskStorage({
        destination: (_req, _file, cb) => cb(null, navIconDir),
        filename: (_req, file, cb) => {
          const ext = path.extname(file.originalname || ".svg").slice(0, 8);
          cb(null, `${crypto.randomUUID()}${ext}`);
        }
      }),
      limits: { fileSize: 2 * 1024 * 1024, files: 1, fields: 10, parts: 12 },
      fileFilter: (_req, file, cb) => {
        if (file.mimetype === "image/png" || file.mimetype === "image/svg+xml") {
          return cb(null, true);
        }
        cb(new Error("Only SVG or PNG files are allowed."));
      }
    });
  const navIconSingle = (req, _res, next) => {
    if (!navIconUpload) {
      req.uploadError = "File uploads require npm install.";
      return next();
    }
    return navIconUpload.single("icon_file")(req, _res, (error) => {
      if (error) {
        cleanupUploadedFiles([req.file, req.files]);
        req.uploadError = error.code === "LIMIT_FILE_SIZE"
          ? "Navigation icons must be 2 MB or smaller."
          : error.message;
        return next();
      }
      try {
        if (req.file) {
          validateUploadedFile(req.file, {
            allowedTypes: ["png", "svg"],
            maxBytes: 2 * 1024 * 1024,
            requireExtension: true,
            label: "navigation icon"
          });
        }
      } catch (validationError) {
        cleanupUploadedFiles(req.file);
        req.file = null;
        req.uploadError = validationError.message;
      }
      next();
    });
  };
  const feedbackScreenshotUpload =
    multer &&
    multer({
      storage: multer.diskStorage({
        destination: (_req, file, cb) => cb(null, file.fieldname === "attachments" ? feedbackAttachmentDir : feedbackScreenshotDir),
        filename: (_req, file, cb) => {
          const ext = file.fieldname === "attachments" ? feedbackAttachmentExtension(file) : screenshotExtension(file.mimetype);
          cb(null, `${crypto.randomUUID()}${ext}`);
        }
      }),
      limits: { fileSize: 8 * 1024 * 1024, files: 4, fields: 30, parts: 36 },
      fileFilter: (_req, file, cb) => {
        if (file.fieldname === "screenshot" && ["image/png", "image/jpeg", "image/webp"].includes(file.mimetype)) {
          return cb(null, true);
        }
        if (file.fieldname === "attachments" && ["image/png", "image/jpeg", "image/webp", "application/pdf", "text/plain"].includes(file.mimetype)) {
          return cb(null, true);
        }
        cb(new Error("Only PNG, JPEG, WebP, PDF, or text feedback files are allowed."));
      }
    });
  const feedbackUploadFields = (req, res, next) => {
    if (!feedbackScreenshotUpload) {
      return next();
    }
    return feedbackScreenshotUpload.fields([
      { name: "screenshot", maxCount: 1 },
      { name: "attachments", maxCount: 3 }
    ])(req, res, (error) => {
      if (error) {
        cleanupUploadedFiles(req.files);
        req.files = {};
        req.feedbackUploadError = error.code === "LIMIT_FILE_SIZE"
          ? "Each feedback file must be 8 MB or smaller."
          : error.message;
        return next();
      }
      try {
        validateUploadedFiles(req.files?.screenshot, {
          allowedTypes: ["png", "jpeg", "webp"],
          maxBytes: 8 * 1024 * 1024,
          requireExtension: true,
          label: "screenshot"
        });
        validateUploadedFiles(req.files?.attachments, {
          allowedTypes: ["png", "jpeg", "webp", "pdf", "text"],
          maxBytes: 8 * 1024 * 1024,
          requireExtension: true,
          label: "feedback attachment"
        });
      } catch (validationError) {
        cleanupUploadedFiles(req.files);
        req.files = {};
        req.feedbackUploadError = validationError.message;
      }
      next();
    });
  };

  const navItems = [];
  const profileSections = [];
  const assistantPanels = [];
  const web = {
    auth: webAuth,
    createRouter: () => express.Router(),
    addRoute: (method, routePath, ...handlers) => {
      const normalizedMethod = String(method || "get").toLowerCase();
      if (typeof app[normalizedMethod] !== "function" || !routePath || !handlers.length) {
        throw new Error("Invalid plugin WebUI route registration.");
      }
      app[normalizedMethod](routePath, ...handlers);
    },
    mount: (mountPath, router, navItem) => {
      app.use(mountPath, webAuth.requireConfigured, router);
      if (navItem) {
        navItems.push({ ...navItem, path: mountPath });
      }
    },
    addNavItem: (navItem) => {
      navItems.push(navItem);
    },
    addProfileSection: (section) => {
      if (!section || (!section.view && !section.content)) {
        return;
      }
      profileSections.push(section);
    },
    addAssistantPanel: (panel) => {
      if (!panel || !panel.id || !panel.view || !fs.existsSync(panel.view)) {
        return () => {};
      }
      const existingIndex = assistantPanels.findIndex((item) => item.id === panel.id);
      if (existingIndex >= 0) {
        assistantPanels.splice(existingIndex, 1, panel);
      } else {
        assistantPanels.push(panel);
      }
      return () => {
        const index = assistantPanels.indexOf(panel);
        if (index >= 0) {
          assistantPanels.splice(index, 1);
        }
      };
    },
    placeholders,
    registerPlaceholder: placeholders.registerPlaceholder,
    registerPlaceholders: placeholders.registerPlaceholders,
    registerPlaceholderField: placeholders.registerFieldPolicy,
    addUpgradeHandler: upgradeRegistry.add,
    emitEvent: publishWebEvent
  };

  registerPublicOverlayRoutes(app);
  registerPublicContentRoutes(app);
  app.post("/api/diagnostics/v1/run", (req, res) => {
    res.set("Cache-Control", "no-store");
    res.set("Pragma", "no-cache");
    const authentication = authenticateDiagnosticsRequest(req);
    if (!authentication.allowed) {
      if (authentication.status === 429) {
        res.set("Retry-After", String(authentication.retry_after_seconds));
        return res.status(429).json({ ok: false, error: "Too many diagnostic requests. Try again shortly." });
      }
      return res.status(404).json({ error: "Not found." });
    }
    const requestId = crypto.randomUUID();
    const startedAt = Date.now();
    const check = String(req.body?.check || "").trim();
    res.set("X-RateLimit-Remaining", String(authentication.remaining));
    try {
      const diagnostic = runDiagnosticCheck(check);
      auditDiagnosticRequest({
        request_id: requestId,
        check,
        ok: true,
        fingerprint: authentication.fingerprint,
        duration_ms: Date.now() - startedAt
      });
      return res.json({ ok: true, request_id: requestId, diagnostic });
    } catch (error) {
      auditDiagnosticRequest({
        request_id: requestId,
        check,
        ok: false,
        fingerprint: authentication.fingerprint,
        reason: error.message,
        duration_ms: Date.now() - startedAt
      });
      return res.status(400).json({ ok: false, request_id: requestId, error: error.message });
    }
  });
  app.use(requireConfigured);
  app.get("/api/events", requireAuth, subscribeWebEvents);
  app.post("/api/destructive-confirmations", requireAuth, (req, res) => {
    try {
      res.json(issueConfirmation(req, req.body.action));
    } catch (error) {
      res.status(400).json({ error: error.message });
    }
  });
  app.get("/api/users/search", requireAuth, (req, res) => {
    res.set("Cache-Control", "no-store");
    res.json({
      ok: true,
      users: searchKnownUsers(req.query.q, { limit: req.query.limit || 30 })
    });
  });
  app.get("/api/placeholders/catalog", requireAuth, (req, res) => {
    res.set("Cache-Control", "no-store");
    try {
      const catalog = placeholders.catalog({
        fieldId: req.query.field_id,
        outputAudience: req.query.output_audience,
        user: req.session.user
      });
      res.json({ ok: true, ...catalog });
    } catch (error) {
      res.status(400).json({ ok: false, error: error.message });
    }
  });
  app.post("/api/placeholders/preview", requireAuth, async (req, res) => {
    res.set("Cache-Control", "no-store");
    try {
      const rendered = await placeholders.renderTemplate({
        fieldId: req.body.field_id,
        template: req.body.template,
        outputAudience: req.body.output_audience,
        user: req.session.user,
        runtimeContext: {
          user: req.session.user,
          preview: true
        }
      });
      res.json({ ok: rendered.ok, rendered: rendered.rendered, errors: rendered.errors });
    } catch (error) {
      res.status(400).json({ ok: false, error: error.message });
    }
  });
  app.get("/api/feedback/similar", requireAuth, (req, res) => {
    try {
      res.json({
        ok: true,
        matches: findSimilarFeedback(req.query, {
          userId: req.session.user.id,
          limit: req.query.limit || 5
        })
      });
    } catch (error) {
      res.status(400).json({ error: error.message });
    }
  });
  app.post("/api/feedback/:id/support", requireAuth, (req, res) => {
    try {
      const support_count = supportFeedback(req.params.id, req.session.user);
      res.json({ ok: true, support_count });
    } catch (error) {
      res.status(400).json({ error: error.message });
    }
  });
  app.post("/api/feedback", requireAuth, feedbackUploadFields, (req, res) => {
    try {
      if (req.feedbackUploadError) {
        throw new Error(req.feedbackUploadError);
      }
      const body = normalizeFeedbackRequestBody(req.body);
      const similarMatches = findSimilarFeedback(body, {
        userId: req.session.user.id,
        limit: 5
      });
      const similarityConfirmed = body.diagnostics?.similar_feedback_confirmation === "distinct_or_additional_context";
      if (similarMatches.length && !similarityConfirmed) {
        cleanupUploadedFiles(req.files);
        return res.status(409).json({
          ok: false,
          reason: "similar_feedback_confirmation_required",
          error: "Review the related feedback, then confirm that this report is distinct or adds useful context.",
          matches: similarMatches
        });
      }
      const screenshotFile = req.files?.screenshot?.[0] || null;
      const attachmentFiles = req.files?.attachments || [];
      const entry = createFeedback(body, req.session.user, {
        screenshot: screenshotFile
          ? {
              path: `feedback/screenshots/${screenshotFile.filename}`,
              mime: screenshotFile.mimetype,
              size: screenshotFile.size
            }
          : null,
        attachments: attachmentFiles.map((file) => ({
          path: `feedback/attachments/${file.filename}`,
          mime: file.mimetype,
          size: file.size,
          original_name: file.originalname
        }))
      });
      res.status(201).json({
        ok: true,
        id: entry.id,
        message: "Feedback submitted. You can review it from the Feedback page."
      });
    } catch (error) {
      cleanupUploadedFiles(req.files);
      res.status(400).json({ error: error.message });
    }
  });
  app.get("/api/feedback/notifications", requireAuth, (req, res) => {
    res.set("Cache-Control", "no-store");
    res.json(notificationSummary(req.session.user.id));
  });
  app.use((req, res, next) => {
    if (req.method !== "POST" || !isDestructivePath(req.path)) return next();
    const confirmation = consumeConfirmation(req, normalizeAction(req.originalUrl));
    if (confirmation.valid) return next();
    const message = confirmation.reason === "too_early"
      ? "Confirmation was submitted before the safety timer completed."
      : "This action requires a new timed confirmation.";
    if (req.accepts("html")) {
      req.session.flash = { type: "error", message };
      return res.redirect(req.get("referer") || "/");
    }
    return res.status(409).json({ error: message, reason: confirmation.reason });
  });
  app.use((req, res, next) => {
    res.locals.siteTitle = getSetting("site_title", "Lumi Bot");
    res.locals.assetVersion = assetVersion;
    res.locals.user = req.session.user || null;
    res.locals.flash = req.session.flash || null;
    res.locals.softError = null;
    res.locals.theme = getThemeSettings();
    res.locals.botAvatar = getSetting("bot_avatar_url", null);
    const platformStatus = getPlatformStatus();
    res.locals.platforms = platformStatus;
    const localhostLogin = getLocalhostLoginPlatform(req);
    res.locals.localhostLoginAvailable = Boolean(localhostLogin);
    res.locals.platformLogins = [
      ...(localhostLogin ? [localhostLogin] : []),
      ...platformStatus.filter(
        (platform) => platform.supported && platform.enabled && platform.supportsLogin
      )
    ];
    res.locals.platformLinks = platformStatus.filter(
      (platform) => platform.supported && platform.enabled && platform.supportsLink
    );
    const twitchPlatform = platformStatus.find((platform) => platform.id === "twitch");
    res.locals.twitchConfigured = Boolean(twitchPlatform?.configured);
    res.locals.currentPath = req.path;
    res.locals.pageWidth = uiContentWidth(req.path);
    res.locals.userAvatar = req.session.user
      ? getPreferredAvatar(req.session.user.id)
      : null;
    res.locals.userInitial = req.session.user?.username
      ? req.session.user.username.charAt(0).toUpperCase()
      : "";
    res.locals.feedbackNotifications = notificationSummary(req.session.user?.id);
    res.locals.feedbackOptions = feedbackOptions();
    req.session.flash = null;
    trackModRole(db, req.session.user);
    res.locals.navSections = buildNavSections(
      req.session.user,
      navItems,
      req.path
    );
    next();
  });

  app.use((req, res, next) => {
    const originalRender = res.render.bind(res);
    res.render = (view, options, callback) => {
      if (typeof options === "function") {
        callback = options;
        options = {};
      }
      const handleError = (err) => {
        if (!err) {
          return;
        }
        const message = err?.message || "";
        const isMissing = message.includes("Failed to lookup view");
        const context = {
          view,
          method: req.method,
          path: req.path,
          userId: req.session.user?.id || null,
          message,
          stack: err?.stack || ""
        };
        if (!isMissing) {
          log("error", "Render failed", context);
          return originalRender(
            "error",
            {
              title: "Something went wrong",
              message: "An unexpected error occurred. Please try again."
            },
            callback
          );
        }
        log("warn", "Missing view fallback", context);
        res.locals.softError = "Some content could not be loaded.";
        if (view === "missing-view") {
          return res
            .status(200)
            .send(
              "<!doctype html><title>Content missing</title><h1>Content unavailable</h1><p>Some content could not be loaded.</p>"
            );
        }
        return originalRender(
          "missing-view",
          {
            title: "Content missing",
            resource: "A page component failed to load. Please try again."
          },
          callback
        );
      };

      return originalRender(view, options, (err, html) => {
        if (err) {
          return handleError(err);
        }
        if (typeof callback === "function") {
          return callback(null, html);
        }
        res.send(html);
      });
    };
    next();
  });

  registerOverlayAdminRoutes(app);
  registerContentAdminRoutes(app, { requireAdmin: requireRole("admin") });

  app.get("/", async (req, res, next) => {
    try {
      res.render("home", {
        title: "Home",
        homepageLinks: homepageLinksForUser(req.session.user),
        homepageHero: await homepageHeroForUser(req.session.user, req)
      });
    } catch (error) {
      next(error);
    }
  });

  app.get("/api/assistant-panels", async (req, res) => {
    res.set("Cache-Control", "no-store");
    if (!req.session.user) {
      return res.json({ panels: [] });
    }

    const panels = [];
    for (const panel of assistantPanels) {
      let panelDebug = panel.debug || null;
      try {
        if (typeof panel.getDebug === "function") {
          panelDebug = await panel.getDebug(req.session.user);
        }
      } catch {}
      let panelAccess = null;
      try {
        panelAccess = typeof panel.canAccess === "function"
          ? await panel.canAccess(req.session.user, {
              origin: "webui",
              platform: "webui",
              requested_surface: "webui_panel"
            })
          : { allowed: hasAccess(req.session.user, panel.role || "public"), reason: "role_forbidden" };
      } catch (error) {
        panelAccess = { allowed: false, reason: "access_check_failed", debug_details: { error: error.message } };
      }
      if (panelAccess === false || panelAccess?.allowed === false) {
        panels.push({
          ...unavailableAssistantPanel(panel, panelAccess?.reason || "role_forbidden"),
          debug: { ...(panelDebug || {}), permission: panelAccess?.debug_details || null }
        });
        continue;
      }

      let availability;
      try {
        availability = typeof panel.getAvailability === "function"
          ? await panel.getAvailability(req.session.user)
          : {
              available: typeof panel.isVisible === "function"
                ? Boolean(await panel.isVisible(req.session.user))
                : true
            };
      } catch (error) {
        console.error(`Assistant panel ${panel.id} availability check failed`, error);
        panels.push({ ...unavailableAssistantPanel(panel, "availability_check_failed"), debug: panelDebug });
        continue;
      }

      if (!availability?.available) {
        panels.push({
          ...unavailableAssistantPanel(panel, availability?.reason_code || "unavailable"),
          status: availability?.status || "offline",
          debug: {
            ...(panelDebug || {}),
            permission: availability?.permission?.debug_details || panelAccess?.debug_details || null
          }
        });
        continue;
      }

      try {
        const rendered = await renderAssistantPanel(app, panel, req.session.user);
        panel.onRenderDiagnostic?.({
          panel_endpoint_status: 200,
          panel_html_length: rendered.html.length,
          panel_html_error: null,
          panel_template_path: panel.view,
          missing_locals: []
        });
        if (typeof panel.getDebug === "function") {
          panelDebug = await panel.getDebug(req.session.user);
        }
        panels.push({
          available: true,
          panel_id: panel.id,
          status: availability.status || "healthy",
          reason_code: null,
          version: panel.version || assetVersion,
          html: rendered.html,
          stylesheet: panel.stylesheet || null,
          script: panel.script || null,
          debug: {
            ...(panelDebug || {}),
            permission: availability?.permission?.debug_details || panelAccess?.debug_details || null
          }
        });
      } catch (error) {
        console.error(`Assistant panel ${panel.id} render failed`, error);
        panel.onRenderDiagnostic?.({
          panel_endpoint_status: 500,
          panel_html_length: 0,
          panel_html_error: error.message,
          panel_template_path: panel.view,
          missing_locals: error.missingLocals || []
        });
        if (typeof panel.getDebug === "function") {
          try { panelDebug = await panel.getDebug(req.session.user); } catch {}
        }
        panels.push({
          ...unavailableAssistantPanel(panel, "render_failed"),
          render_error: {
            message: error.message || "Assistant panel rendering failed.",
            missing_locals: error.missingLocals || []
          },
          debug: panelDebug
        });
      }
    }
    return res.json({ panels });
  });

  app.get("/setup", (req, res) => {
    if (isConfigured()) {
      return res.redirect("/");
    }
    const platforms = getPlatformStatus();
    res.render("setup", {
      title: "Initial setup",
      platforms
    });
  });

  app.get("/setup/discord", (req, res) => {
    if (!isPlatformEnabled("discord")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    const current = getDiscordSettings();
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const form = {
      ...current,
      discord_client_secret: "",
      discord_bot_token: "",
      discord_redirect_uri:
        current.discord_redirect_uri || `${baseUrl}/auth/discord/callback`
    };
    storeSnapshot(req, "discordWizardSnapshot", current);
    res.render("wizard-discord", {
      title: "Discord setup",
      form,
      checks: [],
      errors: [],
      actionBase: "/setup/discord",
      cancelPath: "/setup"
    });
  });

  app.post("/setup/discord/verify", async (req, res) => {
    if (!isPlatformEnabled("discord")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    const current = getDiscordSettings();
    const incoming = {
      discord_client_id: req.body.discord_client_id || "",
      discord_client_secret: req.body.discord_client_secret || "",
      discord_redirect_uri: req.body.discord_redirect_uri || "",
      discord_bot_token: req.body.discord_bot_token || "",
      discord_guild_id: req.body.discord_guild_id || "",
      discord_admin_role_id: req.body.discord_admin_role_id || "",
      discord_mod_role_id: req.body.discord_mod_role_id || ""
    };
    const merged = mergeSecrets(
      current,
      incoming,
      new Set(["discord_client_secret", "discord_bot_token"])
    );
    if (!merged.discord_redirect_uri) {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      merged.discord_redirect_uri = `${baseUrl}/auth/discord/callback`;
    }
    const result = await verifyDiscordSettings(merged);
    if (!result.ok) {
      res.render("wizard-discord", {
        title: "Discord setup",
        form: {
          ...incoming,
          discord_client_secret: "",
          discord_bot_token: "",
          discord_redirect_uri: merged.discord_redirect_uri
        },
        checks: result.checks,
        errors: result.errors,
        actionBase: "/setup/discord",
        cancelPath: "/setup"
      });
      return;
    }
    saveSettingsMap(merged);
    delete req.session.discordWizardSnapshot;
    setFlash(req, "success", "Discord setup saved. Please log in.");
    res.redirect("/auth/discord");
  });

  app.post("/setup/discord/cancel", (req, res) => {
    if (!isPlatformEnabled("discord")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    restoreSnapshot(req, "discordWizardSnapshot");
    setFlash(req, "info", "Discord setup canceled.");
    res.redirect("/setup");
  });

  app.get("/setup/twitch", (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    const current = getTwitchSettings();
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const form = {
      ...current,
      twitch_client_secret: "",
      twitch_bot_oauth: "",
      twitch_redirect_uri:
        current.twitch_redirect_uri || `${baseUrl}/auth/twitch/callback`
    };
    storeSnapshot(req, "twitchWizardSnapshot", current);
    res.render("wizard-twitch", {
      title: "Twitch setup",
      form,
      checks: [],
      errors: [],
      actionBase: "/setup/twitch",
      cancelPath: "/setup"
    });
  });

  app.post("/setup/twitch/verify", async (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    const current = getTwitchSettings();
    const incoming = {
      twitch_client_id: req.body.twitch_client_id || "",
      twitch_client_secret: req.body.twitch_client_secret || "",
      twitch_redirect_uri: req.body.twitch_redirect_uri || "",
      twitch_bot_username: req.body.twitch_bot_username || "",
      twitch_bot_oauth: req.body.twitch_bot_oauth || "",
      twitch_channels: req.body.twitch_channels || ""
    };
    const merged = mergeSecrets(
      current,
      incoming,
      new Set(["twitch_client_secret", "twitch_bot_oauth"])
    );
    if (!merged.twitch_redirect_uri) {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      merged.twitch_redirect_uri = `${baseUrl}/auth/twitch/callback`;
    }
    const result = await verifyTwitchSettings(merged);
    if (!result.ok) {
      res.render("wizard-twitch", {
        title: "Twitch setup",
        form: {
          ...incoming,
          twitch_client_secret: "",
          twitch_bot_oauth: "",
          twitch_redirect_uri: merged.twitch_redirect_uri
        },
        checks: result.checks,
        errors: result.errors,
        actionBase: "/setup/twitch",
        cancelPath: "/setup"
      });
      return;
    }
    saveSettingsMap(merged);
    delete req.session.twitchWizardSnapshot;
    setFlash(req, "success", "Twitch setup saved.");
    res.redirect("/setup");
  });

  app.post("/setup/twitch/cancel", (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    restoreSnapshot(req, "twitchWizardSnapshot");
    setFlash(req, "info", "Twitch setup canceled.");
    res.redirect("/setup");
  });

  app.get("/setup/youtube", (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    const current = getYouTubeSettings();
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const form = {
      ...current,
      youtube_client_secret: "",
      youtube_redirect_uri:
        current.youtube_redirect_uri || `${baseUrl}/auth/youtube/callback`
    };
    const snapshot = {
      ...current,
      youtube_bot_refresh_token: getSetting("youtube_bot_refresh_token", ""),
      youtube_bot_channel_id: getSetting("youtube_bot_channel_id", "")
    };
    storeSnapshot(req, "youtubeWizardSnapshot", snapshot);
    res.render("wizard-youtube", {
      title: "YouTube setup",
      form,
      checks: [],
      errors: [],
      actionBase: "/setup/youtube",
      cancelPath: "/setup",
      connectPath: "/setup/youtube/connect",
      botConnected: Boolean(getSetting("youtube_bot_refresh_token", "")),
      botChannelId: getSetting("youtube_bot_channel_id", ""),
      botChannelName: getYouTubeClient()?.channelName || null
    });
  });

  app.post("/setup/youtube/connect", (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const clientId = (req.body.youtube_client_id || "").trim();
    const clientSecret = (req.body.youtube_client_secret || "").trim();
    const redirectUri =
      (req.body.youtube_redirect_uri || "").trim() ||
      `${baseUrl}/auth/youtube/callback`;
    if (!clientId || !clientSecret) {
      setFlash(req, "error", "Client ID and Client Secret are required.");
      return res.redirect("/setup/youtube");
    }
    setSetting("youtube_client_id", clientId);
    setSetting("youtube_client_secret", clientSecret);
    setSetting("youtube_redirect_uri", redirectUri);
    const state = crypto.randomBytes(16).toString("hex");
    req.session.youtubeBotState = state;
    req.session.youtubeBotReturnTo = "/setup/youtube";
    const url = buildYouTubeAuthUrl(state, redirectUri, { prompt: "consent" });
    res.redirect(url);
  });

  app.post("/setup/youtube/verify", async (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    const current = getYouTubeSettings();
    const incoming = {
      youtube_client_id: req.body.youtube_client_id || "",
      youtube_client_secret: req.body.youtube_client_secret || "",
      youtube_redirect_uri: req.body.youtube_redirect_uri || ""
    };
    const merged = mergeSecrets(
      current,
      incoming,
      new Set(["youtube_client_secret"])
    );
    if (!merged.youtube_redirect_uri) {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      merged.youtube_redirect_uri = `${baseUrl}/auth/youtube/callback`;
    }
    const result = await verifyYouTubeSettings({
      ...merged,
      youtube_bot_refresh_token: getSetting("youtube_bot_refresh_token", "")
    });
    if (!result.ok) {
      res.render("wizard-youtube", {
        title: "YouTube setup",
        form: {
          ...incoming,
          youtube_client_secret: "",
          youtube_redirect_uri: merged.youtube_redirect_uri
        },
        checks: result.checks,
        errors: result.errors,
        actionBase: "/setup/youtube",
        cancelPath: "/setup",
        connectPath: "/setup/youtube/connect",
        botConnected: Boolean(getSetting("youtube_bot_refresh_token", "")),
        botChannelId: getSetting("youtube_bot_channel_id", ""),
        botChannelName: getYouTubeClient()?.channelName || null
      });
      return;
    }
    if (result.channel?.id) {
      merged.youtube_bot_channel_id = result.channel.id;
    }
    saveSettingsMap(merged);
    delete req.session.youtubeWizardSnapshot;
    setFlash(req, "success", "YouTube setup saved.");
    res.redirect("/setup");
  });

  app.post("/setup/youtube/cancel", (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      return res.redirect("/setup");
    }
    if (isConfigured()) {
      return res.redirect("/");
    }
    restoreSnapshot(req, "youtubeWizardSnapshot");
    setFlash(req, "info", "YouTube setup canceled.");
    res.redirect("/setup");
  });

  app.get("/auth/discord", (req, res) => {
    if (!isPlatformEnabled("discord")) {
      setFlash(req, "error", "Discord is disabled in Platform Integration.");
      return res.redirect("/setup");
    }
    if (!isPlatformConfigured("discord")) {
      setFlash(req, "error", "Discord is not configured yet.");
      return res.redirect("/setup");
    }
    const state = crypto.randomBytes(16).toString("hex");
    if (req.session.user) {
      req.session.discordLinkState = state;
    } else {
      req.session.discordState = state;
    }
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const redirectUri =
      getSetting("discord_redirect_uri") ||
      `${baseUrl}/auth/discord/callback`;
    const url = buildDiscordAuthUrl(state, redirectUri);
    res.redirect(url);
  });

  app.get("/auth/discord/callback", async (req, res) => {
    if (!isPlatformEnabled("discord")) {
      return res.status(400).render("error", {
        title: "Login failed",
        message: "Discord is disabled in Platform Integration."
      });
    }
    const { code, state } = req.query;
    const isLogin = state && state === req.session.discordState;
    const isLink = state && state === req.session.discordLinkState && req.session.user;
    if (!code || (!isLogin && !isLink)) {
      return res.status(400).render("error", {
        title: "Login failed",
        message: "Invalid OAuth state."
      });
    }
    try {
      if (isLogin) {
        delete req.session.discordState;
      }
      if (isLink) {
        delete req.session.discordLinkState;
      }
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      const redirectUri =
        getSetting("discord_redirect_uri") ||
        `${baseUrl}/auth/discord/callback`;
      const token = await exchangeDiscordCode(code, redirectUri);
      const user = await fetchDiscordUser(token.access_token);
      const guildId = getSetting("discord_guild_id");
      const member = guildId
        ? await fetchDiscordGuildMember(token.access_token, guildId)
        : null;
      const roles = member?.roles || [];
      const flags = getRoleFlags(roles);
      if (isLink) {
        const linked = linkIdentityToUser({
          userId: req.session.user.id,
          provider: "discord",
          providerUserId: user.id,
          displayName: user.global_name || user.username,
          avatar: user.avatar
            ? `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png?size=128`
            : null
        });
        req.session.user = {
          id: linked.id,
          username: linked.internal_username,
          avatar: user.avatar,
          roles,
          ...flags
        };
        req.session.discordToken = token;
        setFlash(req, "success", "Discord account linked.");
        res.redirect("/profile");
        return;
      }
      const profile = storeDiscordUser(user);
      req.session.user = {
        id: profile.id,
        username: profile.internal_username,
        avatar: user.avatar,
        roles,
        ...flags
      };
      req.session.discordToken = token;
      setFlash(req, "success", "Logged in.");
      res.redirect("/");
    } catch (error) {
      console.error(error);
      res.status(500).render("error", {
        title: "Login failed",
        message: "Discord authentication failed."
      });
    }
  });

  app.get("/auth/localhost", (req, res) => {
    if (!isLocalhostLoginAvailable(req)) {
      return res.status(404).render("error", {
        title: "Login unavailable",
        message: "Localhost Login is only available from a localhost request."
      });
    }
    res.render("localhost-login", {
      title: "Localhost Login",
      username: getSetting("localhost_login_username", "admin")
    });
  });

  app.post("/auth/localhost", (req, res) => {
    if (!isLocalhostLoginAvailable(req)) {
      return res.status(404).render("error", {
        title: "Login unavailable",
        message: "Localhost Login is only available from a localhost request."
      });
    }
    const username = String(req.body.username || "").trim();
    const password = String(req.body.password || "");
    const expectedUsername = String(getSetting("localhost_login_username", "admin"));
    const expectedPassword = String(getSetting("localhost_login_password", "admin"));
    if (username !== expectedUsername || password !== expectedPassword) {
      setFlash(req, "error", "Invalid localhost username or password.");
      return res.redirect("/auth/localhost");
    }
    const profile = ensureUserForIdentity({
      provider: "localhost",
      providerUserId: expectedUsername,
      displayName: expectedUsername,
      fallbackName: "Localhost Admin"
    });
    req.session.user = {
      id: profile.id,
      username: profile.internal_username,
      avatar: null,
      roles: ["localhost-admin"],
      isAdmin: true,
      isMod: true,
      isLocalhost: true
    };
    setFlash(req, "success", "Logged in with Localhost Login.");
    res.redirect("/");
  });

  app.post("/auth/logout", (req, res) => {
    req.session.destroy(() => {
      res.redirect("/");
    });
  });

  app.get("/auth/twitch", requireAuth, (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      setFlash(req, "error", "Twitch is disabled in Platform Integration.");
      return res.redirect("/profile");
    }
    if (!isPlatformConfigured("twitch")) {
      setFlash(req, "error", "Twitch is not configured yet.");
      return res.redirect("/profile");
    }
    const state = crypto.randomBytes(16).toString("hex");
    req.session.twitchState = state;
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const redirectUri =
      getSetting("twitch_redirect_uri") ||
      `${baseUrl}/auth/twitch/callback`;
    const url = buildTwitchAuthUrl(state, redirectUri);
    res.redirect(url);
  });

  app.get("/auth/twitch/login", (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      setFlash(req, "error", "Twitch is disabled in Platform Integration.");
      return res.redirect("/setup");
    }
    if (!isPlatformConfigured("twitch")) {
      setFlash(req, "error", "Twitch is not configured yet.");
      return res.redirect("/setup");
    }
    const state = crypto.randomBytes(16).toString("hex");
    req.session.twitchLoginState = state;
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const redirectUri =
      getSetting("twitch_redirect_uri") ||
      `${baseUrl}/auth/twitch/callback`;
    const url = buildTwitchAuthUrl(state, redirectUri);
    res.redirect(url);
  });

  app.get("/admin/twitch-events/connect", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("twitch") || !isPlatformConfigured("twitch")) {
      setFlash(req, "error", "Configure and enable Twitch before connecting event alerts.");
      return res.redirect("/admin/overlays");
    }
    const state = crypto.randomBytes(24).toString("hex");
    const requestedReturn = String(req.query.return || "");
    req.session.twitchEventState = state;
    req.session.twitchEventReturn = /^\/admin\/[a-zA-Z0-9/?=&._-]*$/.test(requestedReturn)
      ? requestedReturn
      : "/admin/overlays";
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const redirectUri = getSetting("twitch_redirect_uri") || `${baseUrl}/auth/twitch/callback`;
    res.redirect(buildTwitchEventAuthUrl(state, redirectUri));
  });

  app.get("/auth/twitch/callback", async (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      return res.status(400).render("error", {
        title: "Auth failed",
        message: "Twitch is disabled in Platform Integration."
      });
    }
    const { code, state } = req.query;
    const isLogin = state && state === req.session.twitchLoginState;
    const isLink = state && state === req.session.twitchState && req.session.user;
    const isEvent = state && state === req.session.twitchEventState && req.session.user?.isAdmin;
    if (!code || (!isLogin && !isLink && !isEvent)) {
      return res.status(400).render("error", {
        title: "Auth failed",
        message: "Invalid Twitch OAuth state."
      });
    }
    try {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      const redirectUri =
        getSetting("twitch_redirect_uri") ||
        `${baseUrl}/auth/twitch/callback`;
      const token = await exchangeTwitchCode(code, redirectUri);
      const twitchUser = await fetchTwitchUser(token.access_token);
      if (!twitchUser) {
        throw new Error("Twitch user not found.");
      }
      const now = Date.now();
      if (isEvent) {
        setSetting("twitch_event_oauth", token.access_token);
        setSetting("twitch_event_refresh_token", token.refresh_token || "");
        setSetting("twitch_event_expires_at", token.expires_in ? now + token.expires_in * 1000 : null);
        setSetting("twitch_event_user_id", twitchUser.id);
        setSetting("twitch_event_login", twitchUser.login || twitchUser.display_name);
        const returnTo = req.session.twitchEventReturn || "/admin/overlays";
        delete req.session.twitchEventState;
        delete req.session.twitchEventReturn;
        await twitchEventSubManager.restart();
        setFlash(req, "success", `Twitch event alerts connected as ${twitchUser.display_name}.`);
        res.redirect(returnTo);
      } else if (isLogin) {
        const profile = ensureUserForIdentity({
          provider: "twitch",
          providerUserId: twitchUser.id,
          displayName: twitchUser.display_name,
          avatar: twitchUser.profile_image_url || null
        });
        db.prepare(
          "INSERT INTO linked_accounts (user_id, provider, provider_user_id, display_name, access_token, refresh_token, expires_at, created_at, updated_at) " +
            "VALUES (?, 'twitch', ?, ?, ?, ?, ?, ?, ?) " +
            "ON CONFLICT(user_id, provider) DO UPDATE SET provider_user_id = excluded.provider_user_id, display_name = excluded.display_name, access_token = excluded.access_token, refresh_token = excluded.refresh_token, expires_at = excluded.expires_at, updated_at = excluded.updated_at"
        ).run(
          profile.id,
          twitchUser.id,
          twitchUser.display_name,
          token.access_token,
          token.refresh_token || "",
          token.expires_in ? now + token.expires_in * 1000 : null,
          now,
          now
        );
        const discordIdentity = db
          .prepare(
            "SELECT provider_user_id FROM user_identities WHERE user_id = ? AND provider = 'discord'"
          )
          .get(profile.id);
        const roles = discordIdentity?.provider_user_id
          ? await fetchDiscordRolesForUser(discordIdentity.provider_user_id)
          : [];
        const flags = getRoleFlags(roles);
        req.session.user = {
          id: profile.id,
          username: profile.internal_username,
          roles,
          ...flags
        };
        req.session.twitchToken = token;
        setFlash(req, "success", "Logged in with Twitch.");
        res.redirect("/");
      } else {
        const profile = linkIdentityToUser({
          userId: req.session.user.id,
          provider: "twitch",
          providerUserId: twitchUser.id,
          displayName: twitchUser.display_name,
          avatar: twitchUser.profile_image_url || null
        });
        db.prepare(
          "INSERT INTO linked_accounts (user_id, provider, provider_user_id, display_name, access_token, refresh_token, expires_at, created_at, updated_at) " +
            "VALUES (?, 'twitch', ?, ?, ?, ?, ?, ?, ?) " +
            "ON CONFLICT(user_id, provider) DO UPDATE SET provider_user_id = excluded.provider_user_id, display_name = excluded.display_name, access_token = excluded.access_token, refresh_token = excluded.refresh_token, expires_at = excluded.expires_at, updated_at = excluded.updated_at"
        ).run(
          profile.id,
          twitchUser.id,
          twitchUser.display_name,
          token.access_token,
          token.refresh_token || "",
          token.expires_in ? now + token.expires_in * 1000 : null,
          now,
          now
        );
        req.session.user.id = profile.id;
        req.session.user.username = profile.internal_username;
        setFlash(req, "success", "Twitch account linked.");
        res.redirect("/profile");
      }
    } catch (error) {
      console.error(error);
      res.status(500).render("error", {
        title: isLogin ? "Login failed" : isEvent ? "Event connection failed" : "Link failed",
        message: isLogin
          ? "Unable to sign in with Twitch."
          : isEvent
            ? "Unable to authorize Twitch event alerts. Check the Twitch integration settings and try again."
          : "Unable to link Twitch account."
      });
    }
  });

  app.get("/auth/youtube", requireAuth, (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      setFlash(req, "error", "YouTube is disabled in Platform Integration.");
      return res.redirect("/profile");
    }
    if (!isPlatformConfigured("youtube")) {
      setFlash(req, "error", "YouTube is not configured yet.");
      return res.redirect("/profile");
    }
    const state = crypto.randomBytes(16).toString("hex");
    req.session.youtubeState = state;
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const redirectUri =
      getSetting("youtube_redirect_uri") ||
      `${baseUrl}/auth/youtube/callback`;
    const url = buildYouTubeAuthUrl(state, redirectUri);
    res.redirect(url);
  });

  app.get("/auth/youtube/login", (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      setFlash(req, "error", "YouTube is disabled in Platform Integration.");
      return res.redirect("/setup");
    }
    if (!isPlatformConfigured("youtube")) {
      setFlash(req, "error", "YouTube is not configured yet.");
      return res.redirect("/setup");
    }
    const state = crypto.randomBytes(16).toString("hex");
    req.session.youtubeLoginState = state;
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const redirectUri =
      getSetting("youtube_redirect_uri") ||
      `${baseUrl}/auth/youtube/callback`;
    const url = buildYouTubeAuthUrl(state, redirectUri);
    res.redirect(url);
  });

  app.get("/auth/youtube/callback", async (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      return res.status(400).render("error", {
        title: "Auth failed",
        message: "YouTube is disabled in Platform Integration."
      });
    }
    const { code, state } = req.query;
    const isLogin = state && state === req.session.youtubeLoginState;
    const isLink = state && state === req.session.youtubeState && req.session.user;
    const isBot = state && state === req.session.youtubeBotState;
    if (!code || (!isLogin && !isLink && !isBot)) {
      return res.status(400).render("error", {
        title: "Auth failed",
        message: "Invalid YouTube OAuth state."
      });
    }
    try {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      const redirectUri =
        getSetting("youtube_redirect_uri") ||
        `${baseUrl}/auth/youtube/callback`;
      const token = await exchangeYouTubeCode(code, redirectUri);
      const channel = await fetchYouTubeChannel(token.access_token);
      if (!channel) {
        throw new Error("YouTube channel not found.");
      }
      const displayName = channel.snippet?.title || "YouTube Channel";
      const avatar = channel.snippet?.thumbnails?.default?.url || null;
      const now = Date.now();

      if (isBot) {
        const refreshToken =
          token.refresh_token || getSetting("youtube_bot_refresh_token", "");
        if (!refreshToken) {
          throw new Error("Missing YouTube refresh token.");
        }
        setSetting("youtube_bot_refresh_token", refreshToken);
        setSetting("youtube_bot_channel_id", channel.id || "");
        req.session.youtubeBotState = null;
        const returnTo = req.session.youtubeBotReturnTo || "/admin/youtube-wizard";
        req.session.youtubeBotReturnTo = null;
        setFlash(req, "success", "YouTube bot connected.");
        return res.redirect(returnTo);
      }

      if (isLogin) {
        const profile = ensureUserForIdentity({
          provider: "youtube",
          providerUserId: channel.id,
          displayName,
          avatar
        });
        db.prepare(
          "INSERT INTO linked_accounts (user_id, provider, provider_user_id, display_name, access_token, refresh_token, expires_at, created_at, updated_at) " +
            "VALUES (?, 'youtube', ?, ?, ?, ?, ?, ?, ?) " +
            "ON CONFLICT(user_id, provider) DO UPDATE SET provider_user_id = excluded.provider_user_id, display_name = excluded.display_name, access_token = excluded.access_token, refresh_token = excluded.refresh_token, expires_at = excluded.expires_at, updated_at = excluded.updated_at"
        ).run(
          profile.id,
          channel.id,
          displayName,
          token.access_token,
          token.refresh_token || "",
          token.expires_in ? now + token.expires_in * 1000 : null,
          now,
          now
        );
        const discordIdentity = db
          .prepare(
            "SELECT provider_user_id FROM user_identities WHERE user_id = ? AND provider = 'discord'"
          )
          .get(profile.id);
        const roles = discordIdentity?.provider_user_id
          ? await fetchDiscordRolesForUser(discordIdentity.provider_user_id)
          : [];
        const flags = getRoleFlags(roles);
        req.session.user = {
          id: profile.id,
          username: profile.internal_username,
          roles,
          ...flags
        };
        req.session.youtubeToken = token;
        setFlash(req, "success", "Logged in with YouTube.");
        return res.redirect("/");
      }

      const profile = linkIdentityToUser({
        userId: req.session.user.id,
        provider: "youtube",
        providerUserId: channel.id,
        displayName,
        avatar
      });
      db.prepare(
        "INSERT INTO linked_accounts (user_id, provider, provider_user_id, display_name, access_token, refresh_token, expires_at, created_at, updated_at) " +
          "VALUES (?, 'youtube', ?, ?, ?, ?, ?, ?, ?) " +
          "ON CONFLICT(user_id, provider) DO UPDATE SET provider_user_id = excluded.provider_user_id, display_name = excluded.display_name, access_token = excluded.access_token, refresh_token = excluded.refresh_token, expires_at = excluded.expires_at, updated_at = excluded.updated_at"
      ).run(
        profile.id,
        channel.id,
        displayName,
        token.access_token,
        token.refresh_token || "",
        token.expires_in ? now + token.expires_in * 1000 : null,
        now,
        now
      );
      req.session.user.id = profile.id;
      req.session.user.username = profile.internal_username;
      setFlash(req, "success", "YouTube account linked.");
      res.redirect("/profile");
    } catch (error) {
      console.error(error);
      res.status(500).render("error", {
        title: isBot ? "Bot connect failed" : isLogin ? "Login failed" : "Link failed",
        message: isBot
          ? "Unable to connect the YouTube bot."
          : isLogin
          ? "Unable to sign in with YouTube."
          : "Unable to link YouTube account."
      });
    }
  });

  app.get("/profile", requireAuth, (req, res) => {
    const profile = getUserProfileById(req.session.user.id);
    if (!profile) {
      req.session.destroy(() => {
        res.redirect("/");
      });
      return;
    }
    const accounts = getUserIdentities(req.session.user.id);
    const cooldownDays = 90;
    const cooldownMs = cooldownDays * 24 * 60 * 60 * 1000;
    const lastUpdate = profile.username_updated_at || 0;
    const nextAllowedAt = lastUpdate ? lastUpdate + cooldownMs : 0;
    const canChangeUsername = !lastUpdate || Date.now() >= nextAllowedAt;
    const remainingMs = canChangeUsername ? 0 : nextAllowedAt - Date.now();
    const remainingDays = canChangeUsername
      ? 0
      : Math.max(1, Math.ceil(remainingMs / (24 * 60 * 60 * 1000)));
    const profileWidgets = profileSections
      .filter((section) => hasAccess(req.session.user, section.role || "public"))
      .slice()
      .sort((a, b) => (a.order || 100) - (b.order || 100))
      .map((section) => ({
        ...section,
        locals: {
          ...(section.locals || {}),
          user: req.session.user,
          profile,
          accounts
        }
      }));
    res.render("profile", {
      title: "Your profile",
      accounts,
      profile,
      profileSections: profileWidgets,
      canChangeUsername,
      usernameCooldownDays: cooldownDays,
      usernameCooldownRemainingDays: remainingDays,
      usernameNextAllowedAt: nextAllowedAt
    });
  });

  app.post("/profile/unlink/:provider", requireAuth, (req, res) => {
    const provider = req.params.provider;
    if (provider === "discord") {
      setFlash(req, "error", "Discord cannot be unlinked from the WebUI.");
      return res.redirect("/profile");
    }
    db.prepare(
      "DELETE FROM linked_accounts WHERE user_id = ? AND provider = ?"
    ).run(req.session.user.id, provider);
    db.prepare(
      "DELETE FROM user_identities WHERE user_id = ? AND provider = ?"
    ).run(req.session.user.id, provider);
    setFlash(req, "success", "Account unlinked.");
    res.redirect("/profile");
  });

  app.post("/profile/username", requireAuth, (req, res) => {
    const desired = (req.body.internal_username || "").trim();
    const profile = getUserProfileById(req.session.user.id);
    const cooldownMs = 90 * 24 * 60 * 60 * 1000;
    if (profile?.username_updated_at) {
      const nextAllowed = profile.username_updated_at + cooldownMs;
      if (Date.now() < nextAllowed) {
        setFlash(
          req,
          "error",
          "You can change your username once every 90 days."
        );
        return res.redirect("/profile");
      }
    }
    const result = updateInternalUsername(req.session.user.id, desired);
    if (!result.ok) {
      setFlash(req, "error", result.reason);
      return res.redirect("/profile");
    }
    req.session.user.username = result.username;
    setFlash(req, "success", "Username updated.");
    res.redirect("/profile");
  });

  app.get("/feedback", requireAuth, (req, res) => {
    markFeedbackViewed(req.session.user.id);
    res.locals.feedbackNotifications = notificationSummary(req.session.user.id);
    const selected = req.query.id
      ? getFeedbackForViewer(String(req.query.id), req.session.user.id)
      : null;
    res.render("feedback", {
      title: "Feedback",
      feedbackList: listPublicFeedback({ userId: req.session.user.id }),
      myFeedback: listMyFeedback(req.session.user.id),
      selectedFeedback: selected,
      feedbackOptions: feedbackOptions()
    });
  });

  app.post("/feedback/:id/comment", requireAuth, (req, res) => {
    try {
      addSubmitterComment(req.params.id, req.body.comment, req.session.user);
      setFlash(req, "success", "Comment added.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(`/feedback?id=${encodeURIComponent(req.params.id)}`);
  });

  app.post("/feedback/:id/support", requireAuth, (req, res) => {
    try {
      supportFeedback(req.params.id, req.session.user);
      setFlash(req, "success", "Feedback supported.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/feedback");
  });

  app.get("/feedback/:id/screenshot", requireAuth, (req, res) => {
    const entry = req.session.user?.isAdmin
      ? getFeedbackForAdmin(req.params.id)
      : getFeedbackForSubmitter(req.params.id, req.session.user.id);
    if (!entry?.screenshot?.path) {
      return res.status(404).render("error", {
        title: "Screenshot not found",
        message: "That feedback screenshot is not available."
      });
    }
    const screenshotPath = resolveFeedbackScreenshotPath(entry.screenshot.path, feedbackScreenshotDir);
    if (!screenshotPath || !fs.existsSync(screenshotPath)) {
      return res.status(404).render("error", {
        title: "Screenshot not found",
        message: "That feedback screenshot is no longer available."
      });
    }
    res.setHeader("Content-Type", entry.screenshot.mime || "image/png");
    res.setHeader("Cache-Control", "private, no-store");
    res.sendFile(screenshotPath);
  });

  app.get("/feedback/:id/attachments/:attachmentId", requireAuth, (req, res) => {
    const attachment = getFeedbackAttachment(
      req.params.id,
      req.params.attachmentId,
      req.session.user.id,
      Boolean(req.session.user?.isAdmin)
    );
    if (!attachment?.storage_path) {
      return res.status(404).render("error", {
        title: "Attachment not found",
        message: "That feedback attachment is not available."
      });
    }
    const attachmentPath = resolveFeedbackAttachmentPath(attachment.storage_path, feedbackAttachmentDir);
    if (!attachmentPath || !fs.existsSync(attachmentPath)) {
      return res.status(404).render("error", {
        title: "Attachment not found",
        message: "That feedback attachment is no longer available."
      });
    }
    res.download(
      attachmentPath,
      safeDownloadFilename(attachment.original_name, "attachment"),
      { headers: { "Cache-Control": "private, no-store", "X-Content-Type-Options": "nosniff" } }
    );
  });

  app.get("/health", (req, res) => {
    res.set("Cache-Control", "no-store");
    res.json({ ok: true, ts: Date.now() });
  });

  app.get("/commands", (req, res) => {
    const prefix = getSetting("command_prefix", "!");
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const usageMap = buildCommandUsageMap();
    const commands = [];
    const conflictMap = new Map();
    const enabledPlatforms = getEnabledPlatformIds();

    const addConflictEntries = (command) => {
      const triggers = command.conflictTriggers || [command.trigger];
      for (const trigger of triggers) {
        for (const platform of command.activePlatforms || command.platforms) {
          const subcommand = command.subcommand || "";
          const key = `${platform}:${trigger}:${subcommand}`;
          const entries = conflictMap.get(key) || [];
          if (!entries.some((entry) => entry.id === command.id)) {
            entries.push({
              id: command.id,
              name: command.name,
              origin: command.origin
            });
          }
          conflictMap.set(key, entries);
        }
      }
    };

    const addCommand = (command) => {
      command.description = String(command.description || "");
      command.count = usageMap.get(command.id) || 0;
      command.anchor = `cmd-${slugify(command.id)}`;
      command.link = `${baseUrl}/commands#${command.anchor}`;
      const subcommand = command.subcommand || "";
      command.search = [
        command.triggerDisplay,
        subcommand,
        command.name,
        command.description,
        command.preview?.text || "",
        command.origin,
        command.platforms.join(" ")
      ]
        .join(" ")
        .toLowerCase();
      command.sort = {
        trigger: subcommand ? `${command.trigger} ${subcommand}` : command.trigger,
        name: command.name.toLowerCase(),
        description: command.description.toLowerCase(),
        level: command.level.toLowerCase(),
        platform: command.platforms.join(" "),
        origin: command.origin.toLowerCase(),
        count: command.count
      };
      if (command.levelHelp) {
        command.levelHelp = command.levelHelp.toString();
      }
      commands.push(command);
      addConflictEntries(command);
    };

    const customCommands = db
      .prepare(
        "SELECT id, trigger, description, response, mode, language, platform, preview_text, preview_status, preview_error, preview_generated_at, preview_dynamic_segments, random_replies_json, rng_enabled, rng_min, rng_max, conditional_replies_json, conditional_fuzzy FROM custom_commands WHERE enabled = 1 ORDER BY trigger"
      )
      .all();
    const supportedPlatforms = getPlatformStatus()
      .filter((platform) => platform.supported)
      .map((platform) => platform.id);
    for (const row of customCommands) {
      const trigger = normalizeCommandTrigger(row.trigger);
      if (!trigger) {
        continue;
      }
      const platforms = normalizeCustomPlatforms(row.platform, supportedPlatforms);
      const activePlatforms = platforms.filter((platform) => enabledPlatforms.includes(platform));
      const description = truncateText(row.description || "", 500);
      const policyPresentation = commandPolicyPresentation(customCommandKey(row.id));
      addCommand({
        id: `custom:${trigger}`,
        trigger,
        triggerDisplay: `${prefix}${trigger}`,
        name: toTitleCase(trigger) || trigger,
        description,
        preview: buildCustomCommandListPreview(row),
        isCustom: true,
        ...policyPresentation,
        origin: "Custom",
        platforms,
        activePlatforms,
        platformLabels: buildPlatformLabels(platforms),
        conflictTriggers: [trigger]
      });
    }

    const topOptions = getTopCommandOptions();
    if (topOptions.length) {
      const topPlatforms = enabledPlatforms.slice();
      const topPlatformLabels = buildPlatformLabels(topPlatforms);
      const topUsage = buildUsage("top", "top <category>");
      addCommand({
        id: "top",
        trigger: "top",
        triggerDisplay: `${prefix}${topUsage}`,
        name: "Top",
        description: "Show leaderboard rankings.",
        level: "public",
        origin: "Core",
        platforms: topPlatforms,
        platformLabels: topPlatformLabels,
        conflictTriggers: ["top"]
      });
      for (const option of topOptions) {
        const subcommand = normalizeSubcommand(option.id);
        if (!subcommand) {
          continue;
        }
        const usage = buildUsage("top", `top ${subcommand}`);
        addCommand({
          id: `top:${subcommand}`,
          trigger: "top",
          subcommand,
          triggerDisplay: `${prefix}${usage}`,
          name: option.label || toTitleCase(subcommand) || subcommand,
          description:
            option.description ||
            `Show ${option.label || toTitleCase(subcommand) || subcommand} rankings.`,
          level: "public",
          origin: "Core",
          platforms: topPlatforms,
          platformLabels: topPlatformLabels,
          conflictTriggers: ["top"]
        });
      }
    }

    for (const registered of (commandRouter?.listCommands?.() || []).filter((command) => command.pluginId === "core" && command.id !== "top")) {
      const trigger = registered.triggers[0];
      if (!trigger) continue;
      const policyPresentation = commandPolicyPresentation(registered.key, registered.defaultPolicy);
      addCommand({
        id: registered.id,
        trigger,
        triggerDisplay: `${prefix}${trigger}${registered.id === "raid" ? " <channel|cancel>" : registered.id === "clip" ? " [name]" : ""}`,
        name: toTitleCase(registered.id),
        description: registered.description,
        ...policyPresentation,
        origin: "Core",
        platforms: registered.platforms,
        activePlatforms: registered.platforms.filter((platform) => enabledPlatforms.includes(platform)),
        platformLabels: buildPlatformLabels(registered.platforms),
        conflictTriggers: registered.triggers
      });
    }

    const plugins = getPlugins().filter((plugin) => plugin.enabled);
    for (const plugin of plugins) {
      const cmdsPath = path.join(plugin.path, "cmds.json");
      if (!fs.existsSync(cmdsPath)) {
        continue;
      }
      const manifest = readJsonSafe(cmdsPath);
      if (!manifest || !Array.isArray(manifest.commands)) {
        continue;
      }
      const pluginSettings = getPluginSettingsMap(plugin.id);
      const platformKeys = manifest.platformKeys || {};
      const platformFlags = {};
      for (const platform of enabledPlatforms) {
        platformFlags[platform] = platformKeys[platform]
          ? parseBooleanSetting(pluginSettings[platformKeys[platform]], true)
          : true;
      }
      const pluginName = manifest.pluginName || plugin.name || plugin.id;

      for (const command of manifest.commands) {
        if (!command || !command.trigger) {
          continue;
        }
        const enabled = command.enabledKey
          ? parseBooleanSetting(pluginSettings[command.enabledKey], true)
          : true;
        if (!enabled) {
          continue;
        }
        const override = command.triggerKey
          ? pluginSettings[command.triggerKey]
          : "";
        const trigger = normalizeCommandTrigger(override, command.trigger);
        if (!trigger) {
          continue;
        }
        const subcommand = normalizeSubcommand(command.subcommand);
        const usage = buildUsage(
          trigger,
          command.usage || (subcommand ? `${trigger} ${subcommand}` : trigger)
        );
        const platforms = (Array.isArray(command.platforms) && command.platforms.length
          ? command.platforms
          : enabledPlatforms
        ).filter((platform) => platformFlags[platform] && enabledPlatforms.includes(platform));
        if (!platforms.length) {
          continue;
        }
        const defaultTrigger = normalizeCommandTrigger(command.trigger);
        const useAliases =
          Array.isArray(command.aliases) &&
          command.aliases.length &&
          (!command.aliasesEnabledWhenDefault || trigger === defaultTrigger);
        const aliasTriggers = useAliases
          ? command.aliases
              .map((alias) => normalizeCommandTrigger(alias))
              .filter(Boolean)
          : [];
        const description = truncateText(command.description || "", 140);
        const registered = (commandRouter?.listCommands?.() || []).find((item) =>
          item.pluginId === plugin.id && item.triggers.includes(trigger)
        );
        const policyPresentation = registered
          ? commandPolicyPresentation(registered.key, registered.defaultPolicy)
          : { level: command.level || "public", levelHelp: command.levelHelp || "" };
        addCommand({
          id: `${plugin.id}:${command.id || trigger}`,
          trigger,
          subcommand,
          triggerDisplay: `${prefix}${usage}`,
          name: command.name || toTitleCase(trigger) || trigger,
          description,
          ...policyPresentation,
          origin: pluginName,
          platforms,
          platformLabels: buildPlatformLabels(platforms),
          conflictTriggers: [trigger, ...aliasTriggers]
        });
      }
    }

    commands.sort((a, b) =>
      a.triggerDisplay.localeCompare(b.triggerDisplay)
    );

    const conflicts = [];
    for (const [key, entries] of conflictMap.entries()) {
      if (entries.length < 2) {
        continue;
      }
      const [platform, trigger, subcommand] = key.split(":");
      const triggerLabel = subcommand ? `${trigger} ${subcommand}` : trigger;
      const sources = entries.map((entry) => {
        if (entry.origin === entry.name) {
          return entry.origin;
        }
        return `${entry.origin} (${entry.name})`;
      });
      conflicts.push({
        trigger: triggerLabel,
        triggerDisplay: `${prefix}${triggerLabel}`,
        platform,
        platformLabel: getPlatformLabel(platform),
        sourcesLabel: sources.join(", ")
      });
    }
    conflicts.sort((a, b) => {
      if (a.trigger === b.trigger) {
        return a.platform.localeCompare(b.platform);
      }
      return a.trigger.localeCompare(b.trigger);
    });
    const subcommandGroups = new Map();
    for (const command of commands) {
      if (!command.subcommand) {
        continue;
      }
      const group = subcommandGroups.get(command.trigger) || {
        root: null,
        subcommands: []
      };
      group.subcommands.push(command);
      subcommandGroups.set(command.trigger, group);
    }

    for (const command of commands) {
      if (command.subcommand) {
        continue;
      }
      const group = subcommandGroups.get(command.trigger);
      if (group && !group.root) {
        group.root = command;
      }
    }

    const buildRootFromSubcommands = (trigger, group) => {
      const platforms = Array.from(
        new Set(group.subcommands.flatMap((item) => item.platforms))
      );
      const origins = Array.from(
        new Set(group.subcommands.map((item) => item.origin))
      );
      const levels = Array.from(
        new Set(group.subcommands.map((item) => item.level))
      );
      const platformLabels = buildPlatformLabels(platforms);
      const name = toTitleCase(trigger) || trigger;
      const subcommandLabels = group.subcommands
        .map((item) => item.subcommand)
        .filter(Boolean);
      const description = subcommandLabels.length
        ? `Subcommands: ${subcommandLabels.join(", ")}`
        : "Subcommand group.";
      const origin = origins.length === 1 ? origins[0] : "Multiple";
      const level = levels.length === 1 ? levels[0] : "mixed";
      const count = group.subcommands.reduce(
        (total, item) => total + (item.count || 0),
        0
      );
      const id = `group:${trigger}`;
      const triggerDisplay = `${prefix}${trigger}`;
      const anchor = `cmd-${slugify(id)}`;
      const link = `${baseUrl}/commands#${anchor}`;
      const search = [
        triggerDisplay,
        name,
        description,
        origin,
        platforms.join(" "),
        subcommandLabels.join(" ")
      ]
        .join(" ")
        .trim();
      const sort = {
        trigger,
        name: name.toLowerCase(),
        description: description.toLowerCase(),
        level: level.toLowerCase(),
        platform: platforms.join(" "),
        origin: origin.toLowerCase(),
        count
      };
      return {
        id,
        groupKey: trigger,
        trigger,
        triggerDisplay,
        name,
        description,
        level,
        origin,
        platforms,
        platformLabels,
        count,
        anchor,
        link,
        search,
        sort
      };
    };

    const commandGroups = [];
    const processed = new Set();
    for (const command of commands) {
      const group = subcommandGroups.get(command.trigger);
      if (!group) {
        command.groupKey = command.id;
        commandGroups.push({ root: command, subcommands: [] });
        continue;
      }
      if (processed.has(command.trigger)) {
        continue;
      }
      const root = group.root || buildRootFromSubcommands(command.trigger, group);
      root.groupKey = root.groupKey || command.trigger;
      const subcommands = group.subcommands
        .slice()
        .sort((a, b) => a.triggerDisplay.localeCompare(b.triggerDisplay))
        .map((item) => ({ ...item, groupKey: root.groupKey }));
      if (subcommands.length) {
        const extraSearch = subcommands
          .map((item) => [item.subcommand, item.name].filter(Boolean).join(" "))
          .join(" ");
        root.search = `${root.search} ${extraSearch}`.trim();
      }
      commandGroups.push({ root, subcommands });
      processed.add(command.trigger);
    }

    res.render("commands", {
      title: "Commands",
      commandGroups,
      conflicts,
      isAdmin: Boolean(req.session.user?.isAdmin)
    });
  });

  app.get("/leaderboards", (req, res) => {
    res.render("leaderboards", {
      title: "Leaderboards",
      sections: getLeaderboardSections({ limit: 25 })
    });
  });

  app.get("/stats", requireAuth, (req, res) => {
    const payload = buildUserStatsPayload(req.session.user.id);
    res.render("stats", {
      title: "Your stats",
      stats: payload.stats,
      expression: payload.expression,
      pluginStats: payload.pluginStats,
      statsOwner: {
        username: req.session.user.username,
        isSelf: true
      },
      compare: null
    });
  });

  app.get("/stats/:username", (req, res) => {
    const username = (req.params.username || "").trim();
    if (!username) {
      return res.status(404).render("error", {
        title: "Not found",
        message: "User not found."
      });
    }
    const profile = db
      .prepare(
        "SELECT id, internal_username FROM user_profiles WHERE internal_username = ? LIMIT 1"
      )
      .get(username);
    if (!profile) {
      return res.status(404).render("error", {
        title: "Not found",
        message: "User not found."
      });
    }

    const payload = buildUserStatsPayload(profile.id);
    let compare = null;
    if (req.session.user && req.session.user.id !== profile.id) {
      const currentPayload = buildUserStatsPayload(req.session.user.id);
      compare = {
        leftLabel: req.session.user.username || "You",
        rightLabel: profile.internal_username,
        rows: buildCompareRows(currentPayload, payload)
      };
    }

    res.render("stats", {
      title: `${profile.internal_username}'s stats`,
      stats: payload.stats,
      expression: payload.expression,
      pluginStats: payload.pluginStats,
      statsOwner: {
        username: profile.internal_username,
        isSelf: req.session.user?.id === profile.id
      },
      compare
    });
  });

  app.get("/pages/:slug", (req, res) => {
    const page = db
      .prepare(
        "SELECT * FROM custom_pages WHERE slug = ? AND enabled = 1 LIMIT 1"
      )
      .get(req.params.slug);
    if (!page) {
      return res.status(404).render("error", {
        title: "Not found",
        message: "That page does not exist."
      });
    }
    if (!hasAccess(req.session.user, page.role)) {
      return res.status(403).render("error", {
        title: "Access denied",
        message: "You do not have access to that page."
      });
    }
    const format = normalizePageFormat(page.format);
    const pageData = {
      ...page,
      format,
      content_css: page.content_css || ""
    };
    const renderedContent =
      format === "markdown" ? renderMarkdown(pageData.content) : "";
    const pageSrcdoc =
      format === "html" ? buildCustomPageSrcdoc(pageData, res.locals.theme) : "";
    const safePageSrcdoc = pageSrcdoc.replace(/<\/script/gi, "<\\/script");
    res.render("custom-page", {
      title: page.title,
      page: pageData,
      renderedContent,
      pageSrcdoc: safePageSrcdoc
    });
  });

  app.get("/moderator", requireRole("mod"), (req, res) => {
    const now = Date.now();
    const totals = db
      .prepare(
        "SELECT user_id, SUM(CASE WHEN end_at IS NULL THEN ? - start_at ELSE end_at - start_at END) AS total_ms " +
          "FROM mod_role_periods GROUP BY user_id"
      )
      .all(now);
    const totalsMap = new Map(
      totals.map((row) => [row.user_id, Number(row.total_ms || 0)])
    );
    const users = listUsersWithIdentities()
      .filter((user) => totalsMap.has(user.id))
      .map((user) => {
        const identities = (user.identities || []).map((identity) => ({
          ...identity,
          label: getPlatformLabel(identity.provider) || identity.provider
        }));
        const aliases = identities
          .map(
            (identity) =>
              `${identity.label}: ${identity.display_name || identity.provider_user_id}`
          )
          .join(" | ");
        return {
          id: user.id,
          username: user.internal_username,
          identities,
          aliasText: aliases,
          totalMs: totalsMap.get(user.id) || 0
        };
      })
      .sort((a, b) => b.totalMs - a.totalMs);

    res.render("moderator", {
      title: "Mods List",
      mods: users,
      formatDuration
    });
  });

  app.get("/admin", requireRole("admin"), async (req, res) => {
    res.render("admin-dashboard", {
      title: "Admin dashboard",
      dashboardSections: await getAdminDashboardSections()
    });
  });

  app.get("/api/admin/dashboard-metrics", requireRole("admin"), (req, res) => {
    const plugins = getPlugins();
    const scope = parseDashboardScope(req.query.scope);
    const scopeMs = DASHBOARD_SCOPES[scope];
    const now = Date.now();
    const logs = listLogs({ sinceMs: now - scopeMs });
    const memory = process.memoryUsage();
    recordMemorySample(memory, now);
    const count = (table) => {
      try {
        return db.prepare(`SELECT COUNT(*) AS count FROM ${table}`).get().count;
      } catch {
        return 0;
      }
    };
    res.set("Cache-Control", "no-store");
    res.json({
      uptime_seconds: Math.round(process.uptime()),
      memory: {
        rss: memory.rss,
        heap_used: memory.heapUsed,
        heap_total: memory.heapTotal
      },
      plugins: {
        total: plugins.length,
        enabled: plugins.filter((plugin) => plugin.enabled).length
      },
      counts: {
        users: count("user_profiles"),
        commands: countVisibleCommands(),
        pages: count("custom_pages"),
        logs: count("logs")
      },
      scopes: Object.fromEntries(
        Object.entries(DASHBOARD_SCOPES).map(([id, duration]) => [id, { duration_ms: duration }])
      ),
      selected_scope: scope,
      memory_scopes: scopedMemorySamples(now),
      logs: {
        scope,
        scope_ms: scopeMs,
        total: logs.length,
        levels: countLogsByLevel(logs)
      },
      sampled_at: now
    });
  });

  app.get("/admin/settings", requireRole("admin"), (req, res) => {
    res.render("admin-settings", {
      title: "Settings",
      settings: getAllSettings(),
      platforms: getPlatformStatus(),
      localhostLoginAvailable: isLocalhostLoginAvailable(req),
      navIconItems: buildNavIconItems(req.session.user, navItems, req.path)
    });
  });

  app.post("/admin/settings", requireRole("admin"), (req, res) => {
    const customPlaceholderValidation = placeholders.validateCustomPlaceholders(customPlaceholdersFromBody(req.body));
    if (!customPlaceholderValidation.ok) {
      return sendEnhancedError(req, res, {
        message: customPlaceholderValidation.errors[0],
        fieldErrors: { custom_placeholders: customPlaceholderValidation.errors[0] },
        redirect: "/admin/settings"
      });
    }
    if (req.body.git_branch !== undefined) {
      const branch = String(req.body.git_branch || "").trim();
      try {
        if (branch !== "experimental") normalizeDeploymentBranch(branch);
      } catch (error) {
        return sendEnhancedError(req, res, {
          message: error.message,
          fieldErrors: { git_branch: error.message },
          redirect: "/admin/settings"
        });
      }
    }
    const fields = [
      "site_title",
      "command_prefix",
      "auto_update_enabled",
      "auto_update_interval_minutes",
      "git_remote",
      "git_branch"
    ];
    for (const field of fields) {
      if (req.body[field] !== undefined) {
        const value = req.body[field];
        if (field === "auto_update_enabled") {
          setSetting(field, value === "on");
        } else if (field === "auto_update_interval_minutes") {
          setSetting(field, Number(value));
        } else {
          setSetting(field, value.trim());
        }
      }
    }
    if (isLocalhostLoginAvailable(req)) {
      const localhostUsername = String(req.body.localhost_login_username || "").trim();
      if (localhostUsername) {
        setSetting("localhost_login_username", localhostUsername);
      }
      const localhostPassword = String(req.body.localhost_login_password || "");
      if (localhostPassword) {
        setSetting("localhost_login_password", localhostPassword);
      }
    }
    for (const field of ["homepage_link_buttons", "homepage_hero_entries"]) {
      if (req.body[field] === undefined) continue;
      const raw = String(req.body[field] || "").trim();
      if (!raw) {
        setSetting(field, []);
        continue;
      }
      try {
        const parsed = JSON.parse(raw);
        if (!Array.isArray(parsed)) throw new Error("Expected an array.");
        if (field === "homepage_hero_entries") {
          const heroErrors = validateHomepageHeroEntries(parsed);
          if (heroErrors.length) {
            const message = `Homepage hero cannot be saved yet. ${heroErrors.slice(0, 3).join(" ")}`;
            return sendEnhancedError(req, res, {
              message,
              fieldErrors: { homepage_hero_entries: message },
              redirect: "/admin/settings"
            });
          }
        }
        setSetting(field, parsed);
      } catch (error) {
        const message = `${field.replaceAll("_", " ")} JSON is invalid: ${error.message}`;
        return sendEnhancedError(req, res, { message, fieldErrors: { [field]: message }, redirect: "/admin/settings" });
      }
    }
    const platformStatus = getPlatformStatus();
    const nextPlatformValues = new Map();
    for (const platform of platformStatus) {
      nextPlatformValues.set(platform.id, req.body[platform.enabledKey] === "on");
    }
    const hasLoginPlatform = platformStatus.some(
      (platform) =>
        platform.supported &&
        platform.supportsLogin &&
        nextPlatformValues.get(platform.id)
    );
    if (!hasLoginPlatform && !isLocalhostLoginAvailable(req)) {
      return sendEnhancedError(req, res, {
        message: "At least one login platform must remain enabled.",
        fieldErrors: Object.fromEntries(platformStatus.filter((platform) => platform.supportsLogin).map((platform) => [platform.enabledKey, "Keep at least one login platform enabled."])),
        redirect: "/admin/settings"
      });
    }

    setSetting("custom_placeholders", customPlaceholderValidation.definitions);
    placeholders.registerCustomPlaceholders(customPlaceholderValidation.definitions);

    let restartNeeded = false;
    for (const platform of platformStatus) {
      const nextValue = nextPlatformValues.get(platform.id);
      const currentValue = isPlatformEnabled(platform.id);
      if (nextValue !== currentValue) {
        restartNeeded = true;
      }
      setSetting(platform.enabledKey, nextValue);
    }
    const message = restartNeeded ? "Settings saved. Lumi is restarting to apply platform changes." : "Settings saved.";
    if (wantsEnhancedResponse(req)) {
      sendEnhancedResult(res, { message, reloadRequired: restartNeeded });
    } else {
      setFlash(req, "success", restartNeeded ? "Settings saved. Restarting..." : "Settings saved.");
      res.redirect("/admin/settings");
    }
    if (restartNeeded) {
      requestRestart();
    }
  });

  app.post(
    "/admin/settings/nav-icons",
    requireRole("admin"),
    navIconSingle,
    (req, res) => {
      if (req.uploadError) {
        setFlash(req, "error", req.uploadError);
        return res.redirect("/admin/settings");
      }
      const itemId = (req.body.item_id || "").trim();
      if (!itemId) {
        cleanupUploadedFiles(req.file);
        setFlash(req, "error", "Missing navigation item.");
        return res.redirect("/admin/settings");
      }
      if (!req.file) {
        setFlash(req, "error", "Upload an SVG or PNG icon.");
        return res.redirect("/admin/settings");
      }
      const map = getSetting("nav_item_icons", {}) || {};
      const previous = map[itemId];
      map[itemId] = req.file.filename;
      setSetting("nav_item_icons", map);
      if (previous) {
        try {
          fs.rmSync(path.join(navIconDir, previous), { force: true });
        } catch {
          // ignore cleanup errors
        }
      }
      setFlash(req, "success", "Navigation icon updated.");
      res.redirect("/admin/settings");
    }
  );

  app.post("/admin/settings/nav-icons/reset", requireRole("admin"), (req, res) => {
    const itemId = (req.body.item_id || "").trim();
    if (!itemId) {
      setFlash(req, "error", "Missing navigation item.");
      return res.redirect("/admin/settings");
    }
    const map = getSetting("nav_item_icons", {}) || {};
    const previous = map[itemId];
    delete map[itemId];
    setSetting("nav_item_icons", map);
    if (previous) {
      try {
        fs.rmSync(path.join(navIconDir, previous), { force: true });
      } catch {
        // ignore cleanup errors
      }
    }
    setFlash(req, "success", "Navigation icon reset.");
    res.redirect("/admin/settings");
  });

  app.get("/admin/navigation", requireRole("admin"), (req, res) => {
    const availableItems = collectNavItems(req.session.user, navItems, req.path);
    const sortedItems = availableItems
      .slice()
      .sort((a, b) => {
        if (a.section === b.section) {
          return a.label.localeCompare(b.label);
        }
        return a.section.localeCompare(b.section);
      });
    const defaultStructure = buildDefaultNavStructure(sortedItems);
    const storedStructure = normalizeNavStructure(getSetting("nav_structure", null));
    const navStructure = storedStructure || {
      ...defaultStructure,
      enabled: false,
      includeUnassigned: true
    };
    const navSections = storedStructure?.sections?.length
      ? storedStructure.sections
      : defaultStructure.sections;
    res.render("admin-navigation", {
      title: "Navigation",
      navStructure,
      navSectionsJson: JSON.stringify(navSections, null, 2),
      navSectionsData: JSON.stringify(navSections),
      defaultSectionsJson: JSON.stringify(defaultStructure.sections, null, 2),
      navItems: sortedItems,
      navItemsJson: JSON.stringify(sortedItems),
      sectionIcons: NAV_SECTION_ICONS
    });
  });

  app.post("/admin/navigation", requireRole("admin"), (req, res) => {
    const enabled = req.body.nav_enabled === "on";
    const includeUnassigned = req.body.nav_include_unassigned === "on";
    const unassignedLabel = (req.body.nav_unassigned_label || "").trim();
    const unassignedIcon = (req.body.nav_unassigned_icon || "").trim();
    const unassignedId = (req.body.nav_unassigned_id || "").trim();
    const rawSections = (req.body.nav_sections || "").trim();
    let sections = [];
    if (rawSections) {
      try {
        sections = JSON.parse(rawSections);
      } catch {
        return sendEnhancedError(req, res, {
          message: "Navigation JSON is invalid.",
          fieldErrors: { nav_sections: "Enter a valid JSON array of navigation sections." },
          redirect: "/admin/navigation"
        });
      }
    }
    if (!Array.isArray(sections)) {
      return sendEnhancedError(req, res, {
        message: "Navigation JSON must be an array of sections.",
        fieldErrors: { nav_sections: "Use an array, for example: []." },
        redirect: "/admin/navigation"
      });
    }
    const navStructure = normalizeNavStructure({
      enabled,
      includeUnassigned,
      unassignedLabel,
      unassignedIcon,
      unassignedId,
      sections
    });
    if (!navStructure) {
      return sendEnhancedError(req, res, {
        message: "Navigation settings could not be saved.",
        fieldErrors: { nav_sections: "Check that every section has a unique ID, label, and items array." },
        redirect: "/admin/navigation"
      });
    }
    setSetting("nav_structure", navStructure);
    if (wantsEnhancedResponse(req)) {
      return sendEnhancedResult(res, {
        message: "Navigation saved without leaving the editor.",
        data: { navStructure }
      });
    }
    setFlash(req, "success", "Navigation updated.");
    res.redirect("/admin/navigation");
  });

  app.post("/admin/navigation/reset", requireRole("admin"), (req, res) => {
    setSetting("nav_structure", null);
    if (wantsEnhancedResponse(req)) {
      const availableItems = collectNavItems(req.session.user, navItems, req.path)
        .slice()
        .sort((a, b) => a.section === b.section ? a.label.localeCompare(b.label) : a.section.localeCompare(b.section));
      const defaultStructure = buildDefaultNavStructure(availableItems);
      return sendEnhancedResult(res, {
        message: "Navigation reset to Lumi defaults without reloading the page.",
        data: {
          navStructure: {
            ...defaultStructure,
            enabled: false,
            includeUnassigned: true
          }
        }
      });
    }
    setFlash(req, "success", "Navigation reset to default.");
    res.redirect("/admin/navigation");
  });

  app.get("/admin/discord-wizard", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("discord")) {
      setFlash(req, "error", "Discord is disabled in Platform Integration.");
      return res.redirect("/admin/settings");
    }
    const current = getDiscordSettings();
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const form = {
      ...current,
      discord_client_secret: "",
      discord_bot_token: "",
      discord_redirect_uri:
        current.discord_redirect_uri || `${baseUrl}/auth/discord/callback`
    };
    storeSnapshot(req, "discordWizardSnapshot", current);
    res.render("wizard-discord", {
      title: "Discord setup",
      form,
      checks: [],
      errors: [],
      actionBase: "/admin/discord-wizard",
      cancelPath: "/admin/settings"
    });
  });

  app.post("/admin/discord-wizard/verify", requireRole("admin"), async (req, res) => {
    if (!isPlatformEnabled("discord")) {
      setFlash(req, "error", "Discord is disabled in Platform Integration.");
      return res.redirect("/admin/settings");
    }
    const current = getDiscordSettings();
    const incoming = {
      discord_client_id: req.body.discord_client_id || "",
      discord_client_secret: req.body.discord_client_secret || "",
      discord_redirect_uri: req.body.discord_redirect_uri || "",
      discord_bot_token: req.body.discord_bot_token || "",
      discord_guild_id: req.body.discord_guild_id || "",
      discord_admin_role_id: req.body.discord_admin_role_id || "",
      discord_mod_role_id: req.body.discord_mod_role_id || ""
    };
    const merged = mergeSecrets(
      current,
      incoming,
      new Set(["discord_client_secret", "discord_bot_token"])
    );
    if (!merged.discord_redirect_uri) {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      merged.discord_redirect_uri = `${baseUrl}/auth/discord/callback`;
    }
    const result = await verifyDiscordSettings(merged);
    if (!result.ok) {
      res.render("wizard-discord", {
        title: "Discord setup",
        form: {
          ...incoming,
          discord_client_secret: "",
          discord_bot_token: "",
          discord_redirect_uri: merged.discord_redirect_uri
        },
        checks: result.checks,
        errors: result.errors,
        actionBase: "/admin/discord-wizard",
        cancelPath: "/admin/settings"
      });
      return;
    }
    saveSettingsMap(merged);
    delete req.session.discordWizardSnapshot;
    setFlash(req, "success", "Discord setup saved.");
    res.redirect("/admin/settings");
  });

  app.post("/admin/discord-wizard/cancel", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("discord")) {
      return res.redirect("/admin/settings");
    }
    restoreSnapshot(req, "discordWizardSnapshot");
    setFlash(req, "info", "Discord setup canceled.");
    res.redirect("/admin/settings");
  });

  app.get("/admin/twitch-wizard", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      setFlash(req, "error", "Twitch is disabled in Platform Integration.");
      return res.redirect("/admin/settings");
    }
    const current = getTwitchSettings();
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const form = {
      ...current,
      twitch_client_secret: "",
      twitch_bot_oauth: "",
      twitch_redirect_uri:
        current.twitch_redirect_uri || `${baseUrl}/auth/twitch/callback`
    };
    storeSnapshot(req, "twitchWizardSnapshot", current);
    res.render("wizard-twitch", {
      title: "Twitch setup",
      form,
      checks: [],
      errors: [],
      actionBase: "/admin/twitch-wizard",
      cancelPath: "/admin/settings"
    });
  });

  app.post("/admin/twitch-wizard/verify", requireRole("admin"), async (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      setFlash(req, "error", "Twitch is disabled in Platform Integration.");
      return res.redirect("/admin/settings");
    }
    const current = getTwitchSettings();
    const incoming = {
      twitch_client_id: req.body.twitch_client_id || "",
      twitch_client_secret: req.body.twitch_client_secret || "",
      twitch_redirect_uri: req.body.twitch_redirect_uri || "",
      twitch_bot_username: req.body.twitch_bot_username || "",
      twitch_bot_oauth: req.body.twitch_bot_oauth || "",
      twitch_channels: req.body.twitch_channels || ""
    };
    const merged = mergeSecrets(
      current,
      incoming,
      new Set(["twitch_client_secret", "twitch_bot_oauth"])
    );
    if (!merged.twitch_redirect_uri) {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      merged.twitch_redirect_uri = `${baseUrl}/auth/twitch/callback`;
    }
    const result = await verifyTwitchSettings(merged);
    if (!result.ok) {
      res.render("wizard-twitch", {
        title: "Twitch setup",
        form: {
          ...incoming,
          twitch_client_secret: "",
          twitch_bot_oauth: "",
          twitch_redirect_uri: merged.twitch_redirect_uri
        },
        checks: result.checks,
        errors: result.errors,
        actionBase: "/admin/twitch-wizard",
        cancelPath: "/admin/settings"
      });
      return;
    }
    saveSettingsMap(merged);
    delete req.session.twitchWizardSnapshot;
    setFlash(req, "success", "Twitch setup saved.");
    res.redirect("/admin/settings");
  });

  app.post("/admin/twitch-wizard/cancel", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("twitch")) {
      return res.redirect("/admin/settings");
    }
    restoreSnapshot(req, "twitchWizardSnapshot");
    setFlash(req, "info", "Twitch setup canceled.");
    res.redirect("/admin/settings");
  });

  app.get("/admin/youtube-wizard", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      setFlash(req, "error", "YouTube is disabled in Platform Integration.");
      return res.redirect("/admin/settings");
    }
    const current = getYouTubeSettings();
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const form = {
      ...current,
      youtube_client_secret: "",
      youtube_redirect_uri:
        current.youtube_redirect_uri || `${baseUrl}/auth/youtube/callback`
    };
    const snapshot = {
      ...current,
      youtube_bot_refresh_token: getSetting("youtube_bot_refresh_token", ""),
      youtube_bot_channel_id: getSetting("youtube_bot_channel_id", "")
    };
    storeSnapshot(req, "youtubeWizardSnapshot", snapshot);
    res.render("wizard-youtube", {
      title: "YouTube setup",
      form,
      checks: [],
      errors: [],
      actionBase: "/admin/youtube-wizard",
      cancelPath: "/admin/settings",
      connectPath: "/admin/youtube-wizard/connect",
      botConnected: Boolean(getSetting("youtube_bot_refresh_token", "")),
      botChannelId: getSetting("youtube_bot_channel_id", ""),
      botChannelName: getYouTubeClient()?.channelName || null
    });
  });

  app.post("/admin/youtube-wizard/connect", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      setFlash(req, "error", "YouTube is disabled in Platform Integration.");
      return res.redirect("/admin/settings");
    }
    const baseUrl = `${req.protocol}://${req.get("host")}`;
    const clientId = (req.body.youtube_client_id || "").trim();
    const clientSecret = (req.body.youtube_client_secret || "").trim();
    const redirectUri =
      (req.body.youtube_redirect_uri || "").trim() ||
      `${baseUrl}/auth/youtube/callback`;
    if (!clientId || !clientSecret) {
      setFlash(req, "error", "Client ID and Client Secret are required.");
      return res.redirect("/admin/youtube-wizard");
    }
    setSetting("youtube_client_id", clientId);
    setSetting("youtube_client_secret", clientSecret);
    setSetting("youtube_redirect_uri", redirectUri);
    const state = crypto.randomBytes(16).toString("hex");
    req.session.youtubeBotState = state;
    req.session.youtubeBotReturnTo = "/admin/youtube-wizard";
    const url = buildYouTubeAuthUrl(state, redirectUri, { prompt: "consent" });
    res.redirect(url);
  });

  app.post("/admin/youtube-wizard/verify", requireRole("admin"), async (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      setFlash(req, "error", "YouTube is disabled in Platform Integration.");
      return res.redirect("/admin/settings");
    }
    const current = getYouTubeSettings();
    const incoming = {
      youtube_client_id: req.body.youtube_client_id || "",
      youtube_client_secret: req.body.youtube_client_secret || "",
      youtube_redirect_uri: req.body.youtube_redirect_uri || ""
    };
    const merged = mergeSecrets(
      current,
      incoming,
      new Set(["youtube_client_secret"])
    );
    if (!merged.youtube_redirect_uri) {
      const baseUrl = `${req.protocol}://${req.get("host")}`;
      merged.youtube_redirect_uri = `${baseUrl}/auth/youtube/callback`;
    }
    const result = await verifyYouTubeSettings({
      ...merged,
      youtube_bot_refresh_token: getSetting("youtube_bot_refresh_token", "")
    });
    if (!result.ok) {
      res.render("wizard-youtube", {
        title: "YouTube setup",
        form: {
          ...incoming,
          youtube_client_secret: "",
          youtube_redirect_uri: merged.youtube_redirect_uri
        },
        checks: result.checks,
        errors: result.errors,
        actionBase: "/admin/youtube-wizard",
        cancelPath: "/admin/settings",
        connectPath: "/admin/youtube-wizard/connect",
        botConnected: Boolean(getSetting("youtube_bot_refresh_token", "")),
        botChannelId: getSetting("youtube_bot_channel_id", ""),
        botChannelName: getYouTubeClient()?.channelName || null
      });
      return;
    }
    if (result.channel?.id) {
      merged.youtube_bot_channel_id = result.channel.id;
    }
    saveSettingsMap(merged);
    delete req.session.youtubeWizardSnapshot;
    setFlash(req, "success", "YouTube setup saved.");
    res.redirect("/admin/settings");
  });

  app.post("/admin/youtube-wizard/cancel", requireRole("admin"), (req, res) => {
    if (!isPlatformEnabled("youtube")) {
      return res.redirect("/admin/settings");
    }
    restoreSnapshot(req, "youtubeWizardSnapshot");
    setFlash(req, "info", "YouTube setup canceled.");
    res.redirect("/admin/settings");
  });

  app.get("/admin/theming", requireRole("admin"), (req, res) => {
    const activeTheme = getActiveTheme();
    const requestedEdit = String(req.query.edit || "");
    const editingTheme = requestedEdit
      ? getThemeById(requestedEdit)
      : activeTheme.builtin
        ? null
        : activeTheme;
    const editingBaseTheme = editingTheme && !editingTheme.builtin
      ? getThemeById(editingTheme.baseThemeId)
      : null;
    res.render("admin-theme", {
      title: "Theming",
      theme: activeTheme,
      activeTheme,
      themes: listThemes(),
      editingTheme: editingTheme && !editingTheme.builtin ? editingTheme : null,
      editingBaseTheme,
      fontStacks: FONT_STACKS
    });
  });

  app.post("/admin/theming/select", requireRole("admin"), (req, res) => {
    try {
      const theme = setActiveTheme(String(req.body.theme_id || ""));
      setFlash(req, "success", `${theme.name} is now active.`);
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect("/admin/theming");
  });

  app.post("/admin/theming/duplicate", requireRole("admin"), (req, res) => {
    try {
      const theme = duplicateTheme(req.body.theme_id, req.body.name);
      setFlash(req, "success", `${theme.name} created. You can edit it below.`);
      return res.redirect(`/admin/theming?edit=${encodeURIComponent(theme.id)}#theme-editor`);
    } catch (error) {
      setFlash(req, "error", error.message);
      return res.redirect("/admin/theming");
    }
  });

  app.post("/admin/theming/custom/:id/save", requireRole("admin"), (req, res) => {
    const themeId = `custom:${req.params.id}`;
    try {
      const current = getThemeById(themeId);
      if (!current) throw new Error("Theme not found.");
      const theme = saveCustomTheme(themeId, valuesFromRequest(req.body, current));
      const applied = req.body.apply === "on";
      if (applied) setActiveTheme(theme.id);
      const message = applied ? `${theme.name} saved and applied.` : `${theme.name} saved.`;
      if (wantsEnhancedResponse(req)) {
        return sendEnhancedResult(res, {
          message,
          data: { theme, applied }
        });
      }
      setFlash(
        req,
        "success",
        message
      );
    } catch (error) {
      const detail = error.validationErrors?.join(" ") || error.message;
      if (wantsEnhancedResponse(req)) {
        return sendEnhancedError(req, res, {
          message: detail,
          redirect: `/admin/theming?edit=${encodeURIComponent(themeId)}#theme-editor`
        });
      }
      setFlash(req, "error", detail);
    }
    res.redirect(`/admin/theming?edit=${encodeURIComponent(themeId)}#theme-editor`);
  });

  app.post("/admin/theming/custom/:id/rename", requireRole("admin"), (req, res) => {
    const themeId = `custom:${req.params.id}`;
    try {
      const theme = renameCustomTheme(themeId, req.body.name);
      setFlash(req, "success", `Theme renamed to ${theme.name}.`);
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(`/admin/theming?edit=${encodeURIComponent(themeId)}`);
  });

  app.post("/admin/theming/custom/:id/delete", requireRole("admin"), (req, res) => {
    try {
      deleteCustomTheme(`custom:${req.params.id}`);
      setFlash(req, "success", "Custom theme deleted.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect("/admin/theming");
  });

  app.post("/admin/theming", requireRole("admin"), (req, res) => {
    let createdTarget = null;
    try {
      let target = getActiveTheme();
      if (target.builtin) {
        target = duplicateTheme(target.id, "Legacy Custom");
        createdTarget = target.id;
      }
      const values = JSON.parse(JSON.stringify(target));
      const legacyUpdates = [];
      const legacyMap = {
        theme_light_bg_1: ["light", "bg1"],
        theme_light_bg_2: ["light", "bg2"],
        theme_light_bg_3: ["light", "bg3"],
        theme_light_text: ["light", "text"],
        theme_light_text_muted: ["light", "muted"],
        theme_light_accent: ["light", "accent"],
        theme_light_accent_alt: ["light", "accentAlt"],
        theme_light_danger: ["light", "danger"],
        theme_light_surface: ["light", "surface"],
        theme_light_surface_2: ["light", "surface2"],
        theme_light_surface_3: ["light", "surface3"],
        theme_light_border: ["light", "border"],
        theme_dark_bg_1: ["dark", "bg1"],
        theme_dark_bg_2: ["dark", "bg2"],
        theme_dark_bg_3: ["dark", "bg3"],
        theme_dark_text: ["dark", "text"],
        theme_dark_text_muted: ["dark", "muted"],
        theme_dark_accent: ["dark", "accent"],
        theme_dark_accent_alt: ["dark", "accentAlt"],
        theme_dark_danger: ["dark", "danger"],
        theme_dark_surface: ["dark", "surface"],
        theme_dark_surface_2: ["dark", "surface2"],
        theme_dark_surface_3: ["dark", "surface3"],
        theme_dark_border: ["dark", "border"],
        theme_role_public: ["role", "public"],
        theme_role_mod: ["role", "mod"],
        theme_role_admin: ["role", "admin"]
      };
      for (const [field, [group, key]] of Object.entries(legacyMap)) {
        if (req.body[field] === undefined) continue;
        values[group][key] = String(req.body[field]).trim();
        legacyUpdates.push([field, values[group][key]]);
      }
      saveCustomTheme(target.id, values);
      for (const [field, value] of legacyUpdates) setSetting(field, value);
      setActiveTheme(target.id);
      setFlash(req, "success", "Theme updated.");
    } catch (error) {
      if (createdTarget) deleteCustomTheme(createdTarget);
      setFlash(req, "error", error.message);
    }
    res.redirect("/admin/theming");
  });

  const renderDiagnosticsAdmin = (req, res, values = {}) => {
    const diagnosticsBaseUrl = `${diagnosticsRequestProtocol(req)}://${req.get("host")}`;
    res.set("Cache-Control", "no-store");
    res.render("admin-diagnostics", {
      title: "Production diagnostics",
      diagnosticsAccess: diagnosticsAccessStatus(),
      diagnosticAudit: recentDiagnosticAudit(),
      issuedKey: null,
      diagnosticResult: null,
      diagnosticError: null,
      selectedCheck: "system_health",
      diagnosticsBaseUrl,
      diagnosticsEndpointUrl: `${diagnosticsBaseUrl}/api/diagnostics/v1/run`,
      ...values
    });
  };

  app.get("/admin/diagnostics", requireRole("admin"), (req, res) => {
    renderDiagnosticsAdmin(req, res);
  });

  app.post("/admin/diagnostics/run", requireRole("admin"), (req, res) => {
    const requestId = crypto.randomUUID();
    const check = String(req.body.check || "").trim();
    const startedAt = Date.now();
    try {
      const diagnosticResult = runDiagnosticCheck(check);
      auditDiagnosticRequest({
        request_id: requestId,
        check,
        ok: true,
        fingerprint: `admin:${req.session.user.id}`,
        duration_ms: Date.now() - startedAt
      });
      renderDiagnosticsAdmin(req, res, { diagnosticResult, selectedCheck: check });
    } catch (error) {
      auditDiagnosticRequest({
        request_id: requestId,
        check,
        ok: false,
        fingerprint: `admin:${req.session.user.id}`,
        reason: error.message,
        duration_ms: Date.now() - startedAt
      });
      renderDiagnosticsAdmin(req, res, { diagnosticError: error.message, selectedCheck: check });
    }
  });

  app.post("/admin/diagnostics/access/renew", requireRole("admin"), (req, res) => {
    const issuedKey = issueDiagnosticsAccessKey();
    renderDiagnosticsAdmin(req, res, { issuedKey });
  });

  app.post("/admin/diagnostics/access/revoke", requireRole("admin"), (req, res) => {
    revokeDiagnosticsAccess();
    setFlash(req, "success", "Production diagnostics access revoked.");
    res.redirect("/admin/diagnostics");
  });

  app.get("/admin/logs", requireRole("admin"), (req, res) => {
    const range = parseLogRange(req.query.range);
    const limit = parseLogLimit(req.query.limit);
    const levelValue = normalizeLogLevel(req.query.level) || "all";
    const sourceValue = normalizeLogFacet(req.query.source) || "all";
    const categoryValue = normalizeLogFacet(req.query.category) || "all";
    const search = parseLogSearch(req.query.q);
    const levels = levelValue === "all" ? [] : [levelValue];
    const sinceMs = range.rangeMs ? Date.now() - range.rangeMs : null;
    const query = {
      limit: limit.limit,
      sinceMs,
      levels,
      sources: sourceValue === "all" ? [] : [sourceValue],
      categories: categoryValue === "all" ? [] : [categoryValue],
      search
    };
    const logs = listLogs(query);
    res.render("admin-logs", {
      title: "Logs",
      logs,
      logSummary: summarizeLogs(query),
      logFacets: listLogFacets({ sinceMs }),
      logRetention: {
        maxAgeDays: getSetting("log_retention_days", DEFAULT_MAX_AGE_DAYS),
        maxEntries: getSetting("log_retention_max_entries", DEFAULT_MAX_ENTRIES)
      },
      logFilters: {
        range: range.rangeValue,
        level: levelValue,
        limit: limit.limitValue,
        source: sourceValue,
        category: categoryValue,
        search
      }
    });
  });

  app.post("/admin/logs/retention", requireRole("admin"), (req, res) => {
    const cleanup = cleanupLogs({
      maxAgeDays: req.body.max_age_days,
      maxEntries: req.body.max_entries
    });
    setSetting("log_retention_days", cleanup.maxAgeDays);
    setSetting("log_retention_max_entries", cleanup.maxEntries);
    webLog.info("Log retention updated", {
      max_age_days: cleanup.maxAgeDays,
      max_entries: cleanup.maxEntries,
      removed: cleanup.removed,
      user_id: req.session.user.id
    }, { category: "audit", event: "log_retention_updated" });
    setFlash(req, "success", cleanup.removed
      ? `Log storage updated and ${cleanup.removed} old entr${cleanup.removed === 1 ? "y was" : "ies were"} removed.`
      : "Log storage settings updated.");
    res.redirect("/admin/logs");
  });

  app.get("/admin/logs/download", requireRole("admin"), (req, res) => {
    const range = parseLogRange(req.query.range);
    const limit = parseLogLimit(req.query.limit, { allowAll: true });
    const levels = parseLogLevels(req.query.level);
    const source = normalizeLogFacet(req.query.source);
    const category = normalizeLogFacet(req.query.category);
    const search = parseLogSearch(req.query.q);
    const sinceMs = range.rangeMs ? Date.now() - range.rangeMs : null;
    const logs = listLogs({
      limit: limit.limit,
      sinceMs,
      levels,
      sources: source && source !== "all" ? [source] : [],
      categories: category && category !== "all" ? [category] : [],
      search
    });
    const stamp = new Date().toISOString().replace(/[:.]/g, "-");
    const format = req.query.format === "jsonl" ? "jsonl" : "txt";
    res.setHeader(
      "Content-Disposition",
      `attachment; filename="lumi-logs-${stamp}.${format}"`
    );
    res.setHeader("Content-Type", format === "jsonl" ? "application/x-ndjson; charset=utf-8" : "text/plain; charset=utf-8");
    if (format === "jsonl") {
      return res.send(logs.map((entry) => JSON.stringify(entry)).join("\n") + (logs.length ? "\n" : ""));
    }
    const lines = logs.map((log) => {
      const timestamp = new Date(log.created_at).toISOString();
      const scope = [log.source, log.category, log.event].filter(Boolean).join(" / ");
      const request = log.request_id ? ` request=${log.request_id}` : "";
      const header = `${timestamp} [${log.level.toUpperCase()}] [${scope}]${request} ${log.message}`;
      if (log.details) {
        return `${header}\n${log.details}\n`;
      }
      return `${header}\n`;
    });
    res.send(lines.join("\n"));
  });

  app.get("/admin/feedback", requireRole("admin"), (req, res) => {
    res.render("admin-feedback", {
      title: "Feedback review",
      feedbackItems: listFeedbackForAdmin(req.query),
      filters: {
        status: req.query.status || "",
        category: req.query.category || "",
        severity: req.query.severity || "",
        scope: req.query.scope || "",
        area: req.query.area || "",
        route: req.query.route || "",
        plugin: req.query.plugin || "",
        target: req.query.target || "",
        submitter: req.query.submitter || "",
        date_from: req.query.date_from || "",
        date_to: req.query.date_to || "",
        needs_action: req.query.needs_action || "",
        sort: req.query.sort || "last_activity"
      },
      feedbackOptions: feedbackOptions(),
      feedbackExportAiAvailable: isFeedbackExportAiAvailable()
    });
  });

  app.post("/admin/feedback/export", requireRole("admin"), async (req, res) => {
    try {
      const request = normalizeFeedbackExportRequest(req.body);
      const exportPayload = buildFeedbackJobExport({
        ids: request.ids,
        filters: request.filters,
        all: request.all,
        tokenLimit: request.tokenLimit
      });
      const payload = await maybeAddAiFeedbackExportSummary(exportPayload, req, request.useAi);
      res.json({ ok: true, export: payload });
    } catch (error) {
      res.status(400).json({ ok: false, error: error.message });
    }
  });

  app.post("/admin/feedback/:id/export", requireRole("admin"), async (req, res) => {
    try {
      const request = normalizeFeedbackExportRequest({ ...req.body, ids: req.params.id });
      const exportPayload = buildFeedbackJobExport({
        ids: request.ids,
        all: false,
        tokenLimit: request.tokenLimit
      });
      const payload = await maybeAddAiFeedbackExportSummary(exportPayload, req, request.useAi);
      res.json({ ok: true, export: payload });
    } catch (error) {
      res.status(400).json({ ok: false, error: error.message });
    }
  });

  app.post("/admin/feedback/:id/create-okf-correction", requireRole("admin"), (req, res) => {
    try {
      const feedback = getFeedbackForAdmin(req.params.id);
      const saveCorrection = global.lumiFrameworks?.okf?.saveCorrection;
      if (typeof saveCorrection !== "function") {
        throw new Error("Install and enable the OKF Knowledge plugin before creating an OKF correction.");
      }
      const correction = saveCorrection(buildFeedbackCorrectionPayload(feedback, req.body), req.session.user);
      if (!correction) {
        throw new Error("Correction OKF file could not be created.");
      }
      const linkedCorrection = correction.path || `knowledge/corrections/${req.params.id}.md`;
      adminUpdateFeedback(req.params.id, {
        ...req.body,
        linked_correction: linkedCorrection,
        work_note: `Created OKF correction: ${linkedCorrection}`,
        status_note: req.body.status_note || `Created OKF correction: ${linkedCorrection}`
      }, req.session.user);
      setFlash(req, "success", `Correction OKF created at ${linkedCorrection}.`);
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/admin/feedback");
  });

  app.post("/admin/feedback/:id/merge", requireRole("admin"), (req, res) => {
    try {
      const result = mergeFeedback(req.params.id, req.body.target_feedback_id, req.body, req.session.user);
      setFlash(req, "success", `Feedback merged into “${result.target.summary}”. Both reports and their history were preserved.`);
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/admin/feedback");
  });

  app.post("/admin/feedback/:id/unmerge", requireRole("admin"), (req, res) => {
    try {
      unmergeFeedback(req.params.id, req.body, req.session.user);
      setFlash(req, "success", "Feedback merge undone and the report returned to review.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/admin/feedback");
  });

  app.post("/admin/feedback/:id", requireRole("admin"), (req, res) => {
    try {
      const body = { ...req.body };
      if (body.review_action === "finalize") {
        body.status = "closed";
        body.status_note = body.status_note || "Finalized and closed.";
      } else if (body.review_action === "reopen") {
        body.status = "reviewed";
        body.status_note = body.status_note || "Reopened for review.";
      }
      adminUpdateFeedback(req.params.id, body, req.session.user);
      setFlash(req, "success", body.review_action === "finalize"
        ? "Feedback finalized and closed."
        : body.review_action === "reopen"
          ? "Feedback reopened."
          : "Feedback updated.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/admin/feedback");
  });

  app.post("/admin/feedback/:id/finalize", requireRole("admin"), (req, res) => {
    try {
      adminUpdateFeedback(req.params.id, {
        ...req.body,
        status: "closed",
        status_note: req.body.status_note || "Finalized and closed."
      }, req.session.user);
      setFlash(req, "success", "Feedback finalized and closed.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/admin/feedback");
  });

  app.post("/admin/feedback/:id/reopen", requireRole("admin"), (req, res) => {
    try {
      adminUpdateFeedback(req.params.id, {
        ...req.body,
        status: "reviewed",
        status_note: req.body.status_note || "Reopened for review."
      }, req.session.user);
      setFlash(req, "success", "Feedback reopened.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/admin/feedback");
  });

  app.post("/admin/feedback/:id/delete", requireRole("admin"), (req, res) => {
    try {
      deleteFeedback(req.params.id, {
        deleteScreenshot(relativePath) {
          const screenshotPath = resolveFeedbackScreenshotPath(relativePath, feedbackScreenshotDir);
          if (screenshotPath) {
            fs.rmSync(screenshotPath, { force: true });
          }
        },
        deleteAttachment(relativePath) {
          const attachmentPath = resolveFeedbackAttachmentPath(relativePath, feedbackAttachmentDir);
          if (attachmentPath) {
            fs.rmSync(attachmentPath, { force: true });
          }
        }
      });
      setFlash(req, "success", "Feedback permanently deleted.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect("/admin/feedback");
  });

  app.post("/admin/feedback/:id/cleanup", requireRole("admin"), (req, res) => {
    try {
      cleanupFeedback(req.params.id, req.body, req.session.user, {
        deleteScreenshot(relativePath) {
          const screenshotPath = resolveFeedbackScreenshotPath(relativePath, feedbackScreenshotDir);
          if (screenshotPath) {
            fs.rmSync(screenshotPath, { force: true });
          }
        },
        deleteAttachment(relativePath) {
          const attachmentPath = resolveFeedbackAttachmentPath(relativePath, feedbackAttachmentDir);
          if (attachmentPath) {
            fs.rmSync(attachmentPath, { force: true });
          }
        }
      });
      setFlash(req, "success", "Feedback data cleaned.");
    } catch (error) {
      setFlash(req, "error", error.message);
    }
    res.redirect(req.get("referer") || "/admin/feedback");
  });

  app.get("/admin/privileges", requireRole("admin"), async (req, res) => {
    const discord = await buildDiscordPrivileges(discordClient);
    const twitch = await buildTwitchPrivileges();
    res.render("admin-privileges", {
      title: "Privileges",
      discord,
      twitch
    });
  });

  app.get("/admin/commands", requireRole("mod"), (req, res) => {
    const platformStatus = getPlatformStatus().filter((platform) => platform.supported);
    const availablePlatforms = platformStatus.map((platform) => platform.id);
    const commands = db
      .prepare("SELECT * FROM custom_commands ORDER BY trigger")
      .all()
      .map((command) => ({
        ...command,
        platforms: normalizeCustomPlatforms(command.platform, availablePlatforms),
        preview: buildCommandPreviewPresentation(command),
        random: buildRandomCommandPresentation(command),
        conditional: buildConditionalCommandPresentation(command)
      }));
    res.render("admin-commands", {
      title: "Custom commands",
      commands,
      isAdmin: Boolean(req.session.user?.isAdmin),
      platforms: platformStatus.map((platform) => ({
        id: platform.id,
        label: platform.label,
        enabled: platform.enabled
      }))
    });
  });

  app.get("/admin/command-policies", requireRole("admin"), (req, res) => {
    const pluginNames = new Map(getPlugins().map((plugin) => [plugin.id, plugin.name || plugin.id]));
    const allGroups = listCommandGroups();
    const defaultGroup = allGroups.find((group) => group.is_default) || null;
    const groups = allGroups.filter((group) => !group.is_default);
    const premade = (commandRouter?.listCommands?.() || []).map((command) => ({
      key: command.key,
      label: `!${command.triggers[0] || command.id}`,
      description: command.description || "No description provided.",
      origin: command.pluginId === "core" ? "Built-in command" : `${pluginNames.get(command.pluginId) || command.pluginId} plugin`,
      defaultPolicy: command.defaultPolicy || {},
      platforms: command.platforms || []
    }));
    const custom = db.prepare("SELECT id, trigger, description, platform FROM custom_commands ORDER BY trigger").all().map((command) => ({
      key: customCommandKey(command.id),
      label: `!${command.trigger}`,
      description: command.description || "No description provided.",
      origin: "Custom command",
      defaultPolicy: {},
      platforms: normalizePlatformSelection(command.platform, getEnabledPlatformIds())
    }));
    const commands = [...premade, ...custom]
      .filter((command, index, all) => all.findIndex((item) => item.key === command.key) === index)
      .sort((left, right) => left.label.localeCompare(right.label))
      .map((command) => {
        const stored = getCommandPolicy(command.key);
        const effective = commandPolicyEffectivePresentation(command.key, command.defaultPolicy);
        return {
          ...command,
          ...stored,
          effective,
          searchText: [command.label, command.origin, command.description, ...stored.groups.map((group) => group.name)].join(" ").toLowerCase(),
          settingTokens: [
            effective.flags.rate && "rate",
            effective.flags.stream && "stream",
            effective.flags.access && "access",
            effective.flags.cost && "cost",
            effective.flags.groups && "groups",
            Object.keys(stored.policy).length && "overrides"
          ].filter(Boolean)
        };
      });
    res.render("admin-command-policies", {
      title: "Command access and limits",
      commands,
      groups,
      defaultGroup
    });
  });

  app.post("/admin/command-policies/groups", requireRole("admin"), (req, res) => {
    try {
      createCommandGroup({
        name: req.body.name,
        description: req.body.description,
        policy: commandPolicyFromBody(req.body, { allowInherit: false })
      });
      setFlash(req, "success", "Command group created.");
    } catch (error) {
      setFlash(req, "error", error?.message || "The command group could not be created.");
    }
    res.redirect("/admin/command-policies");
  });

  app.post("/admin/command-policies/groups/:id", requireRole("admin"), (req, res) => {
    try {
      const existing = listCommandGroups().find((group) => group.id === req.params.id);
      if (!existing) throw new Error("That command group no longer exists.");
      updateCommandGroup(req.params.id, {
        name: req.body.name,
        description: req.body.description,
        policy: commandPolicyFromBody(req.body, { allowInherit: Boolean(existing.is_default) })
      });
      const group = listCommandGroups().find((item) => item.id === req.params.id);
      if (wantsEnhancedResponse(req)) {
        return sendEnhancedResult(res, {
          message: "Command group updated.",
          data: { group }
        });
      }
      setFlash(req, "success", "Command group updated.");
    } catch (error) {
      if (wantsEnhancedResponse(req)) {
        return sendEnhancedError(req, res, {
          message: error?.message || "The command group could not be updated.",
          fieldErrors: !String(req.body.name || "").trim() ? { name: "Enter a group name." } : {},
          redirect: "/admin/command-policies"
        });
      }
      setFlash(req, "error", error?.message || "The command group could not be updated.");
    }
    res.redirect("/admin/command-policies");
  });

  app.post("/admin/command-policies/groups/:id/delete", requireRole("admin"), (req, res) => {
    try {
      deleteCommandGroup(req.params.id);
      setFlash(req, "success", "Command group deleted. Its commands keep their direct settings.");
    } catch (error) {
      setFlash(req, "error", error?.message || "The command group could not be deleted.");
    }
    res.redirect("/admin/command-policies");
  });

  app.post("/admin/command-policies/commands", requireRole("admin"), (req, res) => {
    const knownKeys = new Set([
      ...(commandRouter?.listCommands?.() || []).map((command) => command.key),
      ...db.prepare("SELECT id FROM custom_commands").all().map((command) => customCommandKey(command.id))
    ]);
    const validGroups = new Set(listCommandGroups().filter((group) => !group.is_default).map((group) => group.id));
    const count = Math.min(2000, Math.max(0, Number(req.body.command_count) || 0));
    const updates = [];
    for (let index = 0; index < count; index += 1) {
      const prefix = `command_${index}_`;
      const key = String(req.body[`${prefix}key`] || "");
      if (!knownKeys.has(key)) continue;
      updates.push({
        commandKey: key,
        policy: commandPolicyFromBody(req.body, { prefix }),
        groupIds: asStringArray(req.body[`${prefix}group_ids`]).filter((id) => validGroups.has(id))
      });
    }
    if (!updates.length) {
      if (wantsEnhancedResponse(req)) {
        return sendEnhancedError(req, res, {
          message: "No available command settings were submitted.",
          redirect: "/admin/command-policies"
        });
      }
      setFlash(req, "error", "No available command settings were submitted.");
      return res.redirect("/admin/command-policies");
    }
    try {
      saveCommandPolicies(updates);
      const message = `${updates.length} command${updates.length === 1 ? "" : "s"} saved.`;
      if (wantsEnhancedResponse(req)) {
        return sendEnhancedResult(res, {
          message,
          data: { savedCount: updates.length }
        });
      }
      setFlash(req, "success", message);
    } catch (error) {
      if (wantsEnhancedResponse(req)) {
        return sendEnhancedError(req, res, {
          message: error?.message || "Command settings could not be saved.",
          redirect: "/admin/command-policies"
        });
      }
      setFlash(req, "error", error?.message || "Command settings could not be saved.");
    }
    return res.redirect("/admin/command-policies");
  });

  app.post("/admin/command-policies/command", requireRole("admin"), (req, res) => {
    const key = String(req.body.command_key || "");
    const knownKeys = new Set([
      ...(commandRouter?.listCommands?.() || []).map((command) => command.key),
      ...db.prepare("SELECT id FROM custom_commands").all().map((command) => customCommandKey(command.id))
    ]);
    if (!knownKeys.has(key)) {
      setFlash(req, "error", "That command is no longer available.");
      return res.redirect("/admin/command-policies");
    }
    const validGroups = new Set(listCommandGroups().map((group) => group.id));
    const groupIds = asStringArray(req.body.group_ids).filter((id) => validGroups.has(id));
    saveCommandPolicy(key, commandPolicyFromBody(req.body), groupIds);
    setFlash(req, "success", "Command settings saved.");
    return res.redirect("/admin/command-policies");
  });

  app.post("/admin/commands", requireRole("mod"), async (req, res) => {
    const isAdmin = Boolean(req.session.user?.isAdmin);
    const availablePlatforms = getPlatformStatus()
      .filter((platform) => platform.supported)
      .map((platform) => platform.id);
    const trigger = (req.body.trigger || "").trim().toLowerCase();
    const description = String(req.body.description || "").trim().slice(0, 500);
    const requestedMode = (req.body.mode || "plain").trim();
    const mode = ["plain", "random", "conditional", "advanced"].includes(requestedMode) ? requestedMode : "plain";
    const language = req.body.language === "python" ? "python" : "js";
    const response = (req.body.response || "").trim();
    const code = (req.body.code || "").trim();
    const randomValidation = randomCommandConfigFromBody(req.body);
    const conditionalValidation = conditionalRepliesFromBody(req.body);
    const selectedPlatforms = parsePlatformSelectionFromBody(
      req.body,
      availablePlatforms
    );
    if (!trigger) {
      return sendCommandMutationError(req, res, "Trigger is required.", { trigger: "Enter a command trigger." });
    }
    if (!selectedPlatforms.length) {
      return sendCommandMutationError(req, res, "Select at least one platform.", { platforms: "Select at least one platform." });
    }
    if (!isAdmin && mode === "advanced") {
      return sendCommandMutationError(req, res, "Dynamic commands are restricted to admins.", { mode: "Choose Static, Random Reply, or Conditional Reply." });
    }
    if (mode === "advanced") {
      if (!code) {
        return sendCommandMutationError(req, res, "Dynamic commands require code.", { code: "Enter the command code." });
      }
    } else if (mode === "plain" && !response) {
      return sendCommandMutationError(req, res, "Static commands require a response.", { response: "Enter the command response." });
    } else if (mode === "random" && !randomValidation.ok) {
      return sendCommandMutationError(req, res, randomValidation.errors[0], { random_text: randomValidation.errors[0] });
    } else if (mode === "conditional" && !conditionalValidation.ok) {
      return sendCommandMutationError(req, res, conditionalValidation.errors[0], { conditional_keyword: conditionalValidation.errors[0] });
    }
    if (mode === "plain") {
      const placeholderValidation = placeholders.validateTemplate({
        fieldId: "core.custom_commands.static_response",
        template: response,
        outputAudience: "user",
        user: req.session.user
      });
      if (!placeholderValidation.ok) {
        const message = formatPlaceholderErrors(placeholderValidation.errors);
        return sendCommandMutationError(req, res, message, { response: message });
      }
    } else if (mode === "random") {
      const templateError = validateRandomReplyTemplates(randomValidation.config, req.session.user);
      if (templateError) {
        return sendCommandMutationError(req, res, templateError, { random_text: templateError });
      }
    } else if (mode === "conditional") {
      const templateError = validateConditionalReplyTemplates(conditionalValidation, req.session.user);
      if (templateError) {
        return sendCommandMutationError(req, res, templateError, { conditional_response: templateError });
      }
    }
    const now = Date.now();
    const preview = isAdmin && mode === "advanced"
      ? await generateCommandPreview({ code, language })
      : emptyCommandPreview();
    try {
      const result = db.prepare(
        "INSERT INTO custom_commands (trigger, description, response, mode, language, code, platform, preview_text, preview_status, preview_error, preview_generated_at, preview_dynamic_segments, random_replies_json, rng_enabled, rng_min, rng_max, conditional_replies_json, conditional_fuzzy, enabled, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?)"
      ).run(
        trigger,
        description,
        response || "",
        isAdmin || mode !== "advanced" ? mode : "plain",
        isAdmin ? language : "js",
        isAdmin && mode === "advanced" ? code : null,
        serializePlatformSelection(selectedPlatforms),
        preview.preview_text,
        preview.preview_status,
        preview.preview_error,
        preview.preview_generated_at,
        preview.preview_dynamic_segments,
        mode === "random" ? JSON.stringify(randomValidation.config.replies) : "[]",
        mode === "random" && randomValidation.config.rngEnabled ? 1 : 0,
        randomValidation.config.rngMin,
        randomValidation.config.rngMax,
        mode === "conditional" ? JSON.stringify(conditionalValidation.replies) : "[]",
        mode === "conditional" && req.body.conditional_fuzzy ? 1 : 0,
        now,
        now
      );
      return sendCommandMutationSuccess(req, res, {
        message: "Command created.",
        data: { commandId: String(result.lastInsertRowid), trigger }
      });
    } catch (error) {
      return sendCommandMutationError(req, res, "That command already exists.", { trigger: "Choose a unique trigger." });
    }
  });

  app.post("/admin/commands/:id/toggle", requireRole("mod"), (req, res) => {
    const row = db
      .prepare("SELECT enabled FROM custom_commands WHERE id = ?")
      .get(req.params.id);
    if (row) {
      db.prepare(
        "UPDATE custom_commands SET enabled = ?, updated_at = ? WHERE id = ?"
      ).run(row.enabled ? 0 : 1, Date.now(), req.params.id);
    }
    if (!row) return sendCommandMutationError(req, res, "That command no longer exists.");
    return sendCommandMutationSuccess(req, res, {
      message: row.enabled ? "Command disabled." : "Command enabled.",
      data: { commandId: req.params.id, enabled: !Boolean(row.enabled) }
    });
  });

  app.post("/admin/commands/:id/delete", requireRole("mod"), (req, res) => {
    db.transaction(() => {
      db.prepare("DELETE FROM command_policies WHERE command_key = ?").run(customCommandKey(req.params.id));
      db.prepare("DELETE FROM command_group_members WHERE command_key = ?").run(customCommandKey(req.params.id));
      db.prepare("DELETE FROM custom_commands WHERE id = ?").run(req.params.id);
    })();
    return sendCommandMutationSuccess(req, res, {
      message: "Command deleted.",
      data: { commandId: req.params.id }
    });
  });

  app.post("/admin/commands/:id/update", requireRole("mod"), async (req, res) => {
    const isAdmin = Boolean(req.session.user?.isAdmin);
    const existing = db
      .prepare("SELECT mode FROM custom_commands WHERE id = ?")
      .get(req.params.id);
    if (!existing) {
      return sendCommandMutationError(req, res, "That command no longer exists.");
    }
    if (existing?.mode === "advanced" && !isAdmin) {
      return sendCommandMutationError(req, res, "Dynamic commands can only be edited by admins.", { mode: "Ask an administrator to edit this command." });
    }
    const availablePlatforms = getPlatformStatus()
      .filter((platform) => platform.supported)
      .map((platform) => platform.id);
    const trigger = (req.body.trigger || "").trim().toLowerCase();
    const description = String(req.body.description || "").trim().slice(0, 500);
    const requestedMode = (req.body.mode || "plain").trim();
    const mode = ["plain", "random", "conditional", "advanced"].includes(requestedMode) ? requestedMode : "plain";
    const language = req.body.language === "python" ? "python" : "js";
    const response = (req.body.response || "").trim();
    const code = (req.body.code || "").trim();
    const randomValidation = randomCommandConfigFromBody(req.body);
    const conditionalValidation = conditionalRepliesFromBody(req.body);
    const selectedPlatforms = parsePlatformSelectionFromBody(
      req.body,
      availablePlatforms
    );
    if (!trigger) {
      return sendCommandMutationError(req, res, "Trigger is required.", { trigger: "Enter a command trigger." });
    }
    if (!selectedPlatforms.length) {
      return sendCommandMutationError(req, res, "Select at least one platform.", { platforms: "Select at least one platform." });
    }
    if (!isAdmin && mode === "advanced") {
      return sendCommandMutationError(req, res, "Dynamic commands are restricted to admins.", { mode: "Choose Static, Random Reply, or Conditional Reply." });
    }
    if (mode === "advanced") {
      if (!code) {
        return sendCommandMutationError(req, res, "Dynamic commands require code.", { code: "Enter the command code." });
      }
    } else if (mode === "plain" && !response) {
      return sendCommandMutationError(req, res, "Static commands require a response.", { response: "Enter the command response." });
    } else if (mode === "random" && !randomValidation.ok) {
      return sendCommandMutationError(req, res, randomValidation.errors[0], { random_text: randomValidation.errors[0] });
    } else if (mode === "conditional" && !conditionalValidation.ok) {
      return sendCommandMutationError(req, res, conditionalValidation.errors[0], { conditional_keyword: conditionalValidation.errors[0] });
    }
    if (mode === "plain") {
      const placeholderValidation = placeholders.validateTemplate({
        fieldId: "core.custom_commands.static_response",
        template: response,
        outputAudience: "user",
        user: req.session.user
      });
      if (!placeholderValidation.ok) {
        const message = formatPlaceholderErrors(placeholderValidation.errors);
        return sendCommandMutationError(req, res, message, { response: message });
      }
    } else if (mode === "random") {
      const templateError = validateRandomReplyTemplates(randomValidation.config, req.session.user);
      if (templateError) {
        return sendCommandMutationError(req, res, templateError, { random_text: templateError });
      }
    } else if (mode === "conditional") {
      const templateError = validateConditionalReplyTemplates(conditionalValidation, req.session.user);
      if (templateError) {
        return sendCommandMutationError(req, res, templateError, { conditional_response: templateError });
      }
    }
    const preview = isAdmin && mode === "advanced"
      ? await generateCommandPreview({ code, language })
      : emptyCommandPreview();
    try {
      db.prepare(
        "UPDATE custom_commands SET trigger = ?, description = ?, response = ?, mode = ?, language = ?, code = ?, platform = ?, preview_text = ?, preview_status = ?, preview_error = ?, preview_generated_at = ?, preview_dynamic_segments = ?, random_replies_json = ?, rng_enabled = ?, rng_min = ?, rng_max = ?, conditional_replies_json = ?, conditional_fuzzy = ?, updated_at = ? WHERE id = ?"
      ).run(
        trigger,
        description,
        response || "",
        isAdmin || mode !== "advanced" ? mode : "plain",
        isAdmin ? language : "js",
        isAdmin && mode === "advanced" ? code : null,
        serializePlatformSelection(selectedPlatforms),
        preview.preview_text,
        preview.preview_status,
        preview.preview_error,
        preview.preview_generated_at,
        preview.preview_dynamic_segments,
        mode === "random" ? JSON.stringify(randomValidation.config.replies) : "[]",
        mode === "random" && randomValidation.config.rngEnabled ? 1 : 0,
        randomValidation.config.rngMin,
        randomValidation.config.rngMax,
        mode === "conditional" ? JSON.stringify(conditionalValidation.replies) : "[]",
        mode === "conditional" && req.body.conditional_fuzzy ? 1 : 0,
        Date.now(),
        req.params.id
      );
      return sendCommandMutationSuccess(req, res, {
        message: "Command updated.",
        data: { commandId: req.params.id, trigger }
      });
    } catch (error) {
      return sendCommandMutationError(req, res, "Unable to update command.", { trigger: "Check that this trigger is unique." });
    }
  });

  app.post("/admin/commands/:id/preview", requireRole("admin"), async (req, res) => {
    const command = db
      .prepare("SELECT mode, language, code FROM custom_commands WHERE id = ?")
      .get(req.params.id);
    if (!command || command.mode !== "advanced" || !command.code) {
      return sendCommandMutationError(req, res, "Dynamic command not found.");
    }
    const preview = await generateCommandPreview(command);
    db.prepare(
      "UPDATE custom_commands SET preview_text = ?, preview_status = ?, preview_error = ?, preview_generated_at = ?, preview_dynamic_segments = ? WHERE id = ?"
    ).run(
      preview.preview_text,
      preview.preview_status,
      preview.preview_error,
      preview.preview_generated_at,
      preview.preview_dynamic_segments,
      req.params.id
    );
    if (preview.preview_status !== "ready") {
      return sendCommandMutationError(req, res, preview.preview_error || "Preview unavailable.");
    }
    return sendCommandMutationSuccess(req, res, {
      message: "Command preview refreshed.",
      data: { commandId: req.params.id, previewStatus: preview.preview_status }
    });
  });

  app.get("/admin/pages", requireRole("admin"), (req, res) => {
    const pages = db
      .prepare("SELECT * FROM custom_pages ORDER BY created_at DESC")
      .all();
    res.render("admin-pages", {
      title: "Custom pages",
      pages
    });
  });

  app.get("/admin/users", requireRole("mod"), (req, res) => {
    const users = listUsersWithIdentities();
    const notes = db
      .prepare(
        "SELECT n.*, s.internal_user_id FROM moderation_notes n " +
          "LEFT JOIN moderation_subjects s ON s.id = n.subject_id"
      )
      .all();
    const notesByUser = notes.reduce((acc, note) => {
      if (!note.internal_user_id) {
        return acc;
      }
      if (!acc[note.internal_user_id]) {
        acc[note.internal_user_id] = [];
      }
      acc[note.internal_user_id].push(note);
      return acc;
    }, {});
    res.render("admin-users", {
      title: "Users",
      users,
      notesByUser,
      isAdmin: Boolean(req.session.user?.isAdmin)
    });
  });

  app.post("/admin/users/:id/username", requireRole("admin"), (req, res) => {
    const desired = (req.body.internal_username || "").trim();
    const result = updateInternalUsername(req.params.id, desired);
    if (!result.ok) {
      setFlash(req, "error", result.reason);
      return res.redirect("/admin/users");
    }
    setFlash(req, "success", "Username updated.");
    res.redirect("/admin/users");
  });

  app.post("/admin/pages", requireRole("admin"), (req, res) => {
    const slug = (req.body.slug || "").trim();
    const title = (req.body.title || "").trim();
    const navLabel = (req.body.nav_label || "").trim();
    const content = (req.body.content || "").trim();
    const format = normalizePageFormat(req.body.format);
    const contentCss =
      format === "html" ? (req.body.content_css || "").trim() : "";
    const role = (req.body.role || "public").trim();
    const showInNav = req.body.show_in_nav === "on";
    if (!slug || !title || !content) {
      setFlash(req, "error", "Slug, title, and content are required.");
      return res.redirect("/admin/pages");
    }
    const now = Date.now();
      try {
        db.prepare(
          "INSERT INTO custom_pages (slug, title, nav_label, content, content_css, format, role, show_in_nav, enabled, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?)"
        ).run(
          slug,
          title,
          navLabel || null,
          content,
          contentCss,
          format,
          role,
          showInNav ? 1 : 0,
          now,
          now
        );
      setFlash(req, "success", "Page created.");
      res.redirect("/admin/pages");
    } catch (error) {
      setFlash(req, "error", "That page already exists.");
      res.redirect("/admin/pages");
    }
  });

  app.post("/admin/pages/:id/toggle", requireRole("admin"), (req, res) => {
    const row = db
      .prepare("SELECT enabled FROM custom_pages WHERE id = ?")
      .get(req.params.id);
    if (row) {
      db.prepare(
        "UPDATE custom_pages SET enabled = ?, updated_at = ? WHERE id = ?"
      ).run(row.enabled ? 0 : 1, Date.now(), req.params.id);
    }
    res.redirect("/admin/pages");
  });

  app.post("/admin/pages/:id/delete", requireRole("admin"), (req, res) => {
    db.prepare("DELETE FROM custom_pages WHERE id = ?").run(req.params.id);
    setFlash(req, "success", "Page deleted.");
    res.redirect("/admin/pages");
  });

  app.post("/admin/pages/:id/update", requireRole("admin"), (req, res) => {
    const slug = (req.body.slug || "").trim();
    const title = (req.body.title || "").trim();
    const navLabel = (req.body.nav_label || "").trim();
    const content = (req.body.content || "").trim();
    const format = normalizePageFormat(req.body.format);
    const contentCss =
      format === "html" ? (req.body.content_css || "").trim() : "";
    const role = (req.body.role || "public").trim();
    const showInNav = req.body.show_in_nav === "on";
    if (!slug || !title || !content) {
      setFlash(req, "error", "Slug, title, and content are required.");
      return res.redirect("/admin/pages");
    }
      try {
        db.prepare(
          "UPDATE custom_pages SET slug = ?, title = ?, nav_label = ?, content = ?, content_css = ?, format = ?, role = ?, show_in_nav = ?, updated_at = ? WHERE id = ?"
        ).run(
          slug,
          title,
          navLabel || null,
          content,
          contentCss,
          format,
          role,
          showInNav ? 1 : 0,
          Date.now(),
          req.params.id
        );
      setFlash(req, "success", "Page updated.");
      res.redirect("/admin/pages");
    } catch (error) {
      setFlash(req, "error", "Unable to update page.");
      res.redirect("/admin/pages");
    }
  });

  app.get("/admin/plugins", requireRole("admin"), (req, res) => {
    syncPluginRegistry();
    const plugins = getPlugins().filter((plugin) => !/^lumi_ai_[a-z0-9_-]+$/i.test(plugin.id || ""));
    res.render("admin-plugins", {
      title: "Plugins",
      plugins
    });
  });

  app.post("/admin/plugins/:id/toggle", requireRole("admin"), (req, res) => {
    setPluginEnabled(req.params.id, req.body.enabled === "true");
    setFlash(req, "success", "Plugin updated. Restarting...");
    res.redirect("/admin/plugins");
    requestRestart();
  });

  app.post("/admin/plugins/:id/uninstall", requireRole("admin"), (req, res) => {
    const plugin = db
      .prepare("SELECT path FROM plugins WHERE id = ?")
      .get(req.params.id);
    if (plugin?.path) {
      try {
        fs.rmSync(plugin.path, { recursive: true, force: true });
      } catch (error) {
        console.error(error);
      }
    }
    removePlugin(req.params.id);
    setFlash(req, "success", "Plugin uninstalled. Restarting...");
    res.redirect("/admin/plugins");
    requestRestart();
  });

  app.post(
    "/admin/plugins/upload",
    requireRole("admin"),
    uploadSingle("plugin_zip"),
    async (req, res) => {
      if (req.uploadError) {
        setFlash(req, "error", req.uploadError);
        return res.redirect("/admin/plugins");
      }
      if (!req.file) {
        setFlash(req, "error", "Upload a ZIP archive.");
        return res.redirect("/admin/plugins");
      }
      try {
        await applyPluginUpdate(req.file.path);
        setFlash(req, "success", "Plugin uploaded. Restarting...");
        res.redirect("/admin/plugins");
        requestRestart();
      } catch (error) {
        setFlash(req, "error", error.message);
        res.redirect("/admin/plugins");
      } finally {
        try {
          fs.rmSync(req.file.path, { force: true });
        } catch {
          // ignore cleanup errors
        }
      }
    }
  );

  app.post("/admin/plugins/install", requireRole("admin"), (req, res) => {
    const url = (req.body.url || "").trim();
    if (!url) {
      setFlash(req, "error", "Plugin URL is required.");
      return res.redirect("/admin/plugins");
    }
    try {
      installFromGit(url);
      setFlash(req, "success", "Plugin installed. Restarting...");
      res.redirect("/admin/plugins");
      requestRestart();
    } catch (error) {
      setFlash(req, "error", error.message);
      res.redirect("/admin/plugins");
    }
  });

  app.post("/admin/plugins/create", requireRole("admin"), (req, res) => {
    const id = (req.body.id || "").trim();
    const name = (req.body.name || "").trim();
    const description = (req.body.description || "").trim();
    try {
      createLocalPlugin({ id, name, description });
      setFlash(req, "success", "Plugin created. Restarting...");
      res.redirect("/admin/plugins");
      requestRestart();
    } catch (error) {
      setFlash(req, "error", error.message);
      res.redirect("/admin/plugins");
    }
  });

  app.post("/admin/plugins/:id/update", requireRole("admin"), (req, res) => {
    const plugin = db
      .prepare("SELECT path FROM plugins WHERE id = ?")
      .get(req.params.id);
    if (!plugin?.path) {
      setFlash(req, "error", "Plugin not found.");
      return res.redirect("/admin/plugins");
    }
    try {
      updatePluginFromGit(plugin.path);
      setFlash(req, "success", "Plugin updated. Restarting...");
      res.redirect("/admin/plugins");
      requestRestart();
    } catch (error) {
      setFlash(req, "error", error.message);
      res.redirect("/admin/plugins");
    }
  });

  function wantsJson(req) {
    return req.xhr ||
      req.get("accept")?.includes("application/json") ||
      req.get("content-type")?.includes("application/json");
  }

  function updateSourceFrom(req) {
    const value = req.body?.source || req.query?.source || "stable";
    return value === "experimental" ? "experimental" : String(value || "stable");
  }

  function sendUpdateResult(req, res, result, redirectPath = "/admin/updates") {
    if (wantsJson(req)) {
      const payload = result && typeof result === "object" ? result : {};
      const { message = "Update action completed.", patch = {}, reloadRequired = false, ...data } = payload;
      return res.json({
        ok: true,
        message,
        ...data,
        data,
        patch,
        reloadRequired
      });
    }
    setFlash(req, "success", result.message || "Update action completed.");
    return res.redirect(redirectPath);
  }

  function sendUpdateError(req, res, error, redirectPath = "/admin/updates") {
    if (wantsJson(req)) {
      const fieldErrors = error?.fieldErrors && typeof error.fieldErrors === "object" ? error.fieldErrors : {};
      return res.status(Object.keys(fieldErrors).length ? 422 : 400).json({
        ok: false,
        message: error.message,
        error: error.message,
        fieldErrors,
        data: {},
        patch: {},
        reloadRequired: false
      });
    }
    setFlash(req, "error", error.message);
    return res.redirect(redirectPath);
  }

  function scheduleRestartAfterNotice() {
    setTimeout(() => requestRestart(), 5000);
  }

  app.get("/admin/updates/events", requireRole("admin"), subscribeWebEvents);

  app.get("/admin/updates/status", requireRole("admin"), (req, res) => {
    try {
      res.json({ ok: true, status: getUpdateStatus({ source: updateSourceFrom(req) }) });
    } catch (error) {
      res.status(500).json({ ok: false, error: error.message });
    }
  });

  app.get("/admin/updates/recovery", requireRole("admin"), (req, res) => {
    res.json({ ok: true, recovery: safeModeStatus(), snapshots: listSnapshots() });
  });

  app.post("/admin/updates/recovery/clear-marker", requireRole("admin"), (req, res) => {
    clearRecoveryMarker();
    publishWebEvent("recovery:marker_detected", { status: "cleared" }, { role: "admin" });
    sendUpdateResult(req, res, { message: "Recovery marker cleared." });
  });

  app.post("/admin/updates/recovery/retry-normal-startup", requireRole("admin"), (req, res) => {
    updateRecoveryMarker({ status: "retry_startup", retry_at: new Date().toISOString() });
    publishWebEvent("recovery:retry_startup", {}, { role: "admin" });
    sendUpdateResult(req, res, {
      restart_required: true,
      refresh_after_ms: 5000,
      message: "Retrying normal startup. This page will reconnect when Lumi is available."
    });
    scheduleRestartAfterNotice();
  });

  app.get("/admin/updates", requireRole("admin"), (req, res) => {
    let updateStatus = null;
    let updateStatusError = null;
    let snapshots = [];
    let recoveryStatus = {};
    let deploymentBranches = [];
    let deploymentError = null;
    const configuredRemote = getSetting("git_remote", "origin");
    const configuredBranch = getSetting("git_branch", "main");
    const updateState = readUpdateState();
    const deployedBranch = String(updateState.deployed_branch || configuredBranch || "main");
    try {
      updateStatus = getUpdateStatus({ source: updateSourceFrom(req) });
    } catch (error) {
      updateStatusError = error.message;
    }
    try {
      snapshots = listSnapshots();
    } catch (error) {
      updateStatusError = [updateStatusError, `Snapshots could not be loaded: ${error.message}`]
        .filter(Boolean)
        .join(" ");
    }
    try {
      recoveryStatus = safeModeStatus();
    } catch (error) {
      updateStatusError = [updateStatusError, `Recovery status could not be loaded: ${error.message}`]
        .filter(Boolean)
        .join(" ");
    }
    try {
      deploymentBranches = listDeploymentBranches(configuredRemote).branches;
    } catch (error) {
      deploymentError = error.message;
    }
    if (!deploymentBranches.some((item) => item.name === deployedBranch) && (deployedBranch === "main" || deployedBranch.startsWith("experimental-"))) {
      deploymentBranches.push({
        name: deployedBranch,
        commit: updateState.deployed_commit || "",
        channel: deployedBranch === "main" ? "stable" : "experimental",
        unavailable: true
      });
    }
    res.render("admin-updates", {
      title: "Updates",
      snapshots,
      snapshotRetention: getSnapshotRetention(),
      updateStatus,
      updateStatusError,
      recoveryStatus,
      deploymentBranches,
      deploymentError,
      deploymentState: {
        branch: deployedBranch,
        commit: updateState.deployed_commit || null,
        version: updateState.deployed_version || require("../../package.json").version,
        previous_branch: updateState.previous_deployed_branch || null,
        remote: configuredRemote
      }
    });
  });

  app.post("/admin/updates/snapshots/settings", requireRole("admin"), (req, res) => {
    try {
      const fieldErrors = {};
      const age = Number(req.body.max_age_days);
      const count = Number(req.body.max_per_target);
      if (!Number.isInteger(age) || age < 1 || age > 3650) {
        fieldErrors.max_age_days = "Enter a whole number from 1 to 3650.";
      }
      if (!Number.isInteger(count) || count < 1 || count > 50) {
        fieldErrors.max_per_target = "Enter a whole number from 1 to 50.";
      }
      if (Object.keys(fieldErrors).length) {
        const error = new Error("Correct the snapshot cleanup limits and try again.");
        error.fieldErrors = fieldErrors;
        throw error;
      }
      const retention = setSnapshotRetention({
        max_age_days: age,
        max_per_target: count
      });
      sendUpdateResult(req, res, {
        retention,
        message: `Snapshot cleanup now keeps up to ${retention.max_per_target} backup(s) per target for at most ${retention.max_age_days} day(s).`
      });
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post("/admin/updates/core/check", requireRole("admin"), (req, res) => {
    try {
      const status = getUpdateStatus({ source: updateSourceFrom(req) });
      sendUpdateResult(req, res, {
        status,
        message: status.core.update_available
          ? `Core version ${status.core.safe_target_version} is available.`
          : status.core.blocked
            ? status.core.blocked_reason
            : "Lumi core is already up to date."
      });
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post("/admin/updates/core/apply", requireRole("admin"), async (req, res) => {
    try {
      const result = await applyCoreUpdate({
        source: updateSourceFrom(req),
        version: req.body.version || null,
        publish: publishWebEvent
      });
      sendUpdateResult(req, res, {
        ...result,
        restart_required: true,
        refresh_after_ms: 5000,
        message: "Core update applied. Lumi will restart after the confirmation notice."
      });
      scheduleRestartAfterNotice();
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post("/admin/updates/core/deploy-branch", requireRole("admin"), async (req, res) => {
    try {
      const result = await deployCoreBranch({
        branch: req.body.branch,
        remote: getSetting("git_remote", "origin"),
        publish: publishWebEvent
      });
      sendUpdateResult(req, res, {
        ...result,
        restart_required: true,
        refresh_after_ms: 5000,
        message: `${result.deployment.branch} was deployed and verified. Lumi will restart gracefully after this notice.`
      });
      scheduleRestartAfterNotice();
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post("/admin/updates/core/revert", requireRole("admin"), async (req, res) => {
    try {
      const status = getUpdateStatus({ source: updateSourceFrom(req) });
      const snapshotId = req.body.snapshot_id || status.core.snapshot.latest_snapshot_id;
      if (!snapshotId) throw new Error("No core snapshot is available to revert.");
      const result = await revertCoreSnapshot(snapshotId, {
        currentVersion: status.core.current_version,
        publish: publishWebEvent
      });
      sendUpdateResult(req, res, {
        ...result,
        restart_required: true,
        refresh_after_ms: 5000,
        message: "Core snapshot reverted. Lumi will restart after the confirmation notice."
      });
      scheduleRestartAfterNotice();
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post(
    "/admin/updates/bot",
    requireRole("admin"),
    uploadSingle("update_zip"),
    async (req, res) => {
      if (req.uploadError) {
        setFlash(req, "error", req.uploadError);
        return res.redirect("/admin/updates");
      }
      if (!req.file) {
        setFlash(req, "error", "Upload a ZIP archive.");
        return res.redirect("/admin/updates");
      }
      try {
        const patchMode = req.body.patch_mode === "1";
        await applyBotUpdate(req.file.path, {
          mode: patchMode ? "patch" : "full"
        });
        setFlash(
          req,
          "success",
          patchMode ? "Patch applied. Restarting..." : "Update applied. Restarting..."
        );
        res.redirect("/admin/updates");
        requestRestart();
      } catch (error) {
        setFlash(req, "error", error.message);
        res.redirect("/admin/updates");
      } finally {
        try {
          fs.rmSync(req.file.path, { force: true });
        } catch {
          // ignore cleanup errors
        }
      }
    }
  );

  app.post(
    "/admin/updates/core/zip",
    requireRole("admin"),
    uploadSingle("update_zip"),
    async (req, res) => {
      if (req.uploadError) return sendUpdateError(req, res, new Error(req.uploadError));
      if (!req.file) return sendUpdateError(req, res, new Error("Upload a ZIP archive."));
      try {
        const patchMode = req.body.patch_mode === "1";
        const snapshot = await applyBotUpdate(req.file.path, {
          mode: patchMode ? "patch" : "full",
          metadata: {
            update_method: patchMode ? "zip_patch" : "zip",
            source_branch: "manual_zip",
            rollback_safe: req.body.rollback_safe === "1"
          }
        });
        sendUpdateResult(req, res, {
          snapshot,
          restart_required: true,
          refresh_after_ms: 5000,
          message: patchMode ? "Core patch ZIP applied. Restarting..." : "Core ZIP update applied. Restarting..."
        });
        scheduleRestartAfterNotice();
      } catch (error) {
        sendUpdateError(req, res, error);
      } finally {
        try { fs.rmSync(req.file?.path, { force: true }); } catch {}
      }
    }
  );

  app.post(
    "/admin/updates/plugin",
    requireRole("admin"),
    uploadSingle("plugin_zip"),
    async (req, res) => {
      if (req.uploadError) return sendUpdateError(req, res, new Error(req.uploadError));
      if (!req.file) return sendUpdateError(req, res, new Error("Upload a ZIP archive."));
      try {
        const snapshot = await applyPluginUpdate(req.file.path);
        sendUpdateResult(req, res, {
          snapshot,
          restart_required: true,
          refresh_after_ms: 5000,
          message: "Plugin update applied. Lumi will restart after the confirmation notice."
        });
        scheduleRestartAfterNotice();
      } catch (error) {
        sendUpdateError(req, res, error);
      } finally {
        try {
          fs.rmSync(req.file.path, { force: true });
        } catch {
          // ignore cleanup errors
        }
      }
    }
  );

  app.post("/admin/updates/plugins/:id/check", requireRole("admin"), (req, res) => {
    try {
      const status = getUpdateStatus({ source: updateSourceFrom(req) });
      const plugin = status.plugins.find((item) => item.id === req.params.id);
      if (!plugin) throw new Error("Plugin not found.");
      sendUpdateResult(req, res, {
        plugin,
        message: plugin.update_available
          ? `${plugin.name} version ${plugin.safe_target_version} is available.`
          : plugin.blocked
            ? plugin.blocked_reason
            : `${plugin.name} is already up to date.`
      });
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post("/admin/updates/plugins/:id/apply", requireRole("admin"), async (req, res) => {
    try {
      const result = await applyPluginUpdateFromRepo(req.params.id, {
        source: updateSourceFrom(req),
        version: req.body.version || null,
        publish: publishWebEvent
      });
      sendUpdateResult(req, res, {
        ...result,
        restart_required: true,
        refresh_after_ms: 5000,
        message: "Plugin update applied. Lumi will restart after the confirmation notice."
      });
      scheduleRestartAfterNotice();
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post("/admin/updates/plugins/:id/revert", requireRole("admin"), async (req, res) => {
    try {
      const status = getUpdateStatus({ source: updateSourceFrom(req) });
      const plugin = status.plugins.find((item) => item.id === req.params.id);
      if (!plugin) throw new Error("Plugin not found.");
      const snapshotId = req.body.snapshot_id || plugin.snapshot.latest_snapshot_id;
      if (!snapshotId) throw new Error("No plugin snapshot is available to revert.");
      const result = await revertPluginSnapshot(req.params.id, snapshotId, {
        currentVersion: plugin.current_version,
        publish: publishWebEvent
      });
      sendUpdateResult(req, res, {
        ...result,
        restart_required: true,
        refresh_after_ms: 5000,
        message: "Plugin snapshot reverted. Restarting..."
      });
      scheduleRestartAfterNotice();
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post("/admin/updates/plugins/:id/disable", requireRole("admin"), (req, res) => {
    try {
      const result = disablePluginForRecovery(req.params.id, publishWebEvent);
      sendUpdateResult(req, res, { ...result, message: "Plugin disabled for recovery." });
    } catch (error) {
      sendUpdateError(req, res, error);
    }
  });

  app.post(
    "/admin/updates/plugins/:id/zip",
    requireRole("admin"),
    uploadSingle("plugin_zip"),
    async (req, res) => {
      if (req.uploadError) return sendUpdateError(req, res, new Error(req.uploadError));
      if (!req.file) return sendUpdateError(req, res, new Error("Upload a ZIP archive."));
      try {
        const snapshot = await applyPluginUpdate(req.file.path, {
          expectedPluginId: req.params.id,
          metadata: {
            target_id: req.params.id,
            source_branch: "manual_zip",
            rollback_safe: req.body.rollback_safe === "1"
          }
        });
        sendUpdateResult(req, res, {
          snapshot,
          message: "Plugin ZIP update applied."
        });
      } catch (error) {
        sendUpdateError(req, res, error);
      } finally {
        try { fs.rmSync(req.file?.path, { force: true }); } catch {}
      }
    }
  );

  app.post("/admin/update", requireRole("admin"), async (req, res) => {
    try {
      const remote = getSetting("git_remote", "origin");
      const branch = getSetting("git_branch", "main");
      const result = await applyCoreUpdate({
        remote,
        source: branch === "main" ? "stable" : branch,
        publish: publishWebEvent
      });
      sendUpdateResult(req, res, {
        ...result,
        restart_required: true,
        refresh_after_ms: 5000,
        message: "Core update applied. Lumi will restart in a few seconds."
      }, "/admin");
      scheduleRestartAfterNotice();
    } catch (error) {
      sendUpdateError(req, res, error, "/admin");
    }
  });

  app.post("/admin/check-update", requireRole("admin"), (req, res) => {
    try {
      const remote = getSetting("git_remote", "origin");
      const branch = getSetting("git_branch", "main");
      const status = getUpdateStatus({
        remote,
        source: branch === "main" ? "stable" : branch
      });
      sendUpdateResult(req, res, {
        status,
        message: status.core.update_available
          ? `Core version ${status.core.safe_target_version} is ready to install.`
          : status.core.blocked
            ? status.core.blocked_reason
            : "Lumi is up to date."
      }, "/admin");
    } catch (error) {
      sendUpdateError(req, res, error, "/admin");
    }
  });

  app.post("/admin/restart", requireRole("admin"), (req, res) => {
    setFlash(req, "success", "Restarting...");
    res.redirect("/admin");
    requestRestart();
  });

  app.use((err, req, res, next) => {
    if (res.headersSent) {
      return next(err);
    }
    const message = err?.message || "";
    const isViewMissing = message.includes("Failed to lookup view");
    log("error", "Unhandled error", {
      path: req.path,
      method: req.method,
      userId: req.session.user?.id || null,
      message,
      stack: err?.stack || ""
    });
    if (isViewMissing) {
      res.locals.softError = "Some content could not be loaded.";
      return res.status(200).render("missing-view", {
        title: "Content missing",
        resource: "A page component failed to load. Please try again."
      });
    }
    const status = err?.status || 500;
    res.status(status).render("error", {
      title: "Something went wrong",
      message: "An unexpected error occurred. Please try again."
    });
  });

  if (typeof loadPlugins === "function") {
    loadPlugins(app, web, webhooks);
  }

  return app;
}

const NAV_SECTION_ICONS = ["home", "spark", "shield", "gear", "blocks"];
const DEFAULT_NAV_SECTIONS = [
  { id: "overview", label: "Overview", icon: "home" },
  { id: "community", label: "Community", icon: "spark" },
  { id: "moderation", label: "Mod", icon: "shield" },
  { id: "admin", label: "Admin", icon: "gear" },
  { id: "plugins", label: "Plugins", icon: "blocks" }
];

function collectNavItems(user, pluginNav, currentPath) {
  const iconMap = getSetting("nav_item_icons", {}) || {};
  const base = [
    { label: "Home", path: "/", role: "public", section: "overview" },
    { label: "Commands", path: "/commands", role: "public", section: "community" },
    {
      label: "Leaderboards",
      path: "/leaderboards",
      role: "public",
      section: "community"
    },
    {
      label: "Stats",
      path: "/stats",
      role: "public",
      authRequired: true,
      section: "community"
    },
    {
      label: "Profile",
      path: "/profile",
      role: "public",
      authRequired: true,
      section: "community"
    },
    {
      label: "Feedback",
      path: "/feedback",
      role: "public",
      authRequired: true,
      section: "community"
    },
    { label: "Mods List", path: "/moderator", role: "mod", section: "moderation" },
    { label: "Admin", path: "/admin", role: "admin", section: "admin" },
    {
      label: "Settings",
      path: "/admin/settings",
      role: "admin",
      section: "admin"
    },
    {
      label: "Navigation",
      path: "/admin/navigation",
      role: "admin",
      section: "admin"
    },
    {
      label: "Theming",
      path: "/admin/theming",
      role: "admin",
      section: "admin"
    },
    {
      label: "Privileges",
      path: "/admin/privileges",
      role: "admin",
      section: "admin"
    },
    {
      label: "OBS overlays",
      path: "/admin/overlays",
      role: "admin",
      section: "admin"
    },
    {
      label: "Resources",
      path: "/admin/resources",
      role: "admin",
      section: "admin"
    },
    { label: "Feedback review", path: "/admin/feedback", role: "admin", section: "admin" },
    { label: "Diagnostics", path: "/admin/diagnostics", role: "admin", section: "admin" },
    { label: "Logs", path: "/admin/logs", role: "admin", section: "admin" },
    { label: "Updates", path: "/admin/updates", role: "admin", section: "admin" },
    {
      label: "Custom commands",
      path: "/admin/commands",
      role: "mod",
      section: "moderation"
    },
    {
      label: "Command access",
      path: "/admin/command-policies",
      role: "admin",
      section: "admin"
    },
    { label: "Pages", path: "/admin/pages", role: "admin", section: "admin" },
    { label: "Users", path: "/admin/users", role: "mod", section: "moderation" },
    { label: "Plugins", path: "/admin/plugins", role: "admin", section: "admin" }
  ];
  const pages = db
    .prepare(
      "SELECT slug, title, nav_label, role FROM custom_pages WHERE show_in_nav = 1 AND enabled = 1 ORDER BY created_at ASC"
    )
    .all()
    .map((page) => ({
      label: page.nav_label || page.title,
      path: `/pages/${page.slug}`,
      role: page.role,
      section: "community"
    }));
  const pluginItems = (pluginNav || []).map((item) => ({
    ...item,
    section: item.section || "plugins"
  }));
  const allItems = [...base, ...pages, ...pluginItems].filter((item) => {
    if (item.authRequired && !user) {
      return false;
    }
    if (typeof item.canAccess === "function") {
      try {
        if (!item.canAccess(user)) return false;
      } catch {
        return false;
      }
    }
    return hasAccess(user, item.role);
  });
  return allItems.map((item) => {
    const navId = buildNavItemId(item);
    const customIcon = iconMap[navId] || null;
    const defaultIcon = getDefaultNavIcon(item);
    const icon = customIcon
      ? `/assets/nav-icons/${customIcon}`
      : defaultIcon
        ? `/icons/nav/${defaultIcon}.svg`
        : null;
    return {
      ...item,
      navId,
      icon,
      active: isActivePath(item.path, currentPath)
    };
  });
}

function buildNavSections(user, pluginNav, currentPath) {
  const items = collectNavItems(user, pluginNav, currentPath);
  const navStructure = normalizeNavStructure(getSetting("nav_structure", null));
  if (navStructure?.enabled && navStructure.sections.length) {
    return buildNavSectionsFromStructure(items, navStructure);
  }
  return buildDefaultNavSections(items);
}

function buildDefaultNavSections(items) {
  const sections = DEFAULT_NAV_SECTIONS.map((section) => ({
    ...section,
    items: []
  }));
  const sectionMap = new Map(sections.map((section) => [section.id, section]));

  for (const item of items) {
    const section = sectionMap.get(item.section);
    if (section) {
      section.items.push(item);
    }
  }

  return sections
    .filter((section) => section.items.length)
    .map((section) => ({
      ...section,
      items: section.items.slice().sort((a, b) => a.label.localeCompare(b.label)),
      open: section.items.some((item) => item.active)
    }));
}

function buildNavSectionsFromStructure(items, structure) {
  const itemMap = new Map(items.map((item) => [item.navId, item]));
  const used = new Set();
  const sections = [];

  const pushSection = (section, sectionItems) => {
    if (!sectionItems.length) {
      return;
    }
    sections.push({
      id: section.id,
      label: section.label || toTitleCase(section.id) || section.id,
      icon: normalizeNavSectionIcon(section.icon) || "blocks",
      items: sectionItems,
      open: sectionItems.some((item) => item.active)
    });
  };

  for (const section of structure.sections) {
    if (!section?.id) {
      continue;
    }
    const sectionItems = [];
    for (const rawId of section.items || []) {
      const navId = (rawId || "").toString().trim();
      if (!navId || used.has(navId)) {
        continue;
      }
      const item = itemMap.get(navId);
      if (!item) {
        continue;
      }
      sectionItems.push(item);
      used.add(navId);
    }
    pushSection(section, sectionItems);
  }

  if (structure.includeUnassigned !== false) {
    const unassigned = items.filter((item) => !used.has(item.navId));
    if (unassigned.length) {
      pushSection(
        {
          id: structure.unassignedId || "other",
          label: structure.unassignedLabel || "Other",
          icon: structure.unassignedIcon || "blocks"
        },
        unassigned
      );
    }
  }

  return sections;
}

function buildNavIconItems(user, pluginNav, currentPath) {
  return collectNavItems(user, pluginNav, currentPath).map((item) => ({
    id: item.navId,
    label: item.label,
    path: item.path,
    icon: item.icon
  }));
}

function buildDefaultNavStructure(items) {
  const sections = DEFAULT_NAV_SECTIONS.map((section) => ({
    id: section.id,
    label: section.label,
    icon: section.icon,
    items: []
  }));
  const sectionMap = new Map(sections.map((section) => [section.id, section]));
  items.forEach((item) => {
    const section = sectionMap.get(item.section);
    if (section) {
      section.items.push(item);
    }
  });
  sections.forEach((section) => {
    section.items = section.items
      .slice()
      .sort((a, b) => a.label.localeCompare(b.label))
      .map((item) => item.navId);
  });
  return {
    enabled: false,
    includeUnassigned: true,
    sections
  };
}

function normalizeNavStructure(raw) {
  if (!raw) {
    return null;
  }
  let value = raw;
  if (typeof value === "string") {
    try {
      value = JSON.parse(value);
    } catch {
      return null;
    }
  }
  if (!value || typeof value !== "object") {
    return null;
  }
  const sections = Array.isArray(value.sections)
    ? value.sections.map(normalizeNavSection).filter(Boolean)
    : [];
  return {
    enabled: Boolean(value.enabled),
    includeUnassigned: value.includeUnassigned !== false,
    unassignedLabel:
      typeof value.unassignedLabel === "string" && value.unassignedLabel.trim()
        ? value.unassignedLabel.trim()
        : null,
    unassignedIcon: normalizeNavSectionIcon(value.unassignedIcon),
    unassignedId:
      typeof value.unassignedId === "string" && value.unassignedId.trim()
        ? value.unassignedId.trim()
        : null,
    sections
  };
}

function normalizeNavSection(section, index) {
  if (!section || typeof section !== "object") {
    return null;
  }
  const id = (section.id || section.label || `section-${index + 1}`)
    .toString()
    .trim();
  if (!id) {
    return null;
  }
  const label = (section.label || toTitleCase(id) || id).toString().trim();
  const icon = normalizeNavSectionIcon(section.icon) || "blocks";
  const items = Array.isArray(section.items)
    ? section.items.map((item) => item.toString().trim()).filter(Boolean)
    : [];
  return { id, label, icon, items };
}

function normalizeNavSectionIcon(value) {
  if (!value) {
    return null;
  }
  const normalized = value.toString().trim().toLowerCase();
  return NAV_SECTION_ICONS.includes(normalized) ? normalized : null;
}

function buildNavItemId(item) {
  const base = (item.path || item.label || "item").toString().toLowerCase();
  return base.replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
}

function getDefaultNavIcon(item) {
  const pathName = (item.path || "").toLowerCase();
  if (pathName === "/") return "home";
  if (pathName === "/commands") return "commands";
  if (pathName === "/leaderboards") return "leaderboards";
  if (pathName === "/stats") return "stats";
  if (pathName === "/profile") return "profile";
  if (pathName === "/moderator") return "users";
  if (pathName.startsWith("/pages/")) return "pages";
  if (pathName === "/admin") return "admin";
  if (pathName === "/admin/settings") return "settings";
  if (pathName === "/admin/navigation") return "settings";
  if (pathName === "/admin/theming") return "theming";
  if (pathName === "/admin/privileges") return "privileges";
  if (pathName === "/admin/diagnostics") return "admin";
  if (pathName === "/admin/logs") return "logs";
  if (pathName === "/admin/updates") return "updates";
  if (pathName === "/admin/commands") return "commands";
  if (pathName === "/admin/command-policies") return "commands";
  if (pathName === "/admin/pages") return "pages";
  if (pathName === "/admin/resources") return "resources";
  if (pathName === "/admin/users") return "users";
  if (pathName === "/admin/plugins") return "plugins";
  if (pathName === "/moderator") return "users";
  if (pathName.startsWith("/plugins/moderation/tos-bans")) return "moderation";
  if (pathName.startsWith("/plugins/moderation")) return "moderation";
  if (pathName.startsWith("/plugins")) return "plugins";
  if (pathName.startsWith("/moderator")) return "moderation";
  return "pages";
}

function isActivePath(itemPath, currentPath) {
  if (!itemPath || !currentPath) {
    return false;
  }
  if (itemPath === "/") {
    return currentPath === "/";
  }
  return currentPath === itemPath || currentPath.startsWith(`${itemPath}/`);
}

function unavailableAssistantPanel(panel, reasonCode) {
  return {
    available: false,
    panel_id: panel.id,
    status: "offline",
    reason_code: reasonCode
  };
}

function renderAssistantPanel(app, panel, user) {
  const requiredLocals = Array.isArray(panel.requiredLocals) ? panel.requiredLocals : [];
  const locals = { ...(panel.locals || {}), user };
  const missingLocals = requiredLocals.filter((key) => locals[key] === undefined || locals[key] === null);
  if (!fs.existsSync(panel.view)) {
    return Promise.reject(new Error(`Assistant panel template does not exist: ${panel.view}`));
  }
  try {
    fs.accessSync(panel.view, fs.constants.R_OK);
  } catch {
    return Promise.reject(new Error(`Assistant panel template is not readable: ${panel.view}`));
  }
  if (missingLocals.length) {
    const error = new Error(`Assistant panel is missing required locals: ${missingLocals.join(", ")}`);
    error.missingLocals = missingLocals;
    return Promise.reject(error);
  }
  return new Promise((resolve, reject) => {
    app.render(
      panel.view,
      locals,
      (error, html) => {
        if (error) return reject(error);
        const content = String(html || "");
        if (!content.trim()) return reject(new Error(`Assistant panel ${panel.id} rendered empty HTML.`));
        if (!content.includes(`data-assistant-panel-id="${panel.id}"`)) {
          return reject(new Error(`Assistant panel ${panel.id} HTML is missing its panel marker.`));
        }
        return resolve({ html: content });
      }
    );
  });
}

module.exports = {
  createWebServer
};
