/**
 * Returns Validation Rules
 * Input validation rules for return 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
 * Handles validation errors and formats response
 */
const handleValidationErrors = (req, res, next) => {
  // Get validation errors
  const errors = validationResult(req); // Get validation errors
  
  // Check if there are errors
  if (!errors.isEmpty()) {
    // Extract error messages
    const errorMessages = errors.array().map(error => ({
      field: error.param, // Field name
      message: error.msg, // Error message
    })); // Map errors to messages
    
    // Throw validation error
    throw new ValidationError('Validation failed', errorMessages); // Throw validation error
  }
  
  // Continue to next middleware if no errors
  next(); // Continue
};

/**
 * Validate create return request
 */
const validateCreateReturn = [
  // Validate sale_id (required)
  body('sale_id')
    .notEmpty()
    .withMessage('Sale ID is required')
    .isInt({ min: 1 })
    .withMessage('Sale ID must be a positive integer'),
  
  // Validate items (required, array)
  body('items')
    .isArray({ min: 1 })
    .withMessage('Return must have at least one item')
    .custom((items) => {
      // Validate each item
      for (const item of items) {
        // Check if sale_item_id exists
        if (!item.sale_item_id) {
          throw new Error('Return item must have sale_item_id'); // Throw error if missing
        }
        // Check if quantity exists
        if (!item.quantity) {
          throw new Error('Return item must have quantity'); // Throw error if missing
        }
        // Check if quantity is positive
        if (parseFloat(item.quantity) <= 0) {
          throw new Error('Return quantity must be greater than 0'); // Throw error if invalid
        }
        // Note: inventory_item_id is optional - only required for UID-tracked items
        // For quantity-based items, inventory_item_id should be null/omitted
      }
      return true; // Return true if valid
    }),
  
  // Validate each item's sale_item_id
  body('items.*.sale_item_id')
    .isInt({ min: 1 })
    .withMessage('Sale item ID must be a positive integer'),
  
  // Validate each item's inventory_item_id (optional - only for UID-tracked items)
  body('items.*.inventory_item_id')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Inventory item ID must be a positive integer if provided'),
  
  // Validate each item's quantity
  body('items.*.quantity')
    .isFloat({ min: 0.001 })
    .withMessage('Return quantity must be a positive number'),
  
  // Validate reason (optional)
  body('reason')
    .optional()
    .trim()
    .isLength({ max: 1000 })
    .withMessage('Return reason must be at most 1000 characters'),
  
  // Validate each item's reason (optional)
  body('items.*.reason')
    .optional()
    .trim()
    .isLength({ max: 255 })
    .withMessage('Item return reason must be at most 255 characters'),
  
  // Handle validation errors
  handleValidationErrors,
];

/**
 * Validate get return by ID request
 */
const validateGetReturn = [
  // Validate id parameter (required)
  param('id')
    .isInt({ min: 1 })
    .withMessage('Return ID must be a positive integer'),
  
  // Handle validation errors
  handleValidationErrors,
];

/**
 * Validate list returns request
 */
const validateListReturns = [
  // Validate sale_id query parameter (optional)
  query('sale_id')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Sale ID must be a positive integer'),
  
  // Validate status query parameter (optional)
  query('status')
    .optional()
    .isIn(['DRAFT', 'COMPLETED'])
    .withMessage('Status must be either DRAFT or COMPLETED'),
  
  // Validate start_date query parameter (optional)
  query('start_date')
    .optional()
    .isISO8601()
    .withMessage('Start date must be a valid ISO 8601 date'),
  
  // Validate end_date query parameter (optional)
  query('end_date')
    .optional()
    .isISO8601()
    .withMessage('End date must be a valid ISO 8601 date'),
  
  // Validate page query parameter (optional)
  query('page')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Page must be a positive integer'),
  
  // Validate limit query parameter (optional)
  query('limit')
    .optional()
    .isInt({ min: 1, max: 100 })
    .withMessage('Limit must be between 1 and 100'),
  
  // Handle validation errors
  handleValidationErrors,
];

/**
 * Validate complete return request
 */
const validateCompleteReturn = [
  // Validate id parameter (required)
  param('id')
    .isInt({ min: 1 })
    .withMessage('Return ID must be a positive integer'),
  
  // Validate refund_method (optional - will default to CREDIT_NOTE in service)
  body('refund_method')
    .optional({ nullable: true, checkFalsy: true })
    .isIn(['CASH', 'CARD', 'MPESA', 'CREDIT_NOTE', 'REPLACEMENT'])
    .withMessage('Refund method must be one of: CASH, CARD, MPESA, CREDIT_NOTE, REPLACEMENT'),
  
  // Validate refund_amount (optional)
  body('refund_amount')
    .optional()
    .isFloat({ min: 0 })
    .withMessage('Refund amount must be a positive number'),
  
  // Validate replacement_product_id (optional)
  body('replacement_product_id')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Replacement product ID must be a positive integer'),
  
  // Validate refund_reference (optional)
  body('refund_reference')
    .optional()
    .trim()
    .isLength({ max: 150 })
    .withMessage('Refund reference must be at most 150 characters'),
  
  // Handle validation errors
  handleValidationErrors,
];

// Export all validations
module.exports = {
  validateCreateReturn,
  validateGetReturn,
  validateListReturns,
  validateCompleteReturn,
};
