import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import * as qs from 'qs';
import { AppModule } from './app.module';

import { ConfigService } from '@nestjs/config';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    logger: ['error', 'warn', 'log', 'debug'],
  });
  app.set('query parser', (str: string) => qs.parse(str));
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      transform: true,
    }),
  );
  const configService = app.get(ConfigService);
  const port = configService.getOrThrow<number>('PORT');
  const nodeEnv = configService.getOrThrow<string>('NODE_ENV');
  const databaseUrl = configService.getOrThrow<string>('DATABASE_URL');
  const jwtSecret = configService.getOrThrow<string>('JWT_SECRET');
  const jwtExpiresIn = configService.getOrThrow<string>('JWT_EXPIRES_IN');
  const clientUrl = configService.getOrThrow<string>('CLIENT_URL');

  console.log('Config verification:');
  console.log('PORT:', port);
  console.log('NODE_ENV:', nodeEnv);
  console.log('DATABASE_URL:', databaseUrl ? '***' : undefined);
  console.log('JWT_SECRET:', jwtSecret ? '***' : undefined);
  console.log('JWT_EXPIRES_IN:', jwtExpiresIn);
  console.log('CLIENT_URL:', clientUrl);
  
  const allowedOrigins = clientUrl.split(',').map(o => o.trim());
  console.log('CORS allowed:', allowedOrigins);

  /**
   * Production-grade CORS logic
   */
  function isOriginAllowed(origin: string): boolean {
    return allowedOrigins.some(pattern => {
      // allow all (dev)
      if (pattern === '*') return true;

      // exact match
      if (pattern === origin) return true;

      // wildcard subdomain (*.example.com)
      if (pattern.startsWith('*.')) {
        const domain = pattern.slice(2);
        return (
          origin.endsWith(`.${domain}`) ||
          origin === `https://${domain}` ||
          origin === `http://${domain}`
        );
      }

      return false;
    });
  }

  app.enableCors({
    origin: (origin, callback) => {
      // allow non-browser clients (Postman, curl, mobile apps)
      if (!origin) return callback(null, true);

      if (isOriginAllowed(origin)) {
        return callback(null, true);
      }

      console.warn(`Blocked CORS origin: ${origin}`);
      return callback(new Error(`Not allowed by CORS: ${origin}`));
    },
    methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
    credentials: true, // safe for JWT headers; required if using cookies
  });

  app.useStaticAssets(join(process.cwd(), 'uploads'), {
    prefix: '/uploads/',
  });

  /**
   * Swagger Configuration
   */
  const config = new DocumentBuilder()
    .setTitle('API Documentation')
    .setDescription('API documentation for the service')
    .setVersion('1.0')
    .addBearerAuth()
    .build();

  const document = SwaggerModule.createDocument(app, config);
  if (configService.get('NODE_ENV') !== 'production') {
    SwaggerModule.setup('api-docs', app, document);
  }

  await app.listen(configService.getOrThrow<number>('PORT'));
}

bootstrap();
