/**
 * Sanitization utilities for user input
 * Prevents XSS attacks by escaping HTML special characters
 */

/**
 * Escape HTML special characters to prevent XSS
 * @param {string} str - String to escape
 * @returns {string} Escaped string
 */
const escapeHtml = (str) => {
  if (typeof str !== "string") {
    return str;
  }

  const htmlEscapeMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot;",
    "'": "&#x27;",
    "/": "&#x2F;",
  };

  return str.replace(/[&<>"'/]/g, (char) => htmlEscapeMap[char]);
};

/**
 * Sanitize object by escaping all string values
 * @param {Object} obj - Object to sanitize
 * @returns {Object} Sanitized object
 */
const sanitizeObject = (obj) => {
  if (typeof obj !== "object" || obj === null) {
    return obj;
  }

  const sanitized = {};
  for (const [key, value] of Object.entries(obj)) {
    if (typeof value === "string") {
      sanitized[key] = escapeHtml(value);
    } else if (typeof value === "object" && value !== null) {
      sanitized[key] = sanitizeObject(value);
    } else {
      sanitized[key] = value;
    }
  }

  return sanitized;
};

/**
 * Strip all HTML tags from a string
 * @param {string} str - String to strip
 * @returns {string} String without HTML tags
 */
const stripHtml = (str) => {
  if (typeof str !== "string") {
    return str;
  }

  return str.replace(/<[^>]*>/g, "");
};

/**
 * Validate and sanitize URL
 * @param {string} url - URL to validate
 * @returns {string|null} Sanitized URL or null if invalid
 */
const sanitizeUrl = (url) => {
  if (typeof url !== "string") {
    return null;
  }

  try {
    const parsed = new URL(url);
    // Only allow http and https protocols
    if (!["http:", "https:"].includes(parsed.protocol)) {
      return null;
    }
    return parsed.toString();
  } catch {
    return null;
  }
};

/**
 * Sanitize filename for safe storage
 * @param {string} filename - Filename to sanitize
 * @returns {string} Sanitized filename
 */
const sanitizeFilename = (filename) => {
  if (typeof filename !== "string") {
    return "file";
  }

  // Remove path separators and null bytes
  return filename
    .replace(/[\/\\]/g, "")
    .replace(/\0/g, "")
    .replace(/[^a-zA-Z0-9._-]/g, "-")
    .substring(0, 255);
};

module.exports = {
  escapeHtml,
  sanitizeObject,
  stripHtml,
  sanitizeUrl,
  sanitizeFilename,
};
