const { body, param, query, validationResult } = require('express-validator');

// Helper function to handle validation errors
const handleValidationErrors = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({
      success: false,
      message: 'Validation failed',
      errors: errors.array().map(err => ({
        field: err.param,
        message: err.msg,
        value: err.value
      }))
    });
  }
  next();
};

// Validate create order request
exports.validateOrder = [
  body('userId')
    .notEmpty()
    .withMessage('User ID is required')
    .isInt({ min: 1 })
    .withMessage('User ID must be a positive integer'),

  body('items')
    .notEmpty()
    .withMessage('Order items are required')
    .isArray({ min: 1 })
    .withMessage('Order must contain at least one item'),

  body('items.*.productId')
    .notEmpty()
    .withMessage('Product ID is required for each item')
    .isInt({ min: 1 })
    .withMessage('Product ID must be a positive integer'),

  body('items.*.quantity')
    .notEmpty()
    .withMessage('Quantity is required for each item')
    .isInt({ min: 1 })
    .withMessage('Quantity must be at least 1'),

  body('items.*.price')
    .optional()
    .isFloat({ min: 0 })
    .withMessage('Price must be a positive number'),

  body('items.*.productVariantId')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Product variant ID must be a positive integer'),

  body('shippingAddressId')
    .notEmpty()
    .withMessage('Shipping address is required')
    .isInt({ min: 1 })
    .withMessage('Shipping address ID must be a positive integer'),

  body('billingAddressId')
    .notEmpty()
    .withMessage('Billing address is required')
    .isInt({ min: 1 })
    .withMessage('Billing address ID must be a positive integer'),

  body('paymentMethod')
    .notEmpty()
    .withMessage('Payment method is required')
    .isIn(['credit_card', 'debit_card', 'paypal', 'stripe', 'cash_on_delivery', 'bank_transfer', 'mobile_money'])
    .withMessage('Invalid payment method'),

  body('couponCode')
    .optional()
    .isString()
    .trim()
    .isLength({ min: 3, max: 50 })
    .withMessage('Coupon code must be between 3 and 50 characters'),

  body('shippingCost')
    .optional()
    .isFloat({ min: 0 })
    .withMessage('Shipping cost must be a positive number'),

  body('notes')
    .optional()
    .isString()
    .trim()
    .isLength({ max: 500 })
    .withMessage('Notes must not exceed 500 characters'),

  handleValidationErrors
];

// Validate order status update
exports.validateOrderUpdate = [
  param('orderId')
    .notEmpty()
    .withMessage('Order ID is required')
    .isInt({ min: 1 })
    .withMessage('Order ID must be a positive integer'),

  body('status')
    .notEmpty()
    .withMessage('Status is required')
    .isIn(['pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded', 'failed'])
    .withMessage('Invalid order status'),

  body('description')
    .optional()
    .isString()
    .trim()
    .isLength({ max: 500 })
    .withMessage('Description must not exceed 500 characters'),

  body('updatedBy')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Updated by must be a valid user ID'),

  handleValidationErrors
];

// Validate payment status update
exports.validatePaymentUpdate = [
  param('orderId')
    .notEmpty()
    .withMessage('Order ID is required')
    .isInt({ min: 1 })
    .withMessage('Order ID must be a positive integer'),

  body('paymentStatus')
    .notEmpty()
    .withMessage('Payment status is required')
    .isIn(['pending', 'paid', 'failed', 'refunded', 'partially_refunded'])
    .withMessage('Invalid payment status'),

  body('transactionId')
    .optional()
    .isString()
    .trim()
    .isLength({ min: 3, max: 100 })
    .withMessage('Transaction ID must be between 3 and 100 characters'),

  body('paymentDetails')
    .optional()
    .isObject()
    .withMessage('Payment details must be an object'),

  handleValidationErrors
];

// Validate bulk update
exports.validateBulkUpdate = [
  body('orderIds')
    .notEmpty()
    .withMessage('Order IDs are required')
    .isArray({ min: 1 })
    .withMessage('Order IDs must be a non-empty array'),

  body('orderIds.*')
    .isInt({ min: 1 })
    .withMessage('Each order ID must be a positive integer'),

  body('updates')
    .notEmpty()
    .withMessage('Updates object is required')
    .isObject()
    .withMessage('Updates must be an object'),

  body('updates.status')
    .optional()
    .isIn(['pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded', 'failed'])
    .withMessage('Invalid order status'),

  body('updates.paymentStatus')
    .optional()
    .isIn(['pending', 'paid', 'failed', 'refunded', 'partially_refunded'])
    .withMessage('Invalid payment status'),

  handleValidationErrors
];

