const { body, param, query, validationResult } = require("express-validator");
const logger = require("../config/logger");

// Validation error handler middleware
const handleValidationErrors = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    logger.warn("Validation error", {
      path: req.path,
      errors: errors.array(),
      body: req.body,
    });
    return res.status(400).json({
      success: false,
      message: "Validation failed",
      errors: errors.array().map((err) => ({
        field: err.param,
        message: err.msg,
      })),
    });
  }
  next();
};

// Common validation rules
const validators = {
  // Auth validators
  login: [
    body("email")
      .isEmail()
      .withMessage("Valid email is required")
      .normalizeEmail()
      .trim(),
    body("password").notEmpty().withMessage("Password is required").trim(),
  ],

  // User validators
  createUser: [
    body("email")
      .isEmail()
      .withMessage("Valid email is required")
      .normalizeEmail()
      .trim(),
    body("username")
      .isLength({ min: 3, max: 50 })
      .matches(/^[a-zA-Z0-9_-]+$/)
      .withMessage(
        "Username must be 3-50 characters and contain only letters, numbers, hyphens, and underscores"
      )
      .trim(),
    body("password")
      .isLength({ min: 12 })
      .matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#])/)
      .withMessage(
        "Password must be at least 12 characters with uppercase, lowercase, number, and special character"
      ),
    body("role_id").notEmpty().withMessage("Role is required").trim(),
  ],

  updateUser: [
    param("id")
      .matches(/^user-[a-f0-9-]+$/)
      .withMessage("Invalid user ID format"),
    body("email")
      .optional()
      .isEmail()
      .withMessage("Valid email is required")
      .normalizeEmail()
      .trim(),
    body("username")
      .optional()
      .isLength({ min: 3, max: 50 })
      .withMessage("Username must be 3-50 characters")
      .matches(/^[a-zA-Z0-9_-]+$/)
      .trim(),
  ],

  // Product validators
  createProduct: [
    body("name")
      .isLength({ min: 1, max: 255 })
      .withMessage("Product name is required (max 255 characters)")
      .trim(),
    body("shortdescription")
      .optional()
      .isString()
      .isLength({ max: 500 })
      .withMessage("Short description must be under 500 characters")
      .trim(),
    body("description")
      .optional()
      .isString()
      .withMessage("Description must be text"),
    body("price")
      .isFloat({ min: 0 })
      .withMessage("Price must be a positive number"),
    body("stockquantity")
      .optional()
      .isInt({ min: 0 })
      .withMessage("Stock quantity must be a non-negative integer"),
    body("category")
      .optional()
      .isString()
      .withMessage("Category must be text")
      .trim(),
    body("sku")
      .optional()
      .isString()
      .isLength({ max: 100 })
      .withMessage("SKU must be under 100 characters")
      .trim(),
    body("weight")
      .optional()
      .isFloat({ min: 0 })
      .withMessage("Weight must be a positive number"),
    body("dimensions")
      .optional()
      .isString()
      .isLength({ max: 100 })
      .withMessage("Dimensions must be under 100 characters")
      .trim(),
    body("material")
      .optional()
      .isString()
      .isLength({ max: 255 })
      .withMessage("Material must be under 255 characters")
      .trim(),
    body("isactive")
      .optional()
      .isBoolean()
      .withMessage("Active status must be true or false"),
    body("isfeatured")
      .optional()
      .isBoolean()
      .withMessage("Featured status must be true or false"),
    body("isbestseller")
      .optional()
      .isBoolean()
      .withMessage("Bestseller status must be true or false"),
    body("images").optional().isArray().withMessage("Images must be an array"),
    body("images.*.color_variant")
      .optional()
      .isString()
      .isLength({ max: 100 })
      .withMessage("Color variant must be under 100 characters")
      .trim(),
    body("images.*.image_url")
      .optional()
      .isString()
      .isLength({ max: 500 })
      .withMessage("Image URL must be under 500 characters"),
    body("images.*.alt_text")
      .optional()
      .isString()
      .isLength({ max: 255 })
      .withMessage("Alt text must be under 255 characters")
      .trim(),
  ],

  updateProduct: [
    param("id").notEmpty().withMessage("Invalid product ID"),
    body("name")
      .optional()
      .isLength({ min: 1, max: 255 })
      .withMessage("Product name must be 1-255 characters")
      .trim(),
    body("shortdescription")
      .optional()
      .isString()
      .isLength({ max: 500 })
      .withMessage("Short description must be under 500 characters")
      .trim(),
    body("description")
      .optional()
      .isString()
      .withMessage("Description must be text"),
    body("price")
      .optional()
      .isFloat({ min: 0 })
      .withMessage("Price must be a positive number"),
    body("stockquantity")
      .optional()
      .isInt({ min: 0 })
      .withMessage("Stock quantity must be a non-negative integer"),
    body("category")
      .optional()
      .isString()
      .withMessage("Category must be text")
      .trim(),
    body("sku")
      .optional()
      .isString()
      .isLength({ max: 100 })
      .withMessage("SKU must be under 100 characters")
      .trim(),
    body("weight")
      .optional()
      .isFloat({ min: 0 })
      .withMessage("Weight must be a positive number"),
    body("dimensions")
      .optional()
      .isString()
      .isLength({ max: 100 })
      .withMessage("Dimensions must be under 100 characters")
      .trim(),
    body("material")
      .optional()
      .isString()
      .isLength({ max: 255 })
      .withMessage("Material must be under 255 characters")
      .trim(),
    body("isactive")
      .optional()
      .isBoolean()
      .withMessage("Active status must be true or false"),
    body("isfeatured")
      .optional()
      .isBoolean()
      .withMessage("Featured status must be true or false"),
    body("isbestseller")
      .optional()
      .isBoolean()
      .withMessage("Bestseller status must be true or false"),
    body("images").optional().isArray().withMessage("Images must be an array"),
    body("images.*.color_variant")
      .optional()
      .isString()
      .isLength({ max: 100 })
      .withMessage("Color variant must be under 100 characters")
      .trim(),
    body("images.*.image_url")
      .optional()
      .isString()
      .isLength({ max: 500 })
      .withMessage("Image URL must be under 500 characters"),
    body("images.*.alt_text")
      .optional()
      .isString()
      .isLength({ max: 255 })
      .withMessage("Alt text must be under 255 characters")
      .trim(),
  ],

  // Blog validators
  createBlogPost: [
    body("title")
      .isLength({ min: 1, max: 255 })
      .withMessage("Title is required (max 255 characters)")
      .trim()
      .escape(),
    body("slug")
      .isLength({ min: 1, max: 255 })
      .matches(/^[a-z0-9-]+$/)
      .withMessage(
        "Slug must contain only lowercase letters, numbers, and hyphens"
      )
      .trim(),
    body("content").notEmpty().withMessage("Content is required").trim(),
  ],

  // Generic ID validator
  idParam: [param("id").notEmpty().withMessage("ID is required").trim()],

  // Pagination validators
  pagination: [
    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"),
  ],
};

module.exports = {
  validators,
  handleValidationErrors,
};
