import "reflect-metadata"
import { NestFactory } from "@nestjs/core"
import { AppModule } from "./app.module"
import * as dotenv from "dotenv"
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"
import * as process from "node:process"
import * as express from "express"
import { ValidationPipe } from "@nestjs/common"
import { validationError } from "./common/response/validation-error.response"
import basicAuth from "express-basic-auth"
import { getCurrentEnvironment } from "./utils/helpers"

dotenv.config()

const bootstrap = async () => {
  try {
    const port = process.env.PORT || 6000
    const app = await NestFactory.create(AppModule)

    app.setGlobalPrefix("api")
    app.use(express.static("public"))
    app.enableCors({
      origin: true,
      credentials: true,
    })
    if (process.env.NODE_ENV != "production") {
      // Basic Auth middleware
      const swaggerAdmin = process.env.SWAGGER_USERNAME
      const swaggerPassword = process.env.SWAGGER_PASSWORD

      getCurrentEnvironment() != "local" &&
        app.use(
          "/api/docs",
          basicAuth({
            users: { [swaggerAdmin]: swaggerPassword }, // Replace with your credentials
            challenge: true,
            realm: "Swagger API",
            unauthorizedResponse:
              "Access denied. Kindly get in touch with the developer.",
          }),
        )
      const config = new DocumentBuilder()
        .setTitle("Nest Base Structure API")
        .setDescription("API Documentation for Nest Base Structure")
        .setVersion("1.0")
        .setContact("Devendra Mali", "", "devendra@moweb.com")
        .addBearerAuth(
          {
            type: "apiKey",
            in: "header",
            name: "Authorization",
            description:
              "Enter your custom token in the format `Token <your_token>`",
          },
          "access-token",
        )
        .build()

      const document = SwaggerModule.createDocument(app, config)
      SwaggerModule.setup("api/docs", app, document, {
        swaggerOptions: {
          persistAuthorization: true,
        },
      })
    }

    // Global validation pipe
    app.useGlobalPipes(
      new ValidationPipe({
        exceptionFactory: validationError,
        transform: true, // Automatically transform payload to DTO class
        transformOptions: {
          enableImplicitConversion: true,
        },
        whitelist: true, // Strip properties that do not have decorators
      }),
    )

    await app.listen(port)

    if (process.env.ENABLE_CONSOLE != "true") {
      console.log = () => {}
    }

    console.log(`server is running at http://localhost:${port}`)
    console.log(`Swagger is running at http://localhost:${port}/api/docs`)
  } catch (error) {
    console.log("error================", error)
  }
}
bootstrap()
