/**
 * Frontend Input Sanitization Utility
 * Provides client-side input validation and sanitization
 * NOTE: This is for UX only - server-side validation is the real security layer
 */

/**
 * Sanitize string to prevent XSS
 */
export function sanitizeString(str) {
  if (typeof str !== 'string') return str;
  
  // Remove HTML tags
  const temp = document.createElement('div');
  temp.textContent = str;
  let sanitized = temp.innerHTML;
  
  // Remove script-related content
  sanitized = sanitized.replace(/javascript:/gi, '');
  sanitized = sanitized.replace(/on\w+\s*=/gi, '');
  
  return sanitized;
}

/**
 * Validate and sanitize username
 */
export function validateUsername(username) {
  const errors = [];
  
  if (!username || typeof username !== 'string') {
    errors.push('Username is required');
    return { valid: false, errors, sanitized: '' };
  }
  
  const trimmed = username.trim();
  
  if (trimmed.length < 3) {
    errors.push('Username must be at least 3 characters');
  }
  
  if (trimmed.length > 50) {
    errors.push('Username must not exceed 50 characters');
  }
  
  if (!/^[a-zA-Z0-9_-]+$/.test(trimmed)) {
    errors.push('Username can only contain letters, numbers, hyphens, and underscores');
  }
  
  return {
    valid: errors.length === 0,
    errors,
    sanitized: sanitizeString(trimmed)
  };
}

/**
 * Validate email
 */
export function validateEmail(email) {
  const errors = [];
  
  if (!email || typeof email !== 'string') {
    errors.push('Email is required');
    return { valid: false, errors, sanitized: '' };
  }
  
  const trimmed = email.trim().toLowerCase();
  
  // Basic email regex
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(trimmed)) {
    errors.push('Invalid email format');
  }
  
  if (trimmed.length > 255) {
    errors.push('Email must not exceed 255 characters');
  }
  
  return {
    valid: errors.length === 0,
    errors,
    sanitized: sanitizeString(trimmed)
  };
}

/**
 * Validate URL
 */
export function validateUrl(url) {
  const errors = [];
  
  if (!url || typeof url !== 'string') {
    errors.push('URL is required');
    return { valid: false, errors, sanitized: '' };
  }
  
  const trimmed = url.trim();
  
  try {
    const urlObj = new URL(trimmed);
    const allowedProtocols = ['http:', 'https:', 'rtmp:', 'rtsp:', 'udp:', 'rtp:'];
    
    if (!allowedProtocols.includes(urlObj.protocol)) {
      errors.push('Invalid URL protocol');
    }
  } catch (e) {
    errors.push('Invalid URL format');
  }
  
  if (trimmed.length > 2048) {
    errors.push('URL must not exceed 2048 characters');
  }
  
  if (trimmed.includes('javascript:')) {
    errors.push('URL contains invalid content');
  }
  
  return {
    valid: errors.length === 0,
    errors,
    sanitized: trimmed
  };
}

/**
 * Validate text field
 */
export function validateTextField(value, minLength = 1, maxLength = 1000, required = true) {
  const errors = [];
  
  if (!value || value === '') {
    if (required) {
      errors.push('This field is required');
      return { valid: false, errors, sanitized: '' };
    }
    return { valid: true, errors: [], sanitized: '' };
  }
  
  if (typeof value !== 'string') {
    errors.push('Must be a string');
    return { valid: false, errors, sanitized: '' };
  }
  
  const trimmed = value.trim();
  
  if (required && trimmed.length < minLength) {
    errors.push(`Must be at least ${minLength} character${minLength > 1 ? 's' : ''}`);
  }
  
  if (trimmed.length > maxLength) {
    errors.push(`Must not exceed ${maxLength} characters`);
  }
  
  return {
    valid: errors.length === 0,
    errors,
    sanitized: sanitizeString(trimmed)
  };
}

/**
 * Validate integer
 */
export function validateInteger(value, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) {
  const errors = [];
  
  const num = parseInt(value, 10);
  
  if (isNaN(num)) {
    errors.push('Must be a valid number');
    return { valid: false, errors, sanitized: null };
  }
  
  if (num < min) {
    errors.push(`Must be at least ${min}`);
  }
  
  if (num > max) {
    errors.push(`Must not exceed ${max}`);
  }
  
  return {
    valid: errors.length === 0,
    errors,
    sanitized: num
  };
}

