/**
 * URL Validation Utilities
 * 
 * Provides robust URL validation that works across different environments
 * (browser, Node.js, Jest) with multiple fallback strategies.
 */

import {
  SUPPORTED_PROTOCOLS,
  HTTP_URL_PATTERN,
  TLD_PATTERN,
} from '../../constants';

/**
 * Resolves the URL constructor available in the current environment
 * @returns {Function|null} URL constructor function or null if not available
 */
const resolveUrlConstructor = () => {
  if (typeof window !== 'undefined' && typeof window.URL === 'function') {
    return window.URL;
  }

  if (typeof URL === 'function') {
    return URL;
  }

  return null;
};

/**
 * Checks if document API is available for DOM-based validation
 * @returns {boolean} True if document.createElement is available
 */
const canUseDocument = () => typeof document !== 'undefined' && typeof document.createElement === 'function';

/**
 * Validates if a value is a valid HTTP/HTTPS URL
 * Uses multiple validation strategies for maximum compatibility:
 * 1. Regex pattern check for http:// or https:// prefix
 * 2. URL constructor validation (if available)
 * 3. DOM-based validation using anchor element (if available)
 * 
 * @param {string} value - The URL string to validate
 * @returns {boolean} True if the value is a valid HTTP/HTTPS URL
 */
export const isValidHttpUrl = (value) => {
  if (!value) {
    return false;
  }

  const trimmedValue = value.trim();
  if (!trimmedValue) {
    return false;
  }

  // First check: regex pattern for http:// or https:// prefix
  if (!HTTP_URL_PATTERN.test(trimmedValue)) {
    return false;
  }

  // Second check: ensure URL has a valid TLD (Top Level Domain)
  // URLs like https://google are invalid, but https://google.com is valid
  if (!TLD_PATTERN.test(trimmedValue)) {
    return false;
  }

  // Third check: try URL constructor if available
  const UrlConstructor = resolveUrlConstructor();
  if (UrlConstructor) {
    try {
      const parsedUrl = new UrlConstructor(trimmedValue);
      if (SUPPORTED_PROTOCOLS.has(parsedUrl.protocol)) {
        return true;
      }
    } catch (error) {
      // URL constructor failed, fall back to DOM-based validation
    }
  }

  // Fourth check: DOM-based validation using anchor element
  if (canUseDocument()) {
    const parser = document.createElement('a');
    parser.href = trimmedValue;
    if (SUPPORTED_PROTOCOLS.has(parser.protocol)) {
      return true;
    }
  }

  // If all validation methods failed, return false
  return false;
};

/**
 * Validates a URL value and returns an error message if invalid
 * This is a higher-level validation function that can be used with form validation
 * 
 * @param {string} value - The URL string to validate
 * @param {Function} formatMessage - Function to format error messages (e.g., react-intl formatMessage)
 * @param {Object} messages - Object containing error message keys:
 *   - urlRequired: Message for empty URL
 *   - urlInvalid: Message for invalid URL format
 * @returns {string} Empty string if valid, error message if invalid
 */
export const validateUrl = (value, formatMessage, messages) => {
  if (!value || value.trim() === '') {
    return formatMessage(messages.urlRequired);
  }

  if (!isValidHttpUrl(value)) {
    return formatMessage(messages.urlInvalid);
  }

  return '';
};

