import { smtpClientMod } from '../../ts/mail/delivery/index.js';
import type { ISmtpClientOptions, SmtpClient } from '../../ts/mail/delivery/smtpclient/index.js';
import { Email } from '../../ts/mail/core/classes.email.js';

/**
 * Create a test SMTP client
 */
export function createTestSmtpClient(options: Partial<ISmtpClientOptions> = {}): SmtpClient {
  const defaultOptions: ISmtpClientOptions = {
    host: options.host || 'localhost',
    port: options.port || 2525,
    secure: options.secure || false,
    auth: options.auth,
    connectionTimeout: options.connectionTimeout || 5000,
    socketTimeout: options.socketTimeout || 5000,
    maxConnections: options.maxConnections || 5,
    maxMessages: options.maxMessages || 100,
    debug: options.debug || false,
    tls: options.tls || {
      rejectUnauthorized: false
    }
  };
  
  return smtpClientMod.createSmtpClient(defaultOptions);
}

/**
 * Send test email using SMTP client
 */
export async function sendTestEmail(
  client: SmtpClient,
  options: {
    from?: string;
    to?: string | string[];
    subject?: string;
    text?: string;
    html?: string;
  } = {}
): Promise<any> {
  const mailOptions = {
    from: options.from || 'test@example.com',
    to: options.to || 'recipient@example.com',
    subject: options.subject || 'Test Email',
    text: options.text || 'This is a test email',
    html: options.html
  };
  
  const email = new Email({
    from: mailOptions.from,
    to: mailOptions.to,
    subject: mailOptions.subject,
    text: mailOptions.text,
    html: mailOptions.html
  });
  return client.sendMail(email);
}

/**
 * Test SMTP client connection
 */
export async function testClientConnection(
  host: string,
  port: number,
  timeout: number = 5000
): Promise<boolean> {
  const client = createTestSmtpClient({
    host,
    port,
    connectionTimeout: timeout
  });
  
  try {
    const result = await client.verify();
    return result;
  } catch (error) {
    throw error;
  } finally {
    if (client.close) {
      await client.close();
    }
  }
}

/**
 * Create authenticated SMTP client
 */
export function createAuthenticatedClient(
  host: string,
  port: number,
  username: string,
  password: string,
  authMethod: 'PLAIN' | 'LOGIN' = 'PLAIN'
): SmtpClient {
  return createTestSmtpClient({
    host,
    port,
    auth: {
      user: username,
      pass: password,
      method: authMethod
    },
    secure: false
  });
}

/**
 * Create TLS-enabled SMTP client
 */
export function createTlsClient(
  host: string,
  port: number,
  options: {
    secure?: boolean;
    rejectUnauthorized?: boolean;
  } = {}
): SmtpClient {
  return createTestSmtpClient({
    host,
    port,
    secure: options.secure || false,
    tls: {
      rejectUnauthorized: options.rejectUnauthorized || false
    }
  });
}

/**
 * Test client pool status
 */
export async function testClientPoolStatus(client: SmtpClient): Promise<any> {
  if (typeof client.getPoolStatus === 'function') {
    return client.getPoolStatus();
  }
  
  // Fallback for clients without pool status
  return {
    size: 1,
    available: 1,
    pending: 0,
    connecting: 0,
    active: 0
  };
}

/**
 * Send multiple emails concurrently
 */
export async function sendConcurrentEmails(
  client: SmtpClient,
  count: number,
  emailOptions: {
    from?: string;
    to?: string;
    subject?: string;
    text?: string;
  } = {}
): Promise<any[]> {
  const promises = [];
  
  for (let i = 0; i < count; i++) {
    promises.push(
      sendTestEmail(client, {
        ...emailOptions,
        subject: `${emailOptions.subject || 'Test Email'} ${i + 1}`
      })
    );
  }
  
  return Promise.all(promises);
}

/**
 * Measure client throughput
 */
export async function measureClientThroughput(
  client: SmtpClient,
  duration: number = 10000,
  emailOptions: {
    from?: string;
    to?: string;
    subject?: string;
    text?: string;
  } = {}
): Promise<{ totalSent: number; successCount: number; errorCount: number; throughput: number }> {
  const startTime = Date.now();
  let totalSent = 0;
  let successCount = 0;
  let errorCount = 0;
  
  while (Date.now() - startTime < duration) {
    try {
      await sendTestEmail(client, emailOptions);
      successCount++;
    } catch (error) {
      errorCount++;
    }
    totalSent++;
  }
  
  const actualDuration = (Date.now() - startTime) / 1000; // in seconds
  const throughput = totalSent / actualDuration;
  
  return {
    totalSent,
    successCount,
    errorCount,
    throughput
  };
}