import { EmailRequest, EmailValidationResult } from '../interfaces/email-request.interface';

/**
 * Validates an email request
 */
export function validateEmailRequest(request: EmailRequest): EmailValidationResult {
  const errors: string[] = [];

  // Validate required fields
  if (!request.to) {
    errors.push('Recipient email is required');
  } else {
    const recipients = Array.isArray(request.to) ? request.to : [request.to];
    recipients.forEach((email, index) => {
      if (!isValidEmail(email)) {
        errors.push(`Invalid recipient email at index ${index}: ${email}`);
      }
    });
  }

  if (!request.subject) {
    errors.push('Subject is required');
  }

  if (!request.text && !request.html) {
    errors.push('Either text or html content is required');
  }

  // Validate optional fields
  if (request.from && !isValidEmail(request.from)) {
    errors.push('Invalid sender email');
  }

  if (request.replyTo && !isValidEmail(request.replyTo)) {
    errors.push('Invalid reply-to email');
  }

  // Validate CC recipients
  if (request.cc) {
    const ccRecipients = Array.isArray(request.cc) ? request.cc : [request.cc];
    ccRecipients.forEach((email, index) => {
      if (!isValidEmail(email)) {
        errors.push(`Invalid CC email at index ${index}: ${email}`);
      }
    });
  }

  // Validate BCC recipients
  if (request.bcc) {
    const bccRecipients = Array.isArray(request.bcc) ? request.bcc : [request.bcc];
    bccRecipients.forEach((email, index) => {
      if (!isValidEmail(email)) {
        errors.push(`Invalid BCC email at index ${index}: ${email}`);
      }
    });
  }

  return {
    isValid: errors.length === 0,
    errors
  };
}

/**
 * Validates a single email address
 */
export function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

/**
 * Checks for common email typos and suggests corrections
 */
export function checkEmailTypos(email: string): string | null {
  if (!email || typeof email !== 'string') {
    return null;
  }

  const commonTypos: Record<string, string> = {
    'gmail.com': 'gmail.com',
    'gmial.com': 'gmail.com',
    'gmal.com': 'gmail.com',
    'gmai.com': 'gmail.com',
    'hotmail.com': 'hotmail.com',
    'hotmial.com': 'hotmail.com',
    'hotmai.com': 'hotmail.com',
    'yahoo.com': 'yahoo.com',
    'yaho.com': 'yahoo.com',
    'outlook.com': 'outlook.com',
    'outlok.com': 'outlook.com',
  };

  const parts = email.split('@');
  if (parts.length !== 2) {
    return null;
  }

  const localPart = parts[0];
  const domain = parts[1];
  const correctedDomain = commonTypos[domain];
  
  if (correctedDomain && correctedDomain !== domain) {
    return `${localPart}@${correctedDomain}`;
  }
  
  return null;
}

/**
 * Validates and suggests corrections for an email address
 */
export function validateEmail(email: string): {
  isValid: boolean;
  suggestion: string | null;
  message: string;
} {
  if (!email || typeof email !== 'string') {
    return {
      isValid: false,
      suggestion: null,
      message: 'Email is required',
    };
  }

  // Check for common typos
  const correctedEmail = checkEmailTypos(email);

  // Check if email is valid
  const valid = isValidEmail(email);

  if (valid) {
    return {
      isValid: true,
      suggestion: null,
      message: 'Email is valid',
    };
  } else if (correctedEmail && isValidEmail(correctedEmail)) {
    return {
      isValid: false,
      suggestion: correctedEmail,
      message: `Invalid email. Did you mean ${correctedEmail}?`,
    };
  } else {
    return {
      isValid: false,
      suggestion: null,
      message: 'Invalid email format',
    };
  }
}

/**
 * Extracts the domain from an email address
 *
 * @param email - Email address
 * @returns string | null - Domain or null if invalid
 */
export function getEmailDomain(email: string): string | null {
  if (!isValidEmail(email)) {
    return null;
  }

  const atIndex = email.lastIndexOf('@');
  return email.substring(atIndex + 1);
}
