import 'dotenv/config'; // loads .env (just NODE_ENV) — must be the first import, before any other module reads process.env at its own top level
import { logger } from './utils/logger.js';
import { getServerConfig } from '../config/database.js';
import { buildApp } from './app.js';
import { refreshCache as refreshStageCache } from './services/stage.service.js';
import { refreshCache as refreshOfficeCalendarCache } from './services/officeCalendar.service.js';

// Last-resort safety net: request-handler errors already go through
// Fastify's own error handler and can't reach here, but anything that
// rejects/throws outside that lifecycle (an event-emitter listener, a
// background task) would otherwise crash the whole process for every user.
// Logging and continuing keeps the server up; the alternative (letting Node
// crash) takes down every in-flight request for something that's often a
// single bad event, not a corrupted process.
process.on('unhandledRejection', (reason) => {
  logger.error({ err: reason }, 'Unhandled promise rejection');
});
process.on('uncaughtException', (err) => {
  logger.error({ err }, 'Uncaught exception');
});

async function main() {
  const app = await buildApp();
  const { port, host } = getServerConfig();

  // Stages are read synchronously from an in-memory cache on hot paths
  // (stage advance, dashboard KPIs, reports, activity log) — populate it
  // once before accepting traffic; stage.service.ts keeps it fresh after
  // any create/update/delete/reorder.
  await refreshStageCache();
  // Office hours/holiday calendar is likewise read synchronously (see
  // officeCalendar.service.ts's officeMinutesElapsed, called per idle order
  // line on the dashboard/orders hot paths) — populate before accepting traffic.
  await refreshOfficeCalendarCache();

  try {
    await app.listen({ port, host });
    logger.info(`Server running on http://${host}:${port}`);
    logger.info(`Environment: ${process.env.NODE_ENV ?? 'development'}`);
  } catch (err) {
    logger.error({ err }, 'Failed to start server');
    process.exit(1);
  }
}

main();
