/**
 * Input Validation and Sanitization
 *
 * Protects against XSS, SQL injection, and malformed input
 */

import validator from 'validator';

// Conditionally import DOMPurify only in browser environment
// Server-side will use simple string sanitization
let DOMPurify: any = null;

if (typeof window !== 'undefined') {
  // Browser environment - use isomorphic-dompurify
  import('isomorphic-dompurify').then(module => {
    DOMPurify = module.default;
  }).catch(() => {
    console.warn('[Validation] DOMPurify not available in browser');
  });
}

/**
 * Sanitize string input by removing HTML tags and dangerous characters
 * Works in both server and browser environments
 */
export function sanitizeInput(input: string): string {
  if (!input) return '';

  let sanitized = input;

  // Use DOMPurify if available (browser), otherwise use regex sanitization (server)
  if (DOMPurify && typeof DOMPurify.sanitize === 'function') {
    // Browser: Use DOMPurify
    sanitized = DOMPurify.sanitize(input, {
      ALLOWED_TAGS: [],
      ALLOWED_ATTR: []
    }).trim();
  } else {
    // Server: Use regex-based sanitization
    // Remove HTML tags
    sanitized = input.replace(/<[^>]*>/g, '');

    // Remove HTML entities
    sanitized = sanitized.replace(/&[a-z]+;/gi, '');

    // Remove script tags content
    sanitized = sanitized.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
  }

  // Common sanitization (both server and browser)
  // Prevent javascript: protocol
  sanitized = sanitized.replace(/javascript:/gi, '');

  // Prevent data: URLs
  sanitized = sanitized.replace(/data:/gi, '');

  // Remove null bytes
  sanitized = sanitized.replace(/\0/g, '');

  // Remove other dangerous patterns
  sanitized = sanitized.replace(/vbscript:/gi, '');
  sanitized = sanitized.replace(/file:/gi, '');

  return sanitized.trim();
}

/**
 * Validate email address
 */
export function validateEmail(email: string): { valid: boolean; error?: string } {
  if (!email) {
    return { valid: false, error: 'Email is required' };
  }

  // Sanitize first
  const sanitized = sanitizeInput(email).toLowerCase();

  // Validate email format
  if (!validator.isEmail(sanitized)) {
    return { valid: false, error: 'Invalid email format' };
  }

  // Additional security checks
  if (/<|>|script/i.test(sanitized)) {
    return { valid: false, error: 'Invalid characters in email' };
  }

  if (sanitized.length > 254) {
    return { valid: false, error: 'Email address too long' };
  }

  return { valid: true };
}

/**
 * Validate and sanitize name (full name, company name, etc.)
 */
