/** Upload Validation Middleware Checks for upload errors and validates required files */

/**
 * Middleware to check if file upload encountered errors
 *
 * @param {import('express').Request} req Express request
 * @param {import('express').Response} res Express response
 * @param {import('express').NextFunction} next Express next function
 * @returns {void}
 */
function checkUploadError(req, res, next) {
  if (req.uploadError) {
    const { type, message, canRetry, allowedTypes, maxSize } = req.uploadError;

    const errorResponse = {
      success: false,
      error: {
        message,
        type,
        canRetry,
      },
    };

    // Add additional context based on error type
    if (allowedTypes) {
      errorResponse.error.allowedTypes = allowedTypes;
    }

    if (maxSize) {
      errorResponse.error.maxSizeMB = maxSize / (1024 * 1024);
    }

    // Determine appropriate HTTP status code
    let statusCode = 400;
    if (type === 'TIMEOUT') {
      statusCode = 408;
    } else if (type === 'FILE_TOO_LARGE') {
      statusCode = 413;
    } else if (type === 'UPLOAD_ERROR') {
      statusCode = 500;
    }

    return res.status(statusCode).json(errorResponse);
  }

  return next();
}

/**
 * Middleware factory to validate required files
 *
 * @param {string[]} requiredFields Array of required file field names
 * @returns {import('express').RequestHandler} Express middleware
 */
function requireFiles(requiredFields) {
  return (req, res, next) => {
    const missingFiles = [];

    requiredFields.forEach((field) => {
      if (!req.files || !req.files[field] || req.files[field].length === 0) {
        missingFiles.push(field);
      }
    });

    if (missingFiles.length > 0) {
      return res.status(400).json({
        success: false,
        error: {
          message: `Missing required file uploads: ${missingFiles.join(', ')}`,
          type: 'MISSING_FILES',
          missingFields: missingFiles,
          canRetry: false,
        },
      });
    }

    return next();
  };
}

/**
 * Middleware to validate file sizes don't exceed limits
 *
 * @param {number} maxSizePerFile Max size per file in bytes
 * @returns {import('express').RequestHandler} Express middleware
 */
function validateFileSize(maxSizePerFile) {
  return (req, res, next) => {
    if (!req.files) {
      return next();
    }

    const oversizedFiles = [];

    Object.entries(req.files).forEach(([field, files]) => {
      files.forEach((file) => {
        if (file.size > maxSizePerFile) {
          oversizedFiles.push({
            field,
            filename: file.originalname,
            size: file.size,
            maxSize: maxSizePerFile,
          });
        }
      });
    });

    if (oversizedFiles.length > 0) {
      return res.status(413).json({
        success: false,
        error: {
          message: `Files exceed maximum size limit of ${maxSizePerFile / (1024 * 1024)}MB`,
          type: 'FILE_TOO_LARGE',
          oversizedFiles,
          canRetry: false,
        },
      });
    }

    return next();
  };
}

module.exports = {
  checkUploadError,
  requireFiles,
  validateFileSize,
};
