/**
 * Sales Validation Rules
 * Input validation rules for sales 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
    }));
    
    // Log validation errors for debugging
    const logger = require('../../../utils/logger');
    logger.error('Validation failed', {
      url: req.url,
      method: req.method,
      errors: formattedErrors,
      body: req.body,
    });
    
    // Throw validation error with formatted errors
    throw new ValidationError('Validation failed', formattedErrors);
  }
  
  // If validation passes, proceed to next middleware
  next();
};

/**
 * Create sale validation rules
 * Validates request body for sale creation
 */
const validateCreateSale = [
  // Customer registration removed - all sales are walk-in customers (customer_id always null)
  
  // Validate sale_type field (optional)
  body('sale_type')
    .optional() // Field is optional
    .isIn(['POS', 'INVOICE']) // Sale type must be POS or INVOICE
    .withMessage('Sale type must be either POS or INVOICE'), // Error message
  
  // Validate items array
  body('items')
    .notEmpty() // Items array is required
    .withMessage('Sale must have at least one item') // Error message
    .isArray({ min: 1 }) // Items must be an array with at least one item
    .withMessage('Items must be an array with at least one item'), // Error message
  
  // Validate items.*.product_id
  body('items.*.product_id')
    .notEmpty() // Product ID is required
    .withMessage('Item product_id is required') // Error message
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Item product_id must be a positive integer'), // Error message
  
  // Variants removed - variant_id validation removed (variants no longer supported)
  
  // Validate items.*.quantity
  body('items.*.quantity')
    .notEmpty() // Quantity is required
    .withMessage('Item quantity is required') // Error message
    .isFloat({ min: 0.001 }) // Quantity must be a positive number
    .withMessage('Item quantity must be a positive number'), // Error message
  
  // Validate items.*.unit_price (optional, but recommended)
  body('items.*.unit_price')
    .optional() // Field is optional
    .isFloat({ min: 0 }) // Unit price must be a non-negative number if provided
    .withMessage('Item unit_price must be a non-negative number'), // Error message
  
  // Validate discount_code (optional)
  body('discount_code')
    .optional() // Field is optional
    .trim() // Trim whitespace
    .isLength({ min: 1, max: 50 }) // Discount code length validation
    .withMessage('Discount code must be between 1 and 50 characters'), // Error message
  
  // Validate discount_id (optional)
  body('discount_id')
    .optional() // Field is optional
    .isInt({ min: 1 }) // Discount ID must be a positive integer if provided
    .withMessage('Discount ID must be a positive integer'), // Error message
  
  // Ensure only one of discount_code or discount_id is provided
  body().custom((value) => {
    // If both discount_code and discount_id are provided, throw error
    if (value.discount_code && value.discount_id) {
      throw new Error('Cannot provide both discount_code and discount_id'); // Throw error if both provided
    }
    return true; // Return true if valid
  }),

  // Validate manager_approval_id (optional)
  body('manager_approval_id')
    .optional() // Field is optional
    .isInt({ min: 1 }) // Manager approval ID must be a positive integer if provided
    .withMessage('Manager approval ID must be a positive integer'), // Error message

  // Validate stock_override (optional)
  body('stock_override')
    .optional() // Field is optional
    .isBoolean() // Stock override must be a boolean if provided
    .withMessage('Stock override must be a boolean'), // Error message

  // Validate stock_override_reason (optional, required if stock_override is true)
  body('stock_override_reason')
    .optional() // Field is optional
    .trim() // Trim whitespace
    .isLength({ min: 1, max: 500 }) // Reason length validation
    .withMessage('Stock override reason must be between 1 and 500 characters'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Get sale validation rules
 * Validates sale ID parameter
 */
const validateGetSale = [
  // Validate sale ID parameter
  param('id')
    .isInt({ min: 1 }) // Sale ID must be a positive integer
    .withMessage('Invalid sale ID'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * List sales validation rules
 * Validates query parameters for sale listing
 */
const validateListSales = [
  // 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
  
  // Customer registration removed - customer_id query parameter removed
  
  // Validate status query parameter (optional)
  query('status')
    .optional() // Field is optional
    .isIn(['DRAFT', 'PAID', 'CANCELLED']) // Status must be valid enum value
    .withMessage('Status must be one of: DRAFT, PAID, CANCELLED'), // Error message
  
  // Validate sale_type query parameter (optional)
  query('sale_type')
    .optional() // Field is optional
    .isIn(['POS', 'INVOICE']) // Sale type must be POS or INVOICE
    .withMessage('Sale type must be either POS or INVOICE'), // Error message
  
  // Validate start_date query parameter (optional)
  query('start_date')
    .optional() // Field is optional
    .isISO8601() // Start date must be valid ISO 8601 date string
    .withMessage('Start date must be a valid ISO 8601 date string'), // Error message
  
  // Validate end_date query parameter (optional)
  query('end_date')
    .optional() // Field is optional
    .isISO8601() // End date must be valid ISO 8601 date string
    .withMessage('End date must be a valid ISO 8601 date string'), // Error message
  
  // Validate user_id query parameter (optional)
  query('user_id')
    .optional() // Field is optional
    .isInt({ min: 1 }) // User ID must be a positive integer if provided
    .withMessage('User ID must be a positive integer'), // Error message
  
  // Validate invoice_no query parameter (optional)
  query('invoice_no')
    .optional() // Field is optional
    .isString() // Invoice number must be a string
    .trim()
    .isLength({ min: 1, max: 100 }) // Invoice number length validation
    .withMessage('Invoice number must be between 1 and 100 characters'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Cancel sale validation rules
 * Validates sale ID parameter for cancellation
 */
const validateCancelSale = [
  // Validate sale ID parameter
  param('id')
    .isInt({ min: 1 }) // Sale ID must be a positive integer
    .withMessage('Invalid sale ID'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Dispatch sale validation rules
 * Validates sale ID for dispatch operation
 */
const validateDispatchSale = [
  // Validate sale ID parameter
  param('id')
    .isInt({ min: 1 }) // Sale ID must be a positive integer
    .withMessage('Invalid sale ID'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Check stock validation rules
 * Validates items array for bulk stock checking
 */
const validateCheckStock = [
  // Validate items array
  body('items')
    .notEmpty() // Items array is required
    .withMessage('Items array is required') // Error message
    .isArray({ min: 1 }) // Items must be an array with at least one item
    .withMessage('Items must be an array with at least one item'), // Error message
  
  // Validate items.*.product_id
  body('items.*.product_id')
    .notEmpty() // Product ID is required
    .withMessage('Item product_id is required') // Error message
    .isInt({ min: 1 }) // Product ID must be a positive integer
    .withMessage('Item product_id must be a positive integer'), // Error message
  
  // Variants removed - variant_id validation removed (variants no longer supported)
  
  // Validate items.*.quantity
  body('items.*.quantity')
    .notEmpty() // Quantity is required
    .withMessage('Item quantity is required') // Error message
    .isFloat({ min: 0.001 }) // Quantity must be a positive number
    .withMessage('Item quantity must be a positive number'), // Error message
  
  // Run validation middleware
  validate,
];

// Export validation rules
module.exports = {
  validateCreateSale, // Create sale validation rules
  validateGetSale, // Get sale validation rules
  validateListSales, // List sales validation rules
  validateCancelSale, // Cancel sale validation rules
  validateDispatchSale, // Dispatch sale validation rules
  validateCheckStock, // Check stock validation rules
};
