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, VersioningType } from "@nestjs/common"
import { validationError } from "./common/response/validation-error.response"
import basicAuth from "express-basic-auth"
import { getCurrentEnvironment } from "./utils/helpers"
import { IoAdapter } from "@nestjs/platform-socket.io"

dotenv.config()

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

    app.setGlobalPrefix("api")

    // When no version is passed (e.g. /api/hospitals), treat as v1 (e.g. /api/v1/hospitals)
    app.use((req: express.Request, _res, next) => {
      const path = req.url?.split("?")[0] ?? ""
      if (path.match(/^\/api\/(?!v\d+|docs)/)) {
        req.url = req.url!.replace(/^(\/api)\/(?!v\d+|docs)/, "$1/v1/")
      }
      next()
    })

    // Enable API versioning with URL-based versioning (e.g., /api/v1/hospitals)
    app.enableVersioning({
      type: VersioningType.URI,
      defaultVersion: "1", // Default version if not specified
    })

    app.use(express.static("public"))
    app.enableCors()
    app.useWebSocketAdapter(new IoAdapter(app))

    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("Nuskin API Documentation")
        .setDescription("API Documentation for Nuskin")
        .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)
    }

    // 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
      }),
    )

    // Serve public folder

    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()
