const { check, validationResult } = require('express-validator');

// Middleware to handle validation errors
const validate = (validations) => {
  return async (req, res, next) => {
    await Promise.all(validations.map(validation => validation.run(req)));

    const errors = validationResult(req);
    if (errors.isEmpty()) {
      return next();
    }

    // Format errors
    const extractedErrors = [];
    errors.array().map(err => extractedErrors.push({ 
      param: err.param, 
      msg: err.msg,
      location: err.location
    }));

    return res.status(422).json({
      success: false,
      errors: extractedErrors,
      msg: 'Validation failed'
    });
  };
};

// Validation rules for user registration
const registerRules = () => {
  return [
    check('name', 'Name is required').not().isEmpty().trim().escape(),
    check('email', 'Please include a valid email').isEmail().normalizeEmail(),
    check('password', 'Please enter a password with 6 or more characters')
      .isLength({ min: 6 }),
    check('phone', 'Please include a valid phone number').isMobilePhone(),
    check('role', 'Please specify a valid role').isIn(['user', 'delivery_boy', 'admin']).optional()
  ];
};

// Validation rules for user login
const loginRules = () => {
  return [
    check('email', 'Please include a valid email').isEmail(),
    check('password', 'Password is required').exists()
  ];
};

// Validation rules for address
const addressRules = () => {
  return [
    check('country', 'Country is required').not().isEmpty().trim().escape(),
    check('state', 'State is required').not().isEmpty().trim().escape(),
    check('city', 'City is required').not().isEmpty().trim().escape(),
    check('postcode').optional({ checkFalsy: true }).trim().escape(),
    check('address', 'Address is required').not().isEmpty().trim().escape(),
    check('latitude', 'Please provide valid coordinates').isFloat({ min: -90, max: 90 }),
    check('longitude', 'Please provide valid coordinates').isFloat({ min: -180, max: 180 })
  ];
};

// Validation rules for updating user profile
const updateProfileRules = () => {
  return [
    check('name', 'Name is required').not().isEmpty().trim().escape().optional(),
    check('email', 'Please include a valid email').isEmail().normalizeEmail().optional(),
    check('phone', 'Please include a valid phone number').isMobilePhone().optional(),
    check('currentPassword', 'Current password is required').if((value, { req }) => req.body.newPassword),
    check('newPassword', 'New password must be at least 6 characters long')
      .if((value, { req }) => req.body.currentPassword)
      .isLength({ min: 6 })
  ];
};

// Validation rules for creating/updating items
const itemRules = () => {
  return [
    check('name', 'Name is required').not().isEmpty().trim().escape(),
    check('description', 'Description is required').not().isEmpty().trim().escape(),
    check('price', 'Price must be a positive number').isFloat({ min: 0 }),
    check('discount_price', 'Discount price must be a positive number').optional().isFloat({ min: 0 }),
    check('category_id', 'Category ID is required').isInt({ min: 1 }),
    check('brand_id', 'Brand ID is required').isInt({ min: 1 }),
    check('unit_id', 'Unit ID is required').isInt({ min: 1 }),
    check('tax_id', 'Tax ID is required').isInt({ min: 1 }),
    check('discount_id', 'Discount ID must be a positive integer').optional().isInt({ min: 1 }),
    check('stock', 'Stock must be a non-negative integer').isInt({ min: 0 }),
    check('min_order_qty', 'Minimum order quantity must be a positive integer').isInt({ min: 1 }),
    check('max_order_qty', 'Maximum order quantity must be a positive integer').isInt({ min: 1 }),
    check('is_featured', 'is_featured must be a boolean').optional().isBoolean(),
    check('is_active', 'is_active must be a boolean').optional().isBoolean()
  ];
};

// Validation rules for creating/updating orders
const orderRules = () => {
  return [
    check('user_id', 'User ID is required').isInt({ min: 1 }),
    check('delivery_address_id', 'Delivery address ID is required').isInt({ min: 1 }),
    check('payment_method', 'Payment method is required').isIn(['cod', 'online', 'wallet']),
    check('payment_status', 'Payment status is required').isIn(['pending', 'completed', 'failed', 'refunded']),
    check('order_status', 'Order status is required').isIn([
      'pending', 'confirmed', 'processing', 'out_for_delivery', 'delivered', 'cancelled', 'returned'
    ]),
    check('subtotal', 'Subtotal must be a positive number').isFloat({ min: 0 }),
    check('tax_amount', 'Tax amount must be a non-negative number').isFloat({ min: 0 }),
    check('delivery_charge', 'Delivery charge must be a non-negative number').isFloat({ min: 0 }),
    check('discount_amount', 'Discount amount must be a non-negative number').optional().isFloat({ min: 0 }),
    check('total_amount', 'Total amount must be a positive number').isFloat({ min: 0 }),
    check('items', 'Order items are required').isArray({ min: 1 }),
    check('items.*.item_id', 'Item ID is required for all items').isInt({ min: 1 }),
    check('items.*.quantity', 'Quantity must be a positive integer').isInt({ min: 1 }),
    check('items.*.price', 'Price must be a positive number').isFloat({ min: 0 }),
    check('items.*.total_price', 'Total price must be a positive number').isFloat({ min: 0 })
  ];
};

// Validation rules for creating/updating prescriptions
const prescriptionRules = () => {
  return [
    check('doctor_name', 'Doctor name must be a string').optional().isString().trim().escape(),
    check('patient_name', 'Patient name is required').not().isEmpty().trim().escape(),
    check('patient_age', 'Patient age is required').isInt({ min: 1, max: 120 }),
    check('patient_gender', 'Patient gender is required').isIn(['male', 'female', 'other']),
    check('diagnosis', 'Diagnosis must be a string').optional().isString().trim().escape(),
    check('notes', 'Notes must be a string').optional().isString().trim().escape(),
    check('prescription_date', 'Invalid prescription date').optional().isISO8601(),
    check('next_visit_date', 'Invalid next visit date').optional().isISO8601(),
    check('status', 'Invalid status').optional().isIn(['pending', 'approved', 'rejected']),
    check('rejection_reason', 'Rejection reason must be a string').optional().isString().trim().escape(),
    check('pharmacist_notes', 'Pharmacist notes must be a string').optional().isString().trim().escape()
  ];
};

module.exports = {
  validate,
  registerRules,
  loginRules,
  addressRules,
  updateProfileRules,
  itemRules,
  orderRules,
  prescriptionRules
};
