/**
 * Multipart Form Data Validation
 * Special validation rules for multipart/form-data requests (file uploads)
 * Note: express-validator works with multipart/form-data, but body fields are strings
 */

// Import express-validator for request validation
const { body, validationResult } = require('express-validator');
// Import custom validation error class
const { ValidationError } = require('../../../utils/errors');

/**
 * Validation middleware wrapper
 * Checks validation results and returns errors if validation fails
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 * @param {Function} next - Express next middleware function
 */
const validate = (req, res, next) => {
  // Get validation errors from request
  const errors = validationResult(req);
  
  // If validation errors exist, return error response
  if (!errors.isEmpty()) {
    // Format validation errors
    const formattedErrors = errors.array().map((error) => ({
      field: error.path || error.param, // Field name
      message: error.msg, // Error message
      value: error.value, // Invalid value
    }));
    
    // Throw validation error with formatted errors
    throw new ValidationError('Validation failed', formattedErrors);
  }
  
  // If validation passes, proceed to next middleware
  next();
};

/**
 * Create product with multipart form data validation rules
 * Validates product data for product creation (multipart/form-data)
 * Note: This handles multipart form data where fields are strings
 */
const validateCreateProductMultipart = [
  // Validate name field
  body('name')
    .trim() // Remove whitespace
    .notEmpty() // Name is required
    .withMessage('Product name is required') // Error message
    .isLength({ min: 1, max: 150 }) // Name length validation
    .withMessage('Product name must be between 1 and 150 characters'), // Error message
  
  // Validate SKU field (optional)
  body('sku')
    .optional() // Field is optional
    .trim() // Remove whitespace
    .isLength({ max: 100 }) // SKU length validation
    .withMessage('SKU must not exceed 100 characters'), // Error message
  
  // Validate product_type field
  body('product_type')
    .notEmpty() // Product type is required
    .withMessage('Product type is required') // Error message
    .isIn(['FG', 'RM']) // Product type must be FG or RM
    .withMessage('Product type must be either FG (Finished Goods) or RM (Raw Materials)'), // Error message
  
  // Validate track_inventory field (optional) - multipart sends as string 'true'/'false'
  body('track_inventory')
    .optional() // Field is optional
    .custom((value) => {
      // Accept boolean string values or actual booleans
      if (value === 'true' || value === true) return true; // Accept 'true' or true
      if (value === 'false' || value === false) return true; // Accept 'false' or false
      throw new Error('Track inventory must be a boolean value'); // Throw error for invalid values
    }),
  
  // Validate description field (optional)
  body('description')
    .optional() // Field is optional
    .trim(), // Remove whitespace
  
  // Validate default_vat_rate field (optional) - multipart sends as string
  body('default_vat_rate')
    .optional() // Field is optional
    .custom((value) => {
      // Convert string to number and validate
      const num = parseFloat(value); // Parse string to float
      if (isNaN(num)) throw new Error('Default VAT rate must be a number'); // Check if valid number
      if (num < 0 || num > 100) throw new Error('Default VAT rate must be between 0 and 100'); // Validate range
      return true; // Validation passed
    }),
  
  // Validate tax_category_id field (optional) - multipart sends as string
  body('tax_category_id')
    .optional() // Field is optional
    .custom((value) => {
      // Convert string to integer and validate
      const num = parseInt(value, 10); // Parse string to integer
      if (isNaN(num) || num < 1) throw new Error('Tax category ID must be a positive integer'); // Validate
      return true; // Validation passed
    }),
  
  // Validate variants field (optional) - multipart sends as JSON string
  body('variants')
    .optional() // Field is optional
    .custom((value) => {
      // If value is provided, it should be a valid JSON string
      if (typeof value === 'string') {
        try {
          const parsed = JSON.parse(value); // Try to parse JSON string
          if (!Array.isArray(parsed)) throw new Error('Variants must be an array'); // Validate it's an array
        } catch (error) {
          throw new Error('Variants must be a valid JSON array string'); // Throw error if parsing fails
        }
      } else if (Array.isArray(value)) {
        // If it's already an array (shouldn't happen with multipart, but handle it)
        return true; // Accept array directly
      } else if (value !== undefined && value !== null && value !== '') {
        throw new Error('Variants must be a valid JSON array string'); // Throw error for other types
      }
      return true; // Validation passed
    }),
  
  // Run validation middleware
  validate,
];

/**
 * Update product with multipart form data validation rules
 * Validates product data for product updates (multipart/form-data)
 */
const validateUpdateProductMultipart = [
  // Validate product ID parameter (handled by param validation in routes)
  
  // Validate name field (optional)
  body('name')
    .optional() // Field is optional
    .trim() // Remove whitespace
    .isLength({ min: 1, max: 150 }) // Name length validation
    .withMessage('Product name must be between 1 and 150 characters'), // Error message
  
  // Validate SKU field (optional)
  body('sku')
    .optional() // Field is optional
    .trim() // Remove whitespace
    .isLength({ max: 100 }) // SKU length validation
    .withMessage('SKU must not exceed 100 characters'), // Error message
  
  // Validate product_type field (optional)
  body('product_type')
    .optional() // Field is optional
    .isIn(['FG', 'RM']) // Product type must be FG or RM
    .withMessage('Product type must be either FG (Finished Goods) or RM (Raw Materials)'), // Error message
  
  // Validate track_inventory field (optional) - multipart sends as string
  body('track_inventory')
    .optional() // Field is optional
    .custom((value) => {
      // Accept boolean string values or actual booleans
      if (value === 'true' || value === true) return true; // Accept 'true' or true
      if (value === 'false' || value === false) return true; // Accept 'false' or false
      throw new Error('Track inventory must be a boolean value'); // Throw error for invalid values
    }),
  
  // Validate description field (optional)
  body('description')
    .optional() // Field is optional
    .trim(), // Remove whitespace
  
  // Validate default_vat_rate field (optional) - multipart sends as string
  body('default_vat_rate')
    .optional() // Field is optional
    .custom((value) => {
      // Convert string to number and validate
      const num = parseFloat(value); // Parse string to float
      if (isNaN(num)) throw new Error('Default VAT rate must be a number'); // Check if valid number
      if (num < 0 || num > 100) throw new Error('Default VAT rate must be between 0 and 100'); // Validate range
      return true; // Validation passed
    }),
  
  // Validate tax_category_id field (optional) - multipart sends as string
  body('tax_category_id')
    .optional() // Field is optional
    .custom((value) => {
      // Convert string to integer and validate
      const num = parseInt(value, 10); // Parse string to integer
      if (isNaN(num) || num < 1) throw new Error('Tax category ID must be a positive integer'); // Validate
      return true; // Validation passed
    }),
  
  // Run validation middleware
  validate,
];

// Export validation rules
module.exports = {
  validateCreateProductMultipart, // Create product multipart validation rules
  validateUpdateProductMultipart, // Update product multipart validation rules
};