/**
 * Sanitize form data object
 */
export function sanitizeFormData(data) {
  const sanitized = {};
  
  for (const [key, value] of Object.entries(data)) {
    if (typeof value === 'string') {
      sanitized[key] = sanitizeString(value);
    } else if (typeof value === 'number' || typeof value === 'boolean') {
      sanitized[key] = value;
    } else if (value === null || value === undefined) {
      sanitized[key] = value;
    } else if (typeof value === 'object') {
      sanitized[key] = sanitizeFormData(value);
    }
  }
  
  return sanitized;
}

/**
 * Validate file upload
 */
export function validateFile(file, allowedTypes = [], maxSizeMB = 50) {
  const errors = [];
  
  if (!file) {
    errors.push('File is required');
    return { valid: false, errors };
  }
  
  // Check file size
  const maxSizeBytes = maxSizeMB * 1024 * 1024;
  if (file.size > maxSizeBytes) {
    errors.push(`File size must not exceed ${maxSizeMB}MB`);
  }
  
  // Check file type if restrictions exist
  if (allowedTypes.length > 0) {
    const fileExt = file.name.split('.').pop().toLowerCase();
    const mimeType = file.type.toLowerCase();
    
    const isAllowed = allowedTypes.some(type => {
      return mimeType.includes(type) || fileExt === type;
    });
    
    if (!isAllowed) {
      errors.push(`File type not allowed. Allowed types: ${allowedTypes.join(', ')}`);
    }
  }
  
  // Check filename
  const filename = file.name;
  if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
    errors.push('Invalid filename');
  }
  
  return {
    valid: errors.length === 0,
    errors
  };
}

/**
 * Escape HTML for display
 */
export function escapeHtml(text) {
  const map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };
  
  return text.replace(/[&<>"']/g, char => map[char]);
}

/**
 * Validate password strength (client-side check)
 */
export function validatePassword(password, username = '', email = '') {
  const errors = [];
  const requirements = {
    minLength: false,
    uppercase: false,
    lowercase: false,
    number: false,
    special: false,
    noUsername: true,
    noEmail: true
  };
  
  if (!password || typeof password !== 'string') {
    errors.push('Password is required');
    return { valid: false, errors, requirements, strength: 0 };
  }
  
  // Check requirements
  requirements.minLength = password.length >= 12;
  requirements.uppercase = /[A-Z]/.test(password);
  requirements.lowercase = /[a-z]/.test(password);
  requirements.number = /[0-9]/.test(password);
  requirements.special = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password);
  
  if (username && password.toLowerCase().includes(username.toLowerCase())) {
    requirements.noUsername = false;
    errors.push('Password cannot contain username');
  }
  
  if (email && password.toLowerCase().includes(email.split('@')[0].toLowerCase())) {
    requirements.noEmail = false;
    errors.push('Password cannot contain email');
  }
  
  // Calculate strength score
  let strength = 0;
  if (requirements.minLength) strength += 20;
  if (requirements.uppercase) strength += 15;
  if (requirements.lowercase) strength += 15;
  if (requirements.number) strength += 15;
  if (requirements.special) strength += 15;
  if (password.length > 15) strength += 10;
  if (password.length > 20) strength += 10;
  if (!requirements.noUsername || !requirements.noEmail) strength -= 30;
  
  strength = Math.max(0, Math.min(100, strength));
  
  // Add errors for missing requirements
  if (!requirements.minLength) errors.push('Password must be at least 12 characters');
  if (!requirements.uppercase) errors.push('Password must contain at least one uppercase letter');
  if (!requirements.lowercase) errors.push('Password must contain at least one lowercase letter');
  if (!requirements.number) errors.push('Password must contain at least one number');
  if (!requirements.special) errors.push('Password must contain at least one special character');
  
  return {
    valid: errors.length === 0,
    errors,
    requirements,
    strength
  };
}

export default {
  sanitizeString,
  validateUsername,
  validateEmail,
  validateUrl,
  validateTextField,
  validateInteger,
  sanitizeFormData,
  validateFile,
  escapeHtml,
  validatePassword
};
