
import 'reflect-metadata'; // For NestJS DI (before any other imports)

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { writeFileSync } from 'fs';
import { join } from 'path';
import { AppModule } from './app.module';
import { AuthenticationGuard } from './domain/auth/AuthenticationGuard';
import { AuthorizationGuard } from './domain/auth/AuthorizationGuard';
import { FeatureAvailabilityGuard } from './domain/policy/FeatureAvailabilityGuard';

import { getGenerateOpenapi } from './env';

async function bootstrap() {
  const generateOpenapi = getGenerateOpenapi();
  const app = await NestFactory.create(AppModule, generateOpenapi ? { logger: false } : undefined);

  // Website runs on a different origin in dev/docker (e.g. http://localhost:3000 -> http://localhost:3001),
  // and our website HTTP client uses `credentials: 'include'`, so we must support CORS with credentials.
  app.enableCors({
    credentials: true,
    origin: (origin, callback) => {
      if (!origin) {
        return callback(null, false);
      }
      return callback(null, origin);
    },
  });

  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      forbidNonWhitelisted: true,
      transform: true,
    }),
  );

  app.useGlobalGuards(
    app.get(AuthenticationGuard),
    app.get(AuthorizationGuard),
    app.get(FeatureAvailabilityGuard),
  );

  // Swagger/OpenAPI configuration
  const config = new DocumentBuilder()
    .setTitle('GridPilot API')
    .setDescription('GridPilot API documentation')
    .setVersion('1.0')
    .addTag('dashboard', 'Dashboard endpoints')
    .addTag('races', 'Race management endpoints')
    .addTag('leagues', 'League management endpoints')
    .addTag('teams', 'Team management endpoints')
    .addTag('drivers', 'Driver management endpoints')
    .addTag('sponsors', 'Sponsor management endpoints')
    .addTag('payments', 'Payment and billing endpoints')
    .addTag('media', 'Media and file management endpoints')
    .addTag('analytics', 'Analytics and reporting endpoints')
    .build();

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const document = SwaggerModule.createDocument(app as any, config);

  // Serve Swagger UI at /api/docs
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  SwaggerModule.setup('api/docs', app as any, document);

  // Export OpenAPI spec as JSON file when GENERATE_OPENAPI env var is set
  if (generateOpenapi) {
    const outputPath = join(__dirname, '../openapi.json');
    writeFileSync(outputPath, JSON.stringify(document, null, 2));
    console.log(`✅ OpenAPI spec generated at: ${outputPath}`);
    await app.close();
    process.exit(0);
  }

  await app.listen(3000);
}
bootstrap();