export function validateName(name: string): { valid: boolean; error?: string; sanitized?: string } {
  if (!name) {
    return { valid: false, error: 'Name is required' };
  }

  const sanitized = sanitizeInput(name);

  // Check length
  if (sanitized.length < 2) {
    return { valid: false, error: 'Name must be at least 2 characters' };
  }

  if (sanitized.length > 100) {
    return { valid: false, error: 'Name must be less than 100 characters' };
  }

  // Allow letters (including Arabic), spaces, hyphens, apostrophes
  if (!/^[\p{L}\s'\-]+$/u.test(sanitized)) {
    return { valid: false, error: 'Name contains invalid characters' };
  }

  return { valid: true, sanitized };
}

/**
 * Validate phone number (supports international formats with or without +)
 */
export function validatePhone(phone: string): { valid: boolean; error?: string; sanitized?: string } {
  if (!phone) {
    return { valid: false, error: 'Phone number is required' };
  }

  // Don't use sanitizeInput for phone - it removes + and other valid phone chars
  // Just trim and remove any HTML/script tags manually
  let cleaned = phone.trim().replace(/<[^>]*>/g, '');

  // Remove spaces, dashes, parentheses for validation (common in user input)
  const normalized = cleaned.replace(/[\s\-()]/g, '');

  // Must have at least 6 digits (relaxed to support country code + local number format)
  const digitsOnly = normalized.replace(/\D/g, '');
  if (digitsOnly.length < 6) {
    return { valid: false, error: 'Phone number must be at least 6 digits' };
  }

  if (digitsOnly.length > 15) {
    return { valid: false, error: 'Phone number too long (max 15 digits)' };
  }

  // Accept phone with or without + prefix
  // Validate international phone format: +[country code 1-3 digits][6-15 total digits]
  const phoneToValidate = normalized.startsWith('+') ? normalized : `+${normalized}`;

  // Custom validation - accept ANY country code (1-3 digits) followed by 6-15 total digits
  // This is more permissive than validator.isMobilePhone() which has limited country support
  const internationalPhonePattern = /^\+\d{7,15}$/; // +[country code + number] = 7-15 digits total

  if (!internationalPhonePattern.test(phoneToValidate)) {
    return { valid: false, error: 'Invalid phone number format. Use international format: +[country code][number]' };
  }

  // Return normalized version (with + if it had it, or add + if it didn't)
  const sanitized = normalized.startsWith('+') ? normalized : `+${normalized}`;

  return { valid: true, sanitized };
}

/**
 * Validate password strength
 */
export function validatePassword(password: string): { valid: boolean; error?: string } {
  if (!password) {
    return { valid: false, error: 'Password is required' };
  }

  // Minimum length: 12 characters
  if (password.length < 12) {
    return { valid: false, error: 'Password must be at least 12 characters' };
  }

  // Maximum length: 128 characters (prevent DoS)
  if (password.length > 128) {
    return { valid: false, error: 'Password must be less than 128 characters' };
  }

  // Must contain lowercase
  if (!/[a-z]/.test(password)) {
    return { valid: false, error: 'Password must contain lowercase letters' };
  }

  // Must contain uppercase
  if (!/[A-Z]/.test(password)) {
    return { valid: false, error: 'Password must contain uppercase letters' };
  }

  // Must contain numbers
  if (!/\d/.test(password)) {
    return { valid: false, error: 'Password must contain numbers' };
  }

  // Must contain special characters
  if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
    return { valid: false, error: 'Password must contain special characters' };
  }

  // Check against common passwords
  const commonPasswords = ['password', '12345678', 'qwerty', 'admin', 'letmein', 'welcome'];
  const lowerPass = password.toLowerCase();
  if (commonPasswords.some(common => lowerPass.includes(common))) {
    return { valid: false, error: 'Password is too common' };
  }

  return { valid: true };
}

/**
 * Validate OTP code format
 */
export function validateOTPCode(code: string): { valid: boolean; error?: string } {
  if (!code) {
    return { valid: false, error: 'Verification code is required' };
  }

  const sanitized = sanitizeInput(code);

  // Must be exactly 6 digits
  if (!/^\d{6}$/.test(sanitized)) {
    return { valid: false, error: 'Verification code must be 6 digits' };
  }

  return { valid: true };
}

/**
 * Validate company information (for B2B signup)
 */
export function validateCompanyInfo(data: {
  companyName?: string;
  businessType?: string;
  location?: string;
}): { valid: boolean; errors?: Record<string, string> } {
  const errors: Record<string, string> = {};

  if (data.companyName) {
    const nameResult = validateName(data.companyName);
    if (!nameResult.valid) {
      errors.companyName = nameResult.error!;
    }
  }

  if (data.businessType) {
    const sanitized = sanitizeInput(data.businessType);
    if (sanitized.length < 2 || sanitized.length > 100) {
      errors.businessType = 'Business type must be 2-100 characters';
    }
  }

  if (data.location) {
    const sanitized = sanitizeInput(data.location);
    if (sanitized.length < 2 || sanitized.length > 100) {
      errors.location = 'Location must be 2-100 characters';
    }
  }

  return {
    valid: Object.keys(errors).length === 0,
    errors: Object.keys(errors).length > 0 ? errors : undefined,
  };
}
