import { app } from './app.js';
import { env } from './config/env.js';
import { tenantDb } from './config/database.js';
import { invalidateTenantCache } from './middlewares/plan-limits.middleware.js';
import { startSatSyncJob } from './jobs/sat-sync.job.js';
import { startWeeklyUpdateJob } from './jobs/weekly-update.job.js';
import { startMetricasInvalidationsJob } from './jobs/metricas-invalidations.job.js';
import { startNotificationsJob } from './jobs/notifications.job.js';

const PORT = parseInt(env.PORT, 10);

const server = app.listen(PORT, '0.0.0.0', () => {
  console.log(`API Server running on http://0.0.0.0:${PORT}`);
  console.log(`Environment: ${env.NODE_ENV}`);

  // Iniciar jobs programados.
  // En dev, los crons se omiten por default para no consumir recursos ni
  // disparar efectos (SAT queries, emails). Con ENABLE_CRONS_IN_DEV=1 se
  // arrancan los crons seguros (SAT sync/retry, métricas); el weekly-update
  // sigue siendo prod-only porque envía emails a owners reales.
  const cronsEnabled = env.NODE_ENV === 'production' || process.env.ENABLE_CRONS_IN_DEV === '1';
  const sendRealEmails = env.NODE_ENV === 'production';
  if (cronsEnabled) {
    startSatSyncJob();
    startMetricasInvalidationsJob();
    if (sendRealEmails) {
      startWeeklyUpdateJob();
      startNotificationsJob();
    } else {
      console.log('[Cron] weekly-update + notifications omitidos en dev (evita emails reales)');
    }
    console.log(`[Cron] SAT + metricas activos (NODE_ENV=${env.NODE_ENV}, ENABLE_CRONS_IN_DEV=${process.env.ENABLE_CRONS_IN_DEV ?? 'unset'})`);
  } else {
    console.log('[Cron] Jobs omitidos en dev (usar ENABLE_CRONS_IN_DEV=1 para activar)');
  }
});

// Graceful shutdown — close all tenant DB pools before exiting
const gracefulShutdown = async (signal: string) => {
  console.log(`${signal} received. Shutting down gracefully...`);
  server.close(() => {
    console.log('HTTP server closed');
  });
  await tenantDb.shutdown();
  process.exit(0);
};

process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));

// PM2 cluster: cross-worker cache invalidation
process.on('message', (msg: any) => {
  if (msg?.type === 'invalidate-tenant-cache' && msg.tenantId) {
    tenantDb.invalidatePool(msg.tenantId);
    invalidateTenantCache(msg.tenantId);
  }
});
