const { migrate } = require("./services/db");
const { ensureDefaults, getSetting, setSetting } = require("./services/settings");
const { createWebServer } = require("./web/server");
const { startBot, stopBot } = require("./services/discord");
const { startTwitchBot, stopTwitchBot } = require("./services/twitch");
const { startYouTubeBot, stopYouTubeBot } = require("./services/youtube");
const pluginService = require("./services/plugins");
const { loadEnabled } = pluginService;
const stopPlugins =
  typeof pluginService.stopPlugins === "function"
    ? pluginService.stopPlugins
    : async () => {};
const { checkForUpdates, pullUpdates, requestRestart } = require("./services/updater");
const { createCommandRouter } = require("./services/command-router");
const { registerTopCommand } = require("./services/top");
const logger = require("./services/logger");
const { isPlatformEnabled } = require("./services/platforms");
const { registerCorePlaceholders } = require("./services/placeholders");
const { overlayConnectorManager } = require("./services/overlay-connectors");
const {
  isSafeModeRequested,
  markStartupVerification
} = require("./services/recovery-mode");

async function main() {
  migrate();
  ensureDefaults();
  registerCorePlaceholders();
  logger.hookConsole();
  const safeModeRequested = isSafeModeRequested();
  const startupMarker = markStartupVerification();
  if (startupMarker?.status === "stale") {
    console.warn("Recovery marker detected from incomplete update; start with LUMI_SAFE_MODE=1 for recovery tools.");
  }

  const settingsApi = { getSetting, setSetting };
  const commandRouter = createCommandRouter({ settings: settingsApi });
  registerTopCommand({ commandRouter, settings: settingsApi });
  let discordClient = null;
  let twitchClient = null;
  let youtubeClient = null;

  if (!safeModeRequested && isPlatformEnabled("discord")) {
    try {
      discordClient = await startBot({ commandRouter });
    } catch (error) {
      console.error("Discord bot failed to start", error);
    }
  }

  if (!safeModeRequested && isPlatformEnabled("twitch")) {
    try {
      twitchClient = await startTwitchBot({ commandRouter });
    } catch (error) {
      console.error("Twitch bot failed to start", error);
    }
  }

  if (!safeModeRequested && isPlatformEnabled("youtube")) {
    try {
      youtubeClient = await startYouTubeBot({ commandRouter });
    } catch (error) {
      console.error("YouTube bot failed to start", error);
    }
  }

  const app = createWebServer({
    discordClient,
    loadPlugins: (appInstance, web, webhooks) => {
      if (safeModeRequested) return;
      loadEnabled({
        app: appInstance,
        discordClient,
        twitchClient,
        youtubeClient,
        settings: settingsApi,
        web,
        webhooks,
        commandRouter
      });
    }
  });

  if (!safeModeRequested) {
    overlayConnectorManager.start().catch((error) => {
      console.error("OBS overlay connectors failed to start", error);
    });
  }

  const port = Number(process.env.PORT || 3000);
  app.listen(port, () => {
    console.log(`WebUI listening on http://localhost:${port}`);
  });

  const autoUpdateEnabled = getSetting("auto_update_enabled", false);
  const intervalMinutes = getSetting("auto_update_interval_minutes", 60);
  if (!safeModeRequested && autoUpdateEnabled) {
    const intervalMs = Math.max(5, Number(intervalMinutes)) * 60 * 1000;
    let autoUpdateRunning = false;
    setInterval(async () => {
      if (autoUpdateRunning) return;
      autoUpdateRunning = true;
      try {
        const remote = getSetting("git_remote", "origin");
        const branch = getSetting("git_branch", "main");
        if (checkForUpdates(remote, branch)) {
          await pullUpdates(remote, branch);
          requestRestart();
        }
      } catch (error) {
        console.error("Auto-update failed", error);
      } finally {
        autoUpdateRunning = false;
      }
    }, intervalMs);
  }

  let shuttingDown = false;
  const shutdown = async () => {
    if (shuttingDown) {
      return;
    }
    shuttingDown = true;
    await overlayConnectorManager.stop();
    await stopPlugins();
    await stopBot();
    await stopTwitchBot();
    await stopYouTubeBot();
    process.exit(0);
  };

  process.on("SIGINT", shutdown);
  process.on("SIGTERM", shutdown);
}

main();
