// Importar reflect-metadata al inicio (requerido por TypeORM)
import 'reflect-metadata';

import app from './app.js';
import { config } from './config/index.js';
import { testConnection, closePool } from './config/database.js';
import { initializeTypeORM, closeTypeORM } from './config/typeorm.js';
import { initializeRedis, closeRedis } from './config/redis.js';
import { logger } from './shared/utils/logger.js';

async function bootstrap(): Promise<void> {
  logger.info('Starting ERP Generic Backend...', {
    env: config.env,
    port: config.port,
  });

  // Test database connection (pool pg existente)
  const dbConnected = await testConnection();
  if (!dbConnected) {
    logger.error('Failed to connect to database. Exiting...');
    process.exit(1);
  }

  // Initialize TypeORM DataSource
  const typeormConnected = await initializeTypeORM();
  if (!typeormConnected) {
    logger.error('Failed to initialize TypeORM. Exiting...');
    process.exit(1);
  }

  // Initialize Redis (opcional - no detiene la app si falla)
  await initializeRedis();

  // Start server
  const server = app.listen(config.port, () => {
    logger.info(`Server running on port ${config.port}`);
    logger.info(`API available at http://localhost:${config.port}${config.apiPrefix}`);
    logger.info(`Health check at http://localhost:${config.port}/health`);
  });

  // Graceful shutdown
  const shutdown = async (signal: string) => {
    logger.info(`Received ${signal}. Starting graceful shutdown...`);

    server.close(async () => {
      logger.info('HTTP server closed');

      // Cerrar conexiones en orden
      await closeRedis();
      await closeTypeORM();
      await closePool();

      logger.info('Shutdown complete');
      process.exit(0);
    });

    // Force shutdown after 10s
    setTimeout(() => {
      logger.error('Forced shutdown after timeout');
      process.exit(1);
    }, 10000);
  };

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

bootstrap().catch((error) => {
  logger.error('Failed to start server', { error: error.message });
  process.exit(1);
});
