import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { useContainer } from 'class-validator';
import { AppModule } from './app.module';
// import { PORT } from '../src/config/common';
import { GlobalExceptionFilter } from './middleware/global-exception.filter';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { SWAGGER_CONSTANTS, SWAGGER_TAGS } from './utility/constants';
import { MTypeErrorHandler } from './middleware/global-error-handler';
import * as session from 'express-session'; // Import express-session
import * as passport from 'passport';
import * as bodyParser from 'body-parser';
import { NestExpressApplication } from '@nestjs/platform-express';
import { resolve } from 'path';

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  // Use express-session middleware
  app.use(
    session({
      secret: '34#$%123MONTYPE@@^&*)', // replace with your own secret
      resave: false,
      saveUninitialized: false,
      cookie: { secure: false }, // set to true if your app is on https
    }),
  );
  app.use(passport.initialize());
  app.use(passport.session());
  // enable validation globally
  // this is from NestJS docs
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      transform: true,
    }),
  );

  // enable DI for class-validator
  // this is an important step, for further steps in this article
  useContainer(app.select(AppModule), { fallbackOnErrors: true });
  //app.enableCors(CORS_OPTIONS);
  app.enableCors({
    origin: [
      'https://dev.jobvumi.com',
      'https://www.dev.jobvumi.com',
      'http://localhost:3000',
      'http://127.0.0.1:3000',
    ],
    credentials: true,
    exposedHeaders: ['Content-Disposition'],
  });

  // const frontendOrigin = process.env.FRONTEND_ORIGIN || 'http://localhost:8080';

  // Trust proxy headers (for production Apache/nginx)
  app.set('trust proxy', true);

  app.useGlobalFilters(new GlobalExceptionFilter());

  const config = new DocumentBuilder()
    .setTitle(SWAGGER_CONSTANTS.TITLE)
    .setDescription(SWAGGER_CONSTANTS.DESCRIPTION)
    .setVersion(SWAGGER_CONSTANTS.VERSION)
    // .addServer('http://localhost:4000')
    .addServer('https://dev.jobvumi.com/api')
    .addBearerAuth(
      { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' },
      'access-token',
    ) // Add this line
    .addTag(SWAGGER_TAGS.COHORT)
    .addTag(SWAGGER_TAGS.Activity)
    .addTag(SWAGGER_TAGS.Analytics)
    .addTag(SWAGGER_TAGS.Area)
    .addTag(SWAGGER_TAGS.Associateusers)
    .addTag(SWAGGER_TAGS.Associates)
    .addTag(SWAGGER_TAGS.City)
    .addTag(SWAGGER_TAGS.Companies)
    .addTag(SWAGGER_TAGS.Company_recruiters)
    .addTag(SWAGGER_TAGS.Config_settings)
    .addTag(SWAGGER_TAGS.Country)
    .addTag(SWAGGER_TAGS.Dashboard)
    .addTag(SWAGGER_TAGS.Education_levels)
    .addTag(SWAGGER_TAGS.Experiences)
    .addTag(SWAGGER_TAGS.FranchiseHistory)
    .addTag(SWAGGER_TAGS.Franchises)
    .addTag(SWAGGER_TAGS.Industries)
    .addTag(SWAGGER_TAGS.Seekerjob_alerts)
    .addTag(SWAGGER_TAGS.JobApplications)
    .addTag(SWAGGER_TAGS.JobLevel)
    .addTag(SWAGGER_TAGS.Job_perks)
    .addTag(SWAGGER_TAGS.Job_posts)
    .addTag(SWAGGER_TAGS.JobSaved)
    .addTag(SWAGGER_TAGS.Job_type)
    .addTag(SWAGGER_TAGS.Job_views)
    .addTag(SWAGGER_TAGS.Languages)
    .addTag(SWAGGER_TAGS.Locations)
    .addTag(SWAGGER_TAGS.Modules)
    .addTag(SWAGGER_TAGS.Perks)
    .addTag(SWAGGER_TAGS.Recruiter_cv_usage)
    .addTag(SWAGGER_TAGS.Recruiter_verification)
    .addTag(SWAGGER_TAGS.Reports)
    .addTag(SWAGGER_TAGS.RoleAccess)
    .addTag(SWAGGER_TAGS.Role_levels)
    .addTag(SWAGGER_TAGS.Roles)
    .addTag(SWAGGER_TAGS.SeekerAddress)
    .addTag(SWAGGER_TAGS.SeekerEducation)
    .addTag(SWAGGER_TAGS.SeekerExperience)
    .addTag(SWAGGER_TAGS.Seekerpreferences)
    .addTag(SWAGGER_TAGS.Apiseeker_resumes)
    .addTag(SWAGGER_TAGS.SeekerSocialLinks)
    .addTag(SWAGGER_TAGS.Skills)
    .addTag(SWAGGER_TAGS.SocialPlatform)
    .addTag(SWAGGER_TAGS.State)
    .addTag(SWAGGER_TAGS.Stats)
    .addTag(SWAGGER_TAGS.Tags)
    .addTag(SWAGGER_TAGS.TempFranchise)
    .addTag(SWAGGER_TAGS.TempTrainers)
    .addTag(SWAGGER_TAGS.Users)
    .addTag(SWAGGER_TAGS.ai_interview_schedules)
    .addTag(SWAGGER_TAGS.AI_Screening)
    .addTag(SWAGGER_TAGS.job_post_ai_settings)
    .addTag(SWAGGER_TAGS.question_bank)
    .addTag(SWAGGER_TAGS.mock_test_attempts)
    .addTag(SWAGGER_TAGS.user_ai_interviews)
    .addTag(SWAGGER_TAGS.Mobile_Auth)
    .addTag(SWAGGER_TAGS.mobile_home)
    .addTag(SWAGGER_TAGS.mock_templates)
    .addTag(SWAGGER_TAGS.mobile_seeker_profile_settings)
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup(SWAGGER_CONSTANTS.PATH, app, document, {
    swaggerOptions: {
      tagsSorter: 'alpha',
      operationsSorter: 'alpha',
      docExpansion: 'none',
    },
  });
  const registerExceptionHandler = function (): void {
    process.on('uncaughtException', MTypeErrorHandler.handleException);
    process.on('unhandledRejection', MTypeErrorHandler.handleRejectedPromise);
  };
  registerExceptionHandler();

  // Increase the limit of the request body.
  app.use(bodyParser.json({ limit: '50mb' }));
  app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));

  // Serve static files from uploads directory
  app.useStaticAssets(resolve(__dirname, '..', 'uploads'), {
    prefix: '/uploads/',
  });
  // console.log('Serving static files from:', resolve(__dirname, '..', 'uploads'));

  await app.listen(4000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}

bootstrap();
