// Load environment variables
require('./config/loadEnv')

// Import necessary modules
const express = require('express')
const bodyParser = require('body-parser')
const swaggerUi = require('swagger-ui-express')
const specs = require('./config/swagger.config')
const logger = require('./utils/logger')
const { connectDB } = require('./config/database.config')
const { syncModels } = require('./models')
const { EventEmitter } = require('events')
const cors = require('cors')
const {
  countHttpRequests,
  measureHttpRequestDuration,
  metricsEndpoint,
} = require('./config/metrics')

// Set MaxListeners
EventEmitter.defaultMaxListeners = 50

// Initialize Express application
const app = express()

// Middleware for parsing request body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

// CORS setup
const corsOptions = {
  origin: '*',
  methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
}

app.use(cors(corsOptions))

// Swagger setup
if (process.env.NODE_ENV !== 'production') {
  app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs))
}

// Routes
const routes = require('./routes')
app.use('/api', routes)

// Metrics Middleware
app.use(countHttpRequests)
app.use(measureHttpRequestDuration)

// Metrics Endpoint
app.get('/metrics', metricsEndpoint)

// Connect Database and Sync Models
connectDB().then(syncModels)

// Handle uncaughtException
process.on('uncaughtException', (err) => {
  logger.error('There was an uncaught error', err)
})

// Export the Express app
module.exports = app
