/**
 * Express Application Setup
 * Main application configuration and middleware setup
 */

// Import Express framework
const express = require('express');
// Import CORS middleware for cross-origin requests
const cors = require('cors');
// Import Helmet for security headers
const helmet = require('helmet');
// Import Morgan for HTTP request logging
const morgan = require('morgan');
// Import Express Rate Limit for API rate limiting
const rateLimit = require('express-rate-limit');
// Import compression middleware for response compression
const compression = require('compression');
// Import app configuration
const appConfig = require('./config/app');
// Import logger utility
const logger = require('./utils/logger');
// Import routes
const routes = require('./routes');
// Import error handling middlewares
const { errorHandler, notFoundHandler } = require('./middlewares/errorHandler');
// Import Swagger setup (only in development)
const setupSwagger = require('./swagger');

// Create Express application instance
const app = express();

// Security middleware - Set various HTTP headers for security
app.use(helmet());

// CORS configuration - Enable cross-origin resource sharing
app.use(cors({
  origin: appConfig.cors.origin, // Allowed origins from config
  credentials: appConfig.cors.credentials, // Allow credentials from config
}));

// Compression middleware - Compress responses for better performance
app.use(compression());

// Body parsing middleware - Parse JSON request bodies
app.use(express.json({ limit: '10mb' })); // Limit request body size to 10MB
// Parse URL-encoded request bodies
app.use(express.urlencoded({ extended: true, limit: '10mb' }));

// HTTP request logging middleware
if (process.env.NODE_ENV !== 'test') {
  // Use morgan for HTTP logging in non-test environments
  app.use(morgan(appConfig.logging.format, {
    stream: {
      write: (message) => logger.info(message.trim()), // Log HTTP requests using logger
    },
  }));
}

// Rate limiting middleware - Prevent API abuse
const limiter = rateLimit({
  windowMs: appConfig.rateLimit.windowMs, // Time window from config
  max: appConfig.rateLimit.max, // Maximum requests per window from config
  message: {
    success: false, // Indicate failure
    message: 'Too many requests from this IP, please try again later.', // Rate limit message
  },
  standardHeaders: true, // Return rate limit info in `RateLimit-*` headers
  legacyHeaders: false, // Disable `X-RateLimit-*` headers
});
app.use('/api/', limiter); // Apply rate limiting to all API routes

// Swagger API documentation (only in development, not in test)
if (process.env.NODE_ENV === 'development') {
  try {
    setupSwagger(app); // Setup Swagger documentation
  } catch (error) {
    // Ignore Swagger errors in test environment
    if (process.env.NODE_ENV !== 'test') {
      logger.warn('Swagger setup failed:', error.message);
    }
  }
}

// Static file serving - Serve uploaded files
const path = require('path');
app.use('/uploads', express.static(path.join(__dirname, 'uploads'))); // Serve files from uploads directory

// API routes - Mount main routes at /api prefix
app.use('/api', routes);

// Root route - Simple welcome message
app.get('/', (req, res) => {
  res.status(200).json({
    success: true, // Indicate success
    message: 'Welcome to Smart POS API', // Welcome message
    version: '1.0.0', // API version
  });
});

// 404 handler - Handle undefined routes
app.use(notFoundHandler);

// Global error handler - Handle all errors
app.use(errorHandler);

// Export Express application
module.exports = app;

