import { tap, expect } from '@git.zone/tstest/tapbundle';
import { startTestServer, stopTestServer, type ITestServer } from '../../helpers/server.loader.js';
import { createSmtpClient } from '../../../ts/mail/delivery/smtpclient/index.js';
import { Email } from '../../../ts/mail/core/classes.email.js';

let testServer: ITestServer;

tap.test('setup test SMTP server', async () => {
  testServer = await startTestServer({
    port: 2578,
    tlsEnabled: false,
    authRequired: false
  });
  expect(testServer).toBeTruthy();
  expect(testServer.port).toEqual(2578);
});

tap.test('CEP-05: Basic Reply-To header', async () => {
  console.log('Testing basic Reply-To header');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with Reply-To header
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    replyTo: 'replies@example.com',
    subject: 'Reply-To Test',
    text: 'This email tests Reply-To header functionality'
  });

  const result = await smtpClient.sendMail(email);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();
  
  console.log('Successfully sent email with Reply-To header');

  await smtpClient.close();
});

tap.test('CEP-05: Multiple Reply-To addresses', async () => {
  console.log('Testing multiple Reply-To addresses');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with multiple Reply-To addresses
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    replyTo: ['reply1@example.com', 'reply2@example.com'],
    subject: 'Multiple Reply-To Test',
    text: 'This email tests multiple Reply-To addresses'
  });

  const result = await smtpClient.sendMail(email);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();
  
  console.log('Successfully sent email with multiple Reply-To addresses');

  await smtpClient.close();
});

tap.test('CEP-05: Reply-To with display names', async () => {
  console.log('Testing Reply-To with display names');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with Reply-To containing display names
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    replyTo: 'Support Team <support@example.com>',
    subject: 'Reply-To Display Name Test',
    text: 'This email tests Reply-To with display names'
  });

  const result = await smtpClient.sendMail(email);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();
  
  console.log('Successfully sent email with Reply-To display name');

  await smtpClient.close();
});

tap.test('CEP-05: Return-Path header', async () => {
  console.log('Testing Return-Path header');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with custom Return-Path
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'Return-Path Test',
    text: 'This email tests Return-Path functionality',
    headers: {
      'Return-Path': '<bounces@example.com>'
    }
  });

  const result = await smtpClient.sendMail(email);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();
  
  console.log('Successfully sent email with Return-Path header');

  await smtpClient.close();
});

tap.test('CEP-05: Different From and Return-Path', async () => {
  console.log('Testing different From and Return-Path addresses');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with different From and Return-Path
  const email = new Email({
    from: 'noreply@example.com',
    to: ['recipient@example.com'],
    subject: 'Different Return-Path Test',
    text: 'This email has different From and Return-Path addresses',
    headers: {
      'Return-Path': '<bounces+tracking@example.com>'
    }
  });

  const result = await smtpClient.sendMail(email);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();
  
  console.log('Successfully sent email with different From and Return-Path');

  await smtpClient.close();
});

tap.test('CEP-05: Reply-To and Return-Path together', async () => {
  console.log('Testing Reply-To and Return-Path together');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with both Reply-To and Return-Path
  const email = new Email({
    from: 'notifications@example.com',
    to: ['user@example.com'],
    replyTo: 'support@example.com',
    subject: 'Reply-To and Return-Path Test',
    text: 'This email tests both Reply-To and Return-Path headers',
    headers: {
      'Return-Path': '<bounces@example.com>'
    }
  });

  const result = await smtpClient.sendMail(email);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();
  
  console.log('Successfully sent email with both Reply-To and Return-Path');

  await smtpClient.close();
});

tap.test('CEP-05: International characters in Reply-To', async () => {
  console.log('Testing international characters in Reply-To');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with international characters in Reply-To
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    replyTo: 'Suppört Téam <support@example.com>',
    subject: 'International Reply-To Test',
    text: 'This email tests international characters in Reply-To'
  });

  const result = await smtpClient.sendMail(email);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();
  
  console.log('Successfully sent email with international Reply-To');

  await smtpClient.close();
});

tap.test('CEP-05: Empty and invalid Reply-To handling', async () => {
  console.log('Testing empty and invalid Reply-To handling');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Test with empty Reply-To (should work)
  const email1 = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'No Reply-To Test',
    text: 'This email has no Reply-To header'
  });

  const result1 = await smtpClient.sendMail(email1);
  expect(result1).toBeDefined();
  expect(result1.messageId).toBeDefined();
  
  console.log('Successfully sent email without Reply-To');

  // Test with empty string Reply-To
  const email2 = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    replyTo: '',
    subject: 'Empty Reply-To Test',
    text: 'This email has empty Reply-To'
  });

  const result2 = await smtpClient.sendMail(email2);
  expect(result2).toBeDefined();
  expect(result2.messageId).toBeDefined();
  
  console.log('Successfully sent email with empty Reply-To');

  await smtpClient.close();
});

tap.test('cleanup test SMTP server', async () => {
  if (testServer) {
    await stopTestServer(testServer);
  }
});

export default tap.start();