/**
 * HTML Sanitization Module
 *
 * Provides secure HTML rendering with DOMPurify integration.
 * Ensures consistent XSS protection across the application.
 */

/**
 * Sanitize HTML content for safe rendering
 *
 * @param {string} html - HTML to sanitize
 * @param {object} options - DOMPurify options
 * @returns {string} Sanitized HTML
 */
export function sanitizeHtml(html, options = {}) {
  const defaultOptions = {
    ALLOWED_TAGS: [
      'div', 'span', 'p', 'a', 'button', 'input', 'textarea',
      'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
      'ul', 'ol', 'li', 'table', 'tr', 'td', 'th', 'thead', 'tbody',
      'strong', 'em', 'code', 'pre', 'blockquote',
      'svg', 'img'
    ],
    ALLOWED_ATTR: [
      'class', 'id', 'style', 'data-*',
      'href', 'target', 'rel',
      'type', 'placeholder', 'disabled', 'checked', 'name', 'value',
      'alt', 'src', 'width', 'height',
      'aria-label', 'aria-describedby', 'aria-invalid', 'role'
    ],
    KEEP_CONTENT: true,
    RETURN_DOM: false
  };

  const mergedOptions = { ...defaultOptions, ...options };

  // Use DOMPurify if available (loaded in HTML)
  if (typeof DOMPurify !== 'undefined') {
    return DOMPurify.sanitize(html, mergedOptions);
  }

  // Fallback: escape HTML (basic protection)
  console.warn('DOMPurify not available, using basic HTML escaping');
  return escapeHtml(html);
}

/**
 * Escape HTML special characters (basic XSS protection)
 *
 * @param {string} text - Text to escape
 * @returns {string} Escaped text
 */
export function escapeHtml(text) {
  const map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };
  return text.replace(/[&<>"']/g, char => map[char]);
}

/**
 * Safely set innerHTML on an element
 *
 * @param {HTMLElement} element - Target element
 * @param {string} html - HTML to set (will be sanitized)
 * @param {object} options - Sanitization options
 */
export function setSafeHtml(element, html, options = {}) {
  if (!element) {
    console.warn('setSafeHtml: element is null or undefined');
    return;
  }
  element.innerHTML = sanitizeHtml(html, options);
}

/**
 * Sanitize text for safe display (no HTML)
 *
 * @param {string} text - Text to sanitize
 * @returns {string} Sanitized text
 */
export function sanitizeText(text) {
  return escapeHtml(String(text || ''));
}

/**
 * Sanitize URL for safe linking
 *
 * @param {string} url - URL to sanitize
 * @returns {string} Safe URL or empty string
 */
export function sanitizeUrl(url) {
  try {
    // Only allow safe protocols
    const allowedProtocols = ['http:', 'https:', 'mailto:', 'tel:', 'data:'];
    const urlObj = new URL(url, window.location.href);

    if (allowedProtocols.includes(urlObj.protocol)) {
      return url;
    }

    console.warn(`Unsafe URL protocol: ${urlObj.protocol}`);
    return '';
  } catch (e) {
    console.warn(`Invalid URL: ${url}`);
    return '';
  }
}

/**
 * Create safe HTML element from template literal
 *
 * Usage:
 *   const html = createSafeHtml`
 *     <div class="card">
 *       <h3>${title}</h3>
 *       <p>${description}</p>
 *     </div>
 *   `;
 *
 * @param {string[]} strings - Template strings
 * @param {...any} values - Interpolated values (will be escaped)
 * @returns {string} Safe HTML
 */
export function createSafeHtml(strings, ...values) {
  let result = '';

  for (let i = 0; i < strings.length; i++) {
    result += strings[i];

    if (i < values.length) {
      // Escape all interpolated values
      const value = values[i];

      if (value === null || value === undefined) {
        result += '';
      } else if (typeof value === 'object') {
        result += sanitizeText(JSON.stringify(value));
      } else {
        result += sanitizeText(String(value));
      }
    }
  }

  return result;
}

/**
 * Validate HTML structure without executing scripts
 *
 * @param {string} html - HTML to validate
 * @returns {boolean} True if HTML is well-formed
 */
export function validateHtml(html) {
  try {
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, 'text/html');

    // Check for parsing errors
    if (doc.getElementsByTagName('parsererror').length > 0) {
      return false;
    }

    return true;
  } catch (e) {
    return false;
  }
}

export default {
  sanitizeHtml,
  escapeHtml,
  setSafeHtml,
  sanitizeText,
  sanitizeUrl,
  createSafeHtml,
  validateHtml
};
