import "server-only";

import { runDomainTick } from "../domains/run";
import { env } from "../env";
import { logger } from "../logger";
import { runSchedulerTick } from "./run";

const globalForTicker = globalThis as unknown as { btsSchedulerTicker?: NodeJS.Timeout };

async function tick() {
  // Side by side: a long health run must not delay the daily domain check, or the other way round.
  await Promise.all([
    runSchedulerTick().catch((error) => {
      // Never let a bad tick kill the timer (e.g. the database being briefly down).
      logger.error("scheduler.tick.failed", { error });
    }),
    runDomainTick().catch((error) => logger.error("domain.tick.failed", { error })),
  ]);
}

/** Start the in-process scheduler once per server process. */
export function startSchedulerTicker() {
  if (globalForTicker.btsSchedulerTicker) return;

  const intervalMs = env.SCHEDULER_TICK_SECONDS * 1000;
  const timer = setInterval(tick, intervalMs);
  timer.unref(); // don't keep the process alive just for the scheduler
  globalForTicker.btsSchedulerTicker = timer;

  // First look shortly after boot, so a slot missed while the server was down is caught up promptly.
  setTimeout(tick, 5_000).unref();
  logger.info("scheduler.ticker.started", { intervalSeconds: env.SCHEDULER_TICK_SECONDS });
}
