import nodemailer from 'nodemailer';
import Imap from 'imap';
import { encryptCredentials, storeCredentialsInSession } from '~/server/utils/encryption';

export default defineEventHandler(async (event) => {
  const xTagHeader = getRequestHeader(event, "x-tag");

  if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) {
    throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
  }

  try {
    const body = await readBody(event);
    const { email, password, imapHost, smtpHost, sessionId } = body;

    console.log('[test-connection] Testing email connection for:', email);

    if (!email || !password || !sessionId) {
      throw createError({ 
        statusCode: 400, 
        statusMessage: "Email, password, and sessionId are required" 
      });
    }

    // Use provided hosts or defaults from environment
    const imapHostToUse = imapHost || process.env.NUXT_EMAIL_IMAP_HOST || 'mail.portnimara.com';
    const smtpHostToUse = smtpHost || process.env.NUXT_EMAIL_SMTP_HOST || 'mail.portnimara.com';
    const imapPort = parseInt(process.env.NUXT_EMAIL_IMAP_PORT || '993');
    const smtpPort = parseInt(process.env.NUXT_EMAIL_SMTP_PORT || '587');

    console.log('[test-connection] Using IMAP:', imapHostToUse, ':', imapPort);
    console.log('[test-connection] Using SMTP:', smtpHostToUse, ':', smtpPort);

    // Test SMTP connection
    console.log('[test-connection] Testing SMTP connection...');
    const transporter = nodemailer.createTransport({
      host: smtpHostToUse,
      port: smtpPort,
      secure: false, // false for STARTTLS
      auth: {
        user: email,
        pass: password
      },
      tls: {
        rejectUnauthorized: false // Allow self-signed certificates
      }
    });

    try {
      await transporter.verify();
      console.log('[test-connection] SMTP connection successful');
    } catch (smtpError: any) {
      console.error('[test-connection] SMTP connection failed:', smtpError);
      throw new Error(`SMTP connection failed: ${smtpError.message || smtpError}`);
    }
    
    // Test IMAP connection
    const imapConfig = {
      user: email,
      password: password,
      host: imapHostToUse,
      port: imapPort,
      tls: true,
      tlsOptions: { 
        rejectUnauthorized: false // Allow self-signed certificates
      }
    };

    const testImapConnection = () => {
      return new Promise((resolve, reject) => {
        console.log('[test-connection] Testing IMAP connection...');
        const imap = new Imap(imapConfig);
        
        // Add a timeout to prevent hanging
        const timeout = setTimeout(() => {
          console.error('[test-connection] IMAP connection timeout');
          imap.end();
          reject(new Error('IMAP connection timeout after 10 seconds'));
        }, 10000); // 10 second timeout
        
        imap.once('ready', () => {
          console.log('[test-connection] IMAP connection successful');
          clearTimeout(timeout);
          imap.end();
          resolve(true);
        });
        
        imap.once('error', (err: Error) => {
          console.error('[test-connection] IMAP connection error:', err);
          clearTimeout(timeout);
          reject(err);
        });
        
        imap.connect();
      });
    };

    try {
      await testImapConnection();
    } catch (imapError: any) {
      console.error('[test-connection] IMAP connection failed:', imapError);
      throw new Error(`IMAP connection failed: ${imapError.message || imapError}`);
    }

    // If both connections successful, encrypt and store credentials
    console.log('[test-connection] Both connections successful, storing credentials');
    const encryptedCredentials = encryptCredentials(email, password);
    storeCredentialsInSession(sessionId, encryptedCredentials);

    return { 
      success: true, 
      message: "Email connection tested successfully",
      email: email
    };
  } catch (error) {
    console.error('Email connection test failed:', error);
    if (error instanceof Error) {
      // Check for common authentication errors
      if (error.message.includes('Authentication') || error.message.includes('AUTHENTICATIONFAILED')) {
        throw createError({ 
          statusCode: 401, 
          statusMessage: "Invalid email or password" 
        });
      }
      throw createError({ 
        statusCode: 500, 
        statusMessage: `Connection failed: ${error.message}` 
      });
    } else {
      throw createError({
        statusCode: 500,
        statusMessage: "An unexpected error occurred",
      });
    }
  }
});
