/**
 * User Management Validation Rules
 * Input validation rules for user 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();
};

/**
 * Create user validation rules
 * Validates user data for user creation
 */
const validateCreateUser = [
  // Validate username field
  body('username')
    .trim() // Remove whitespace
    .notEmpty() // Username is required
    .withMessage('Username is required') // Error message
    .isLength({ min: 3, max: 100 }) // Username length validation
    .withMessage('Username must be between 3 and 100 characters') // Error message
    .matches(/^[a-zA-Z0-9_]+$/) // Username can only contain letters, numbers, and underscores
    .withMessage('Username can only contain letters, numbers, and underscores'), // Error message
  
  // Validate email field
  body('email')
    .trim() // Remove whitespace
    .notEmpty() // Email is required
    .withMessage('Email is required') // Error message
    .isEmail() // Validate email format
    .withMessage('Invalid email format') // Error message
    .normalizeEmail(), // Normalize email (lowercase, etc.)
  
  // Validate password field
  body('password')
    .notEmpty() // Password is required
    .withMessage('Password is required') // Error message
    .isLength({ min: 6 }) // Minimum password length
    .withMessage('Password must be at least 6 characters'), // Error message
  
  // Validate full_name field (optional)
  body('full_name')
    .optional() // Field is optional
    .trim() // Remove whitespace
    .isLength({ max: 200 }) // Maximum length
    .withMessage('Full name must not exceed 200 characters'), // Error message
  
  // Validate role field (optional)
  body('role')
    .optional() // Field is optional
    .isIn(['cashier', 'manager', 'system_admin']) // Role must be one of these values
    .withMessage('Role must be one of: cashier, manager, system_admin'), // Error message
  
  // Validate pin_code field (optional)
  body('pin_code')
    .optional() // Field is optional
    .isLength({ min: 4, max: 6 }) // PIN code length (4-6 digits)
    .withMessage('PIN code must be between 4 and 6 characters') // Error message
    .isNumeric() // PIN code must be numeric
    .withMessage('PIN code must be numeric'), // Error message
  
  // Validate active field (optional)
  body('active')
    .optional() // Field is optional
    .isBoolean() // Active must be boolean
    .withMessage('Active must be a boolean value'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * Update user validation rules
 * Validates user data for user updates
 */
const validateUpdateUser = [
  // Validate user ID parameter
  param('id')
    .isInt({ min: 1 }) // User ID must be a positive integer
    .withMessage('Invalid user ID'), // Error message
  
  // Validate username field (optional)
  body('username')
    .optional() // Field is optional
    .trim() // Remove whitespace
    .isLength({ min: 3, max: 100 }) // Username length validation
    .withMessage('Username must be between 3 and 100 characters') // Error message
    .matches(/^[a-zA-Z0-9_]+$/) // Username can only contain letters, numbers, and underscores
    .withMessage('Username can only contain letters, numbers, and underscores'), // Error message
  
  // Validate email field (optional)
  body('email')
    .optional() // Field is optional
    .trim() // Remove whitespace
    .isEmail() // Validate email format
    .withMessage('Invalid email format') // Error message
    .normalizeEmail(), // Normalize email (lowercase, etc.)
  
  // Validate password field (optional)
  body('password')
    .optional() // Field is optional
    .isLength({ min: 6 }) // Minimum password length
    .withMessage('Password must be at least 6 characters'), // Error message
  
  // Validate full_name field (optional)
  body('full_name')
    .optional() // Field is optional
    .trim() // Remove whitespace
    .isLength({ max: 200 }) // Maximum length
    .withMessage('Full name must not exceed 200 characters'), // Error message
  
  // Validate role field (optional)
  body('role')
    .optional() // Field is optional
    .isIn(['cashier', 'manager', 'system_admin']) // Role must be one of these values
    .withMessage('Role must be one of: cashier, manager, system_admin'), // Error message
  
  // Validate pin_code field (optional)
  body('pin_code')
    .optional() // Field is optional
    .isLength({ min: 4, max: 6 }) // PIN code length (4-6 digits)
    .withMessage('PIN code must be between 4 and 6 characters') // Error message
    .isNumeric() // PIN code must be numeric
    .withMessage('PIN code must be numeric'), // Error message
  
  // Validate active field (optional)
  body('active')
    .optional() // Field is optional
    .isBoolean() // Active must be boolean
    .withMessage('Active must be a boolean value'), // Error message
  
  // Run validation middleware
  validate,
];

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

/**
 * Delete user validation rules
 * Validates user ID parameter for deletion
 */
const validateDeleteUser = [
  // Validate user ID parameter
  param('id')
    .isInt({ min: 1 }) // User ID must be a positive integer
    .withMessage('Invalid user ID'), // Error message
  
  // Run validation middleware
  validate,
];

/**
 * List users validation rules
 * Validates query parameters for user listing
 */
const validateListUsers = [
  // 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 role query parameter (optional)
  query('role')
    .optional() // Field is optional
    .isIn(['cashier', 'manager', 'system_admin']) // Role must be one of these values
    .withMessage('Role must be one of: cashier, manager, system_admin'), // Error message
  
  // Validate active query parameter (optional)
  query('active')
    .optional() // Field is optional
    .isIn(['true', 'false']) // Active must be 'true' or 'false' string
    .withMessage('Active must be "true" or "false"'), // Error message
  
  // Run validation middleware
  validate,
];

// Export validation rules
module.exports = {
  validateCreateUser, // Create user validation rules
  validateUpdateUser, // Update user validation rules
  validateGetUser, // Get user validation rules
  validateDeleteUser, // Delete user validation rules
  validateListUsers, // List users validation rules
};

