import { NestFactory } from '@nestjs/core';
import { ValidationPipe, Logger as NestLogger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import helmet from 'helmet';
import { Logger, LoggerErrorInterceptor } from 'nestjs-pino';

async function bootstrap() {
  const logger = new NestLogger('Bootstrap');

  logger.log('🔄 Starting application...');

  const app = await NestFactory.create(AppModule, { bufferLogs: true });

  // Use Pino Logger
  app.useLogger(app.get(Logger));
  app.useGlobalInterceptors(new LoggerErrorInterceptor());

  // Security Headers
  app.use(
    helmet({
      contentSecurityPolicy: false,
      crossOriginEmbedderPolicy: false,
    }),
  );

  // Graceful Shutdown (Prisma & Docker)
  app.enableShutdownHooks();

  // Get config service
  const configService = app.get(ConfigService);
  const port = configService.get<number>('PORT', 3000);
  const nodeEnv = configService.get('NODE_ENV', 'development');

  // Enable CORS
  app.enableCors({
    origin: true,
    credentials: true,
  });

  // Global prefix
  app.setGlobalPrefix('api');

  // Validation pipe (Strict)
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      transform: true,
      forbidNonWhitelisted: true,
      transformOptions: {
        enableImplicitConversion: true,
      },
    }),
  );

  // Swagger setup
  const swaggerConfig = new DocumentBuilder()
    .setTitle('HarunCAN Studio API')
    .setDescription(
      'HarunCAN Studio backend API - NestJS with authentication, i18n, and PostgreSQL',
    )
    .setVersion('1.0')
    .addBearerAuth()
    .addTag('Auth', 'Authentication endpoints')
    .addTag('Users', 'User management endpoints')
    .addTag('Admin', 'Admin management endpoints')
    .addTag('Health', 'Health check endpoints')
    .build();

  logger.log('Initializing Swagger...');
  const document = SwaggerModule.createDocument(app, swaggerConfig);
  SwaggerModule.setup('api/docs', app, document, {
    swaggerOptions: {
      persistAuthorization: true,
    },
  });
  logger.log('Swagger initialized');

  try {
    logger.log(`Attempting to listen on port ${port}...`);
    await app.listen(port, '0.0.0.0');
  } catch (err: any) {
    logger.error('Failed to bind to port:', err.message, err.stack);
    process.exit(1);
  }

  logger.log('═══════════════════════════════════════════════════════════');
  logger.log(`🚀 Server is running on: http://localhost:${port}/api`);
  logger.log(`📚 Swagger documentation: http://localhost:${port}/api/docs`);
  logger.log(`💚 Health check: http://localhost:${port}/api/health`);
  logger.log(`🌍 Environment: ${nodeEnv.toUpperCase()}`);
  logger.log('═══════════════════════════════════════════════════════════');

  if (nodeEnv === 'development') {
    logger.warn('⚠️  Running in development mode');
  }
}

void bootstrap();