// Validate order cancellation
exports.validateCancelOrder = [
  param('orderId')
    .notEmpty()
    .withMessage('Order ID is required')
    .isInt({ min: 1 })
    .withMessage('Order ID must be a positive integer'),

  body('reason')
    .notEmpty()
    .withMessage('Cancellation reason is required')
    .isString()
    .trim()
    .isLength({ min: 10, max: 500 })
    .withMessage('Reason must be between 10 and 500 characters'),

  body('cancelledBy')
    .notEmpty()
    .withMessage('Cancelled by user ID is required')
    .isInt({ min: 1 })
    .withMessage('Cancelled by must be a valid user ID'),

  handleValidationErrors
];

// Validate order items update
exports.validateOrderItemsUpdate = [
  param('orderId')
    .notEmpty()
    .withMessage('Order ID is required')
    .isInt({ min: 1 })
    .withMessage('Order ID must be a positive integer'),

  body('items')
    .notEmpty()
    .withMessage('Items are required')
    .isArray({ min: 1 })
    .withMessage('Items must be a non-empty array'),

  body('items.*.orderItemId')
    .notEmpty()
    .withMessage('Order item ID is required')
    .isInt({ min: 1 })
    .withMessage('Order item ID must be a positive integer'),

  body('items.*.quantity')
    .notEmpty()
    .withMessage('Quantity is required')
    .isInt({ min: 0 })
    .withMessage('Quantity must be a non-negative integer'),

  handleValidationErrors
];

// Validate query parameters for listing orders
exports.validateOrderQuery = [
  query('page')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Page must be a positive integer'),

  query('limit')
    .optional()
    .isInt({ min: 1, max: 100 })
    .withMessage('Limit must be between 1 and 100'),

  query('status')
    .optional()
    .isIn(['pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded', 'failed'])
    .withMessage('Invalid order status'),

  query('paymentStatus')
    .optional()
    .isIn(['pending', 'paid', 'failed', 'refunded', 'partially_refunded'])
    .withMessage('Invalid payment status'),

  query('startDate')
    .optional()
    .isISO8601()
    .withMessage('Start date must be a valid ISO 8601 date'),

  query('endDate')
    .optional()
    .isISO8601()
    .withMessage('End date must be a valid ISO 8601 date'),

  query('sortBy')
    .optional()
    .isIn(['createdAt', 'updatedAt', 'total', 'status', 'orderNumber'])
    .withMessage('Invalid sort field'),

  query('sortOrder')
    .optional()
    .isIn(['ASC', 'DESC'])
    .withMessage('Sort order must be ASC or DESC'),

  query('search')
    .optional()
    .isString()
    .trim()
    .isLength({ max: 100 })
    .withMessage('Search query must not exceed 100 characters'),

  handleValidationErrors
];

// Validate order ID parameter
exports.validateOrderId = [
  param('orderId')
    .notEmpty()
    .withMessage('Order ID is required')
    .isInt({ min: 1 })
    .withMessage('Order ID must be a positive integer'),

  handleValidationErrors
];

// Validate order number parameter
exports.validateOrderNumber = [
  param('orderNumber')
    .notEmpty()
    .withMessage('Order number is required')
    .isString()
    .trim()
    .matches(/^ORD-\d+-[A-Z0-9]+$/)
    .withMessage('Invalid order number format'),

  handleValidationErrors
];

// Validate user ID parameter
exports.validateUserId = [
  param('userId')
    .notEmpty()
    .withMessage('User ID is required')
    .isInt({ min: 1 })
    .withMessage('User ID must be a positive integer'),

  handleValidationErrors
];

// Validate reorder request
exports.validateReorder = [
  param('orderId')
    .notEmpty()
    .withMessage('Order ID is required')
    .isInt({ min: 1 })
    .withMessage('Order ID must be a positive integer'),

  body('userId')
    .optional()
    .isInt({ min: 1 })
    .withMessage('User ID must be a positive integer'),

  body('shippingAddressId')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Shipping address ID must be a positive integer'),

  body('billingAddressId')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Billing address ID must be a positive integer'),

  handleValidationErrors
];

// Validate export orders query
exports.validateExportQuery = [
  query('startDate')
    .optional()
    .isISO8601()
    .withMessage('Start date must be a valid ISO 8601 date'),

  query('endDate')
    .optional()
    .isISO8601()
    .withMessage('End date must be a valid ISO 8601 date'),

  query('status')
    .optional()
    .isIn(['pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded', 'failed'])
    .withMessage('Invalid order status'),

  query('paymentStatus')
    .optional()
    .isIn(['pending', 'paid', 'failed', 'refunded', 'partially_refunded'])
    .withMessage('Invalid payment status'),

  handleValidationErrors
];

// Validate order statistics query
exports.validateStatsQuery = [
  query('startDate')
    .optional()
    .isISO8601()
    .withMessage('Start date must be a valid ISO 8601 date'),

  query('endDate')
    .optional()
    .isISO8601()
    .withMessage('End date must be a valid ISO 8601 date'),

  query('groupBy')
    .optional()
    .isIn(['hour', 'day', 'week', 'month', 'year'])
    .withMessage('Group by must be one of: hour, day, week, month, year'),

  handleValidationErrors
];