/**
 * Inventory Validation Rules
 * Input validation rules for inventory management endpoints
 */

// Import express-validator for request validation
const { body, param, query, 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();
};

/**
 * Get quantity validation rules
 * Validates query parameters for getting inventory quantity
 */
const validateGetQuantity = [
  // Validate product_id query parameter
  query('product_id')
    .notEmpty() // Product ID is required
    .withMessage('Product ID is required') // Error message
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Product ID must be a positive integer'), // Error message
  
];

/**
 * Check availability validation rules
 * Validates query parameters for checking stock availability
 */
const validateCheckAvailability = [
  // Validate product_id query parameter
  query('product_id')
    .notEmpty() // Product ID is required
    .withMessage('Product ID is required') // Error message
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Product ID must be a positive integer'), // Error message
  
  
  // Validate quantity query parameter
  query('quantity')
    .notEmpty() // Quantity is required
    .withMessage('Quantity is required') // Error message
    .isFloat({ min: 0.001 }) // Quantity must be a positive number
    .withMessage('Quantity must be a positive number'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Get inventory validation rules
 * Validates parameters for getting inventory record
 */
const validateGetInventory = [
  // Validate productId path parameter
  param('productId')
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Invalid product ID'), // Error message
  
  
  // Run validation middleware
  validate,
];

/**
 * List inventory validation rules
 * Validates query parameters for listing inventory
 */
const validateListInventory = [
  // Validate page query parameter (optional)
  query('page')
    .optional() // Field is optional
    .isInt({ min: 1 }) // Page must be a positive integer
    .withMessage('Page must be a positive integer'), // Error message
  
  // Validate limit query parameter (optional)
  query('limit')
    .optional() // Field is optional
    .isInt({ min: 1, max: 100 }) // Limit must be between 1 and 100
    .withMessage('Limit must be between 1 and 100'), // Error message
  
  // Validate product_id query parameter (optional)
  query('product_id')
    .optional() // Field is optional
    .isInt({ min: 1 }) // Product ID must be a positive integer if provided
    .withMessage('Product ID must be a positive integer'), // Error message
  
  // Validate product_type query parameter (optional)
  query('product_type')
    .optional() // Field is optional
    .isIn(['RM', 'FG']) // Product type must be RM or FG
    .withMessage('Product type must be either RM or FG'), // Error message
  
  // Validate low_stock query parameter (optional)
  query('low_stock')
    .optional() // Field is optional
    .isIn(['true', 'false']) // Low stock must be 'true' or 'false' string
    .withMessage('Low stock must be "true" or "false"'), // Error message
  
  // Validate out_of_stock query parameter (optional)
  query('out_of_stock')
    .optional() // Field is optional
    .isIn(['true', 'false']) // Out of stock must be 'true' or 'false' string
    .withMessage('Out of stock must be "true" or "false"'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Adjust inventory validation rules
 * Validates request body for inventory adjustment
 */
const validateAdjustInventory = [
  // Validate product_id field
  body('product_id')
    .notEmpty() // Product ID is required
    .withMessage('Product ID is required') // Error message
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Product ID must be a positive integer'), // Error message
  
  
  // Validate quantity_change field
  body('quantity_change')
    .notEmpty() // Quantity change is required
    .withMessage('Quantity change is required') // Error message
    .isFloat() // Quantity change must be a number
    .withMessage('Quantity change must be a number') // Error message
    .custom((value) => {
      // Quantity change cannot be zero
      if (parseFloat(value) === 0) {
        throw new Error('Quantity change cannot be zero'); // Throw error if zero
      }
      return true; // Validation passed
    }),
  
  // Validate reason field
  body('reason')
    .notEmpty() // Reason is required
    .withMessage('Reason is required') // Error message
    .isIn(['GRN', 'SALE', 'SALE_RETURN', 'PRODUCTION_CONSUME', 'PRODUCTION_OUTPUT', 'ADJUSTMENT']) // Reason must be valid enum value
    .withMessage('Reason must be one of: GRN, SALE, SALE_RETURN, PRODUCTION_CONSUME, PRODUCTION_OUTPUT, ADJUSTMENT'), // Error message
  
  // Validate reference_id field (optional)
  body('reference_id')
    .optional() // Field is optional
    .isInt({ min: 1 }) // Reference ID must be a positive integer if provided
    .withMessage('Reference ID must be a positive integer'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Set inventory quantity validation rules
 * Validates request body for setting inventory quantity
 */
const validateSetInventoryQuantity = [
  // Validate product_id field
  body('product_id')
    .notEmpty() // Product ID is required
    .withMessage('Product ID is required') // Error message
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Product ID must be a positive integer'), // Error message
  
  
  // Validate quantity field
  body('quantity')
    .notEmpty() // Quantity is required
    .withMessage('Quantity is required') // Error message
    .isFloat({ min: 0 }) // Quantity must be a non-negative number
    .withMessage('Quantity must be a non-negative number'), // Error message
  
  // Validate notes field (optional)
  body('notes')
    .optional() // Field is optional
    .trim(), // Remove whitespace
  
  // Run validation middleware
  validate,
];

/**
 * Set reorder level validation rules
 * Validates request body for setting reorder level
 */
const validateSetReorderLevel = [
  // Validate product_id field
  body('product_id')
    .notEmpty() // Product ID is required
    .withMessage('Product ID is required') // Error message
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Product ID must be a positive integer'), // Error message
  
  
  // Validate reorder_level field
  body('reorder_level')
    .notEmpty() // Reorder level is required
    .withMessage('Reorder level is required') // Error message
    .isFloat({ min: 0 }) // Reorder level must be a non-negative number
    .withMessage('Reorder level must be a non-negative number'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Get inventory movements validation rules
 * Validates parameters for getting inventory movements
 */
const validateGetInventoryMovements = [
  // Validate productId path parameter
  param('productId')
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Invalid product ID'), // Error message
  
  
  // Validate page query parameter (optional)
  query('page')
    .optional() // Field is optional
    .isInt({ min: 1 }) // Page must be a positive integer
    .withMessage('Page must be a positive integer'), // Error message
  
  // Validate limit query parameter (optional)
  query('limit')
    .optional() // Field is optional
    .isInt({ min: 1, max: 100 }) // Limit must be between 1 and 100
    .withMessage('Limit must be between 1 and 100'), // Error message
  
  // Run validation middleware
  validate,
];

// Import inventory items validations
const inventoryItemsValidations = require('./items');

// Export validation rules (quantity-based + UID-based)
module.exports = {
  // Quantity-based inventory validations
  validateGetQuantity, // Get quantity validation rules
  validateCheckAvailability, // Check availability validation rules
  validateGetInventory, // Get inventory validation rules
  validateListInventory, // List inventory validation rules
  validateAdjustInventory, // Adjust inventory validation rules
  validateSetInventoryQuantity, // Set inventory quantity validation rules
  validateSetReorderLevel, // Set reorder level validation rules
  validateGetInventoryMovements, // Get inventory movements validation rules
  // UID-based inventory item validations
  validateCreateInventoryItem: inventoryItemsValidations.validateCreateInventoryItem,
  validateGetInventoryItemByUID: inventoryItemsValidations.validateGetInventoryItemByUID,
  validateUpdateInventoryItemStatus: inventoryItemsValidations.validateUpdateInventoryItemStatus,
  validateScanInventoryItem: inventoryItemsValidations.validateScanInventoryItem,
  validateListInventoryItems: inventoryItemsValidations.validateListInventoryItems,
};
