/**
 * File Upload Middleware
 * Handles file uploads using multer
 */

// Import multer for file upload handling
const multer = require('multer');
// Import path for file path manipulation
const path = require('path');
// Import fs for file system operations
const fs = require('fs');
// Import app configuration
const appConfig = require('../config/app');

// Ensure uploads directory exists
const uploadsDir = appConfig.upload.uploadPath || './uploads';
if (!fs.existsSync(uploadsDir)) {
  fs.mkdirSync(uploadsDir, { recursive: true }); // Create directory if it doesn't exist
}

// Ensure product images subdirectory exists
const productImagesDir = path.join(uploadsDir, 'products');
if (!fs.existsSync(productImagesDir)) {
  fs.mkdirSync(productImagesDir, { recursive: true }); // Create directory if it doesn't exist
}

/**
 * Configure storage for product images
 * Stores files in uploads/products directory
 */
const storage = multer.diskStorage({
  // Destination function - determines where to store files
  destination: (req, file, cb) => {
    cb(null, productImagesDir); // Store in uploads/products directory
  },
  // Filename function - determines file name
  filename: (req, file, cb) => {
    // Generate unique filename: timestamp-randomnumber-originalname
    const uniqueSuffix = `${Date.now()}-${Math.round(Math.random() * 1E9)}`; // Unique suffix
    const fileExt = path.extname(file.originalname); // Get file extension
    const baseName = path.basename(file.originalname, fileExt); // Get base name without extension
    const sanitizedName = baseName.replace(/[^a-zA-Z0-9]/g, '-'); // Sanitize filename
    const filename = `${sanitizedName}-${uniqueSuffix}${fileExt}`; // Create unique filename
    cb(null, filename); // Return filename
  },
});

/**
 * File filter function
 * Validates file type (only images allowed)
 * @param {Object} req - Express request object
 * @param {Object} file - Multer file object
 * @param {Function} cb - Callback function
 */
const fileFilter = (req, file, cb) => {
  // Get allowed file types from config (default: image types)
  const allowedTypes = appConfig.upload.allowedFileTypes || ['image/jpeg', 'image/png', 'image/jpg', 'image/gif', 'image/webp'];
  
  // Check if file MIME type is allowed
  if (allowedTypes.includes(file.mimetype)) {
    cb(null, true); // Accept file
  } else {
    // Reject file with error
    cb(new Error(`Invalid file type. Allowed types: ${allowedTypes.join(', ')}`), false);
  }
};

/**
 * Multer configuration
 * Configures multer with storage, file filter, and limits
 */
const upload = multer({
  storage: storage, // Use disk storage configuration
  fileFilter: fileFilter, // Use file filter for validation
  limits: {
    fileSize: appConfig.upload.maxFileSize || 5242880, // Maximum file size (5MB default)
  },
});

/**
 * Single file upload middleware for product images
 * Accepts a single file with field name 'image'
 */
const uploadProductImage = upload.single('image');

/**
 * Error handler for multer errors
 * Formats multer errors for consistent error responses
 * @param {Error} err - Error object
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 * @param {Function} next - Express next middleware function
 */
const handleUploadError = (err, req, res, next) => {
  // Handle multer errors
  if (err instanceof multer.MulterError) {
    if (err.code === 'LIMIT_FILE_SIZE') {
      // File size limit exceeded
      return res.status(400).json({
        success: false, // Indicate failure
        message: `File size exceeds maximum limit of ${appConfig.upload.maxFileSize / 1024 / 1024}MB`, // Error message
      });
    }
    // Other multer errors
    return res.status(400).json({
      success: false, // Indicate failure
      message: `Upload error: ${err.message}`, // Error message
    });
  }
  
  // Handle other upload errors (file type validation, etc.)
  if (err) {
    return res.status(400).json({
      success: false, // Indicate failure
      message: err.message || 'File upload failed', // Error message
    });
  }
  
  // If no error, proceed to next middleware
  next();
};

// Export upload middleware and error handler
module.exports = {
  uploadProductImage, // Single file upload middleware for product images
  handleUploadError, // Error handler for upload errors
};

