/**
 * Application Entry Point
 *
 * Initializes the server and starts listening for requests
 */

import { createServer } from './server';
import { config, initializeConfigFromDatabase } from './config';
import { validatePayPalConfig } from './config/paypalValidation';
import { logger } from './utils/logger';
import { PrismaClient } from '@prisma/client';
import { translationQueue } from './queue';
import { configureBulkQueueDispatcher, startBulkQueueDispatcher, stopBulkQueueDispatcher } from './queue/bulkQueueDispatcher';

// Initialize Prisma client
export const prisma = new PrismaClient({
  log: config.nodeEnv === 'development' ? ['query', 'error', 'warn'] : ['error'],
});

configureBulkQueueDispatcher(prisma.translationJob);

// Handle graceful shutdown
async function gracefulShutdown(signal: string) {
  logger.info(`Received ${signal}, shutting down gracefully...`);

  await stopBulkQueueDispatcher();
  await translationQueue.close();

  // Disconnect Prisma
  await prisma.$disconnect();

  logger.info('Prisma disconnected');

  process.exit(0);
}

// Register shutdown handlers
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));

// Start server
async function start() {
  try {
    // Test database connection
    await prisma.$connect();
    logger.info('Database connected successfully');

    await translationQueue.isReady();
    await startBulkQueueDispatcher();

    // Initialize configuration from database
    try {
      await initializeConfigFromDatabase();
      logger.info('Configuration loaded from database with .env fallback');
    } catch (error) {
      logger.error('Failed to initialize database configuration', { error });
      logger.warn('Continuing with .env configuration only');
    }

    // Validate PayPal configuration
    const paypalValidation = validatePayPalConfig();
    if (!paypalValidation.ok) {
      const missingList = paypalValidation.missing.join(', ');
      if (config.nodeEnv === 'production') {
        logger.error(
          `[PayPal] FATAL: missing required PayPal credentials — server will not start. Missing: ${missingList}`
        );
        process.exit(1);
      } else {
        logger.warn(
          `[PayPal] Missing credentials (non-prod — continuing with mock flow). Missing: ${missingList}`
        );
      }
    } else {
      logger.info(`[PayPal] Configuration OK (mode: ${paypalValidation.mode})`);
    }
    // Create Express app
    const app = createServer();

    // Start listening
    const server = app.listen(config.port, () => {
      logger.info(`Server started on port ${config.port}`);
      logger.info(`Environment: ${config.nodeEnv}`);
      logger.info(`API URL: ${config.apiUrl}`);
    });

    // Handle server errors
    server.on('error', (error: NodeJS.ErrnoException) => {
      if (error.code === 'EADDRINUSE') {
        logger.error(`Port ${config.port} is already in use`);
      } else {
        logger.error('Server error:', error);
      }
      process.exit(1);
    });

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

// Start the application
start();
