const { returnToPool } = require('../database/init');

// Global error handler middleware
const errorHandler = (err, req, res, next) => {
  console.error('Error occurred:', {
    message: err.message,
    stack: err.stack,
    url: req.url,
    method: req.method,
    timestamp: new Date().toISOString()
  });

  // Handle database connection errors
  if (err.code === 'SQLITE_BUSY' || err.code === 'SQLITE_LOCKED') {
    return res.status(503).json({
      error: 'Database temporarily unavailable, please try again',
      retryAfter: 5
    });
  }

  // Handle timeout errors
  if (err.code === 'ETIMEDOUT' || err.message.includes('timeout')) {
    return res.status(408).json({
      error: 'Request timeout, please try again',
      retryAfter: 10
    });
  }

  // Handle validation errors
  if (err.type === 'entity.parse.failed') {
    return res.status(400).json({
      error: 'Invalid JSON format in request body'
    });
  }

  // Handle file size errors
  if (err.code === 'LIMIT_FILE_SIZE') {
    return res.status(413).json({
      error: 'File too large, maximum size is 10MB'
    });
  }

  // Default error response
  const statusCode = err.status || 500;
  const message = process.env.NODE_ENV === 'production' 
    ? 'Internal server error' 
    : err.message;

  res.status(statusCode).json({
    error: message,
    ...(process.env.NODE_ENV !== 'production' && { stack: err.stack })
  });
};

// Database connection cleanup middleware
const dbCleanup = (req, res, next) => {
  // Store the original end method
  const originalEnd = res.end;
  
  // Override the end method to ensure database connections are returned to pool
  res.end = function(...args) {
    // If there's a database connection in the request, return it to the pool
    if (req.db) {
      returnToPool(req.db);
    }
    
    // Call the original end method
    return originalEnd.apply(this, args);
  };
  
  next();
};

// Request timeout middleware
const requestTimeout = (timeout = 30000) => {
  return (req, res, next) => {
    const timer = setTimeout(() => {
      if (!res.headersSent) {
        res.status(408).json({
          error: 'Request timeout',
          retryAfter: 5
        });
      }
    }, timeout);

    // Clear timeout when response is sent
    res.on('finish', () => {
      clearTimeout(timer);
    });

    res.on('close', () => {
      clearTimeout(timer);
    });

    next();
  };
};

// Rate limiting error handler
const rateLimitErrorHandler = (err, req, res, next) => {
  if (err.type === 'entity.too.large') {
    return res.status(413).json({
      error: 'Request entity too large',
      maxSize: '50MB'
    });
  }
  next(err);
};

module.exports = {
  errorHandler,
  dbCleanup,
  requestTimeout,
  rateLimitErrorHandler
}; 