/**
 * Inventory Items Validations (UID-Based)
 * Validation rules for UID-based inventory item operations
 */

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

/**
 * Validation middleware
 * Checks validation results and throws error if validation fails
 * @param {Object} req - Express request object
 * @param {Object} res - Express response object
 * @param {Function} next - Express next middleware
 */
const validate = (req, res, next) => {
  // Get validation results
  const errors = validationResult(req); // Get validation errors
  
  // If validation errors exist, format and throw error
  if (!errors.isEmpty()) {
    // Format 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
    throw new ValidationError('Validation failed', formattedErrors); // Throw error
  }
  
  // Continue to next middleware
  next(); // Proceed
};

/**
 * Validation rules for creating inventory item
 */
const validateCreateInventoryItem = [
  // Validate product_id
  body('product_id')
    .notEmpty()
    .withMessage('Product ID is required')
    .isInt({ min: 1 })
    .withMessage('Product ID must be a positive integer')
    .toInt(), // Convert to integer
  
  // Validate variant_id (optional)
  body('variant_id')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Variant ID must be a positive integer')
    .toInt(), // Convert to integer
  
  // Validate source
  body('source')
    .notEmpty()
    .withMessage('Source is required')
    .isIn(['GRN', 'PRODUCTION', 'RETURN'])
    .withMessage('Source must be one of: GRN, PRODUCTION, RETURN'),
  
  // Validate uid (optional - will be generated if not provided)
  body('uid')
    .optional()
    .trim()
    .isLength({ min: 1, max: 100 })
    .withMessage('UID must be between 1 and 100 characters')
    .matches(/^[A-Z0-9_-]+$/i)
    .withMessage('UID must contain only alphanumeric characters, dashes, and underscores'),
  
  // Validate barcode (optional - will be generated if not provided)
  body('barcode')
    .optional()
    .trim()
    .isLength({ min: 1, max: 100 })
    .withMessage('Barcode must be between 1 and 100 characters')
    .matches(/^[A-Z0-9]+$/i)
    .withMessage('Barcode must contain only alphanumeric characters'),
  
  // Run validation
  validate, // Validate request
];

/**
 * Validation rules for getting inventory item by UID
 */
const validateGetInventoryItemByUID = [
  // Validate uid parameter
  param('uid')
    .notEmpty()
    .withMessage('UID/barcode is required')
    .trim()
    .isLength({ min: 1, max: 100 })
    .withMessage('UID/barcode must be between 1 and 100 characters'),
  
  // Run validation
  validate, // Validate request
];

/**
 * Validation rules for updating inventory item status
 */
const validateUpdateInventoryItemStatus = [
  // Validate uid parameter
  param('uid')
    .notEmpty()
    .withMessage('UID/barcode is required')
    .trim()
    .isLength({ min: 1, max: 100 })
    .withMessage('UID/barcode must be between 1 and 100 characters'),
  
  // Validate status
  body('status')
    .notEmpty()
    .withMessage('Status is required')
    .isIn(['IN_STOCK', 'RESERVED', 'SOLD', 'RETURNED', 'DAMAGED', 'SCRAPPED'])
    .withMessage('Status must be one of: IN_STOCK, RESERVED, SOLD, RETURNED, DAMAGED, SCRAPPED'),
  
  // Validate reason (optional)
  body('reason')
    .optional()
    .trim()
    .isLength({ max: 500 })
    .withMessage('Reason must not exceed 500 characters'),
  
  // Run validation
  validate, // Validate request
];

/**
 * Validation rules for scanning inventory item
 */
const validateScanInventoryItem = [
  // Validate uid parameter
  param('uid')
    .notEmpty()
    .withMessage('UID/barcode is required')
    .trim()
    .isLength({ min: 1, max: 100 })
    .withMessage('UID/barcode must be between 1 and 100 characters'),
  
  // Run validation
  validate, // Validate request
];

/**
 * Validation rules for listing inventory items
 */
const validateListInventoryItems = [
  // Validate page query parameter
  query('page')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Page must be a positive integer')
    .toInt(), // Convert to integer
  
  // Validate limit query parameter
  query('limit')
    .optional()
    .isInt({ min: 1, max: 10000 })
    .withMessage('Limit must be between 1 and 10000')
    .toInt(), // Convert to integer
  
  // Validate product_id query parameter
  query('product_id')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Product ID must be a positive integer')
    .toInt(), // Convert to integer
  
  // Validate variant_id query parameter
  query('variant_id')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Variant ID must be a positive integer')
    .toInt(), // Convert to integer
  
  // Validate status query parameter
  query('status')
    .optional()
    .isIn(['IN_STOCK', 'RESERVED', 'SOLD', 'RETURNED', 'DAMAGED', 'SCRAPPED'])
    .withMessage('Status must be one of: IN_STOCK, RESERVED, SOLD, RETURNED, DAMAGED, SCRAPPED'),
  
  // Validate source query parameter
  query('source')
    .optional()
    .isIn(['GRN', 'PRODUCTION', 'RETURN'])
    .withMessage('Source must be one of: GRN, PRODUCTION, RETURN'),
  
  // Validate source_reference_id query parameter (for filtering by source reference)
  query('source_reference_id')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Source reference ID must be a positive integer')
    .toInt(), // Convert to integer
  
  // Validate uid query parameter (for searching by UID)
  query('uid')
    .optional()
    .trim()
    .isLength({ min: 1, max: 100 })
    .withMessage('UID must be between 1 and 100 characters'),
  
  // Validate barcode query parameter (for searching by barcode)
  query('barcode')
    .optional()
    .trim()
    .isLength({ min: 1, max: 100 })
    .withMessage('Barcode must be between 1 and 100 characters'),
  
  // Run validation
  validate, // Validate request
];

// Export validation rules
module.exports = {
  validateCreateInventoryItem, // Create inventory item validation
  validateGetInventoryItemByUID, // Get inventory item by UID validation
  validateUpdateInventoryItemStatus, // Update inventory item status validation
  validateScanInventoryItem, // Scan inventory item validation
  validateListInventoryItems, // List inventory items validation
};

