import nodemailer from 'nodemailer';
import { requireAuth } from '~/server/utils/auth';
import { getCredentialsFromSession, decryptCredentials } from '~/server/utils/encryption';
import { uploadFile, getMinioClient } from '~/server/utils/minio';
import { updateInterest } from '~/server/utils/nocodb';

export default defineEventHandler(async (event) => {
  // Check authentication (x-tag header OR Keycloak session)
  await requireAuth(event);

  console.log('[Email Send] Request authenticated');

  try {
    const body = await readBody(event);
    const { 
      to, 
      subject, 
      body: emailBody, 
      interestId, 
      sessionId, 
      includeSignature = true,
      signatureConfig,
      attachments = []
    } = body;

    console.log('[Email Send] Request body:', {
      to,
      subject,
      hasBody: !!emailBody,
      interestId,
      hasSessionId: !!sessionId,
      attachmentCount: attachments.length
    });

    if (!to || !subject || !emailBody || !sessionId) {
      console.error('[Email Send] Missing required fields:', {
        hasTo: !!to,
        hasSubject: !!subject,
        hasBody: !!emailBody,
        hasSessionId: !!sessionId
      });
      throw createError({ 
        statusCode: 400, 
        statusMessage: "To, subject, body, and sessionId are required" 
      });
    }

    // Get encrypted credentials from session
    console.log('[Email Send] Getting credentials for sessionId:', sessionId);
    const encryptedCredentials = getCredentialsFromSession(sessionId);
    if (!encryptedCredentials) {
      console.error('[Email Send] No credentials found for sessionId:', sessionId);
      throw createError({ 
        statusCode: 401, 
        statusMessage: "Email credentials not found. Please reconnect." 
      });
    }

    // Decrypt credentials
    console.log('[Email Send] Decrypting credentials');
    let email: string;
    let password: string;
    
    try {
      const decrypted = decryptCredentials(encryptedCredentials);
      email = decrypted.email;
      password = decrypted.password;
      console.log('[Email Send] Successfully decrypted credentials for:', email);
    } catch (decryptError) {
      console.error('[Email Send] Failed to decrypt credentials:', decryptError);
      throw createError({ 
        statusCode: 401, 
        statusMessage: "Failed to decrypt email credentials. Please reconnect." 
      });
    }

    // Get user info for signature
    const defaultName = email.split('@')[0].replace('.', ' ').replace(/\b\w/g, l => l.toUpperCase());
    
    // Build email signature with customizable fields
    const sig = signatureConfig || {};
    const contactLines = sig.contactInfo ? sig.contactInfo.split('\n').filter((line: string) => line.trim()).join('<br>') : '';
    const signature = includeSignature ? `
<br><br>
<div style="margin-top: 20px; font-family: Arial, sans-serif;">
  <img src="${process.env.NUXT_EMAIL_LOGO_URL || 'https://portnimara.com/Port_Nimara_Logo_2_Colour_New_Transparent.png'}" alt="Port Nimara" style="width: 150px; height: auto; max-height: 40px; margin-bottom: 10px; display: block;">
  <div style="font-weight: bold;">${sig.name || defaultName}</div>
  <div style="color: #666; margin-bottom: 8px;">${sig.title || 'Sales & Marketing Director'}</div>
  <div style="font-weight: bold; margin-bottom: 12px;">${sig.company || 'Port Nimara'}</div>
  ${contactLines ? contactLines + '<br>' : ''}
  <a href="mailto:${sig.email || email}" style="color: #0066cc;">${sig.email || email}</a>
  <br><br>
  <div style="color: #666; font-size: 12px; margin-top: 10px;">
    The information in this message is confidential and may be privileged.<br>
    It is intended for the addressee alone.<br>
    If you are not the intended recipient it is prohibited to disclose, use or copy this information.<br>
    Please contact the Sender immediately should this message have been transmitted incorrectly.
  </div>
</div>` : '';

    // Convert plain text body to HTML with line breaks
    const htmlBody = emailBody.replace(/\n/g, '<br>') + signature;

    // Configure SMTP transport
    const transporter = nodemailer.createTransport({
      host: process.env.NUXT_EMAIL_SMTP_HOST || 'mail.portnimara.com',
      port: parseInt(process.env.NUXT_EMAIL_SMTP_PORT || '587'),
      secure: false, // false for STARTTLS
      auth: {
        user: email,
        pass: password
      },
      tls: {
        rejectUnauthorized: false // Allow self-signed certificates
      }
    });

    // Prepare email attachments
    console.log('[Email Send] Processing', attachments.length, 'attachments');
    const emailAttachments = [];
    if (attachments && attachments.length > 0) {
      const client = getMinioClient();
      
      for (const attachment of attachments) {
        try {
          // Determine which bucket to use
          const bucket = attachment.bucket || 'client-portal'; // Default to client-portal
          console.log('[Email Send] Processing attachment:', attachment.name, 'from bucket:', bucket, 'path:', attachment.path);
          
          // Download file from MinIO
          const stream = await client.getObject(bucket, attachment.path);
          const chunks: Buffer[] = [];
          
          await new Promise((resolve, reject) => {
            stream.on('data', (chunk) => chunks.push(chunk));
            stream.on('end', resolve);
            stream.on('error', reject);
          });
          
          const content = Buffer.concat(chunks);
          console.log('[Email Send] Successfully downloaded attachment:', attachment.name, 'size:', content.length);
          
          emailAttachments.push({
            filename: attachment.name,
            content: content
          });
        } catch (error) {
          console.error(`[Email Send] Failed to attach file ${attachment.name} from bucket ${attachment.bucket}:`, error);
          // Continue with other attachments
        }
      }
    }

    // Send email
    const fromName = sig.name || defaultName;
    console.log('[Email Send] Sending email from:', email, 'to:', to);
    
    const info = await transporter.sendMail({
      from: `"${fromName}" <${email}>`,
      to: to,
      subject: subject,
      text: emailBody, // Plain text version
      html: htmlBody, // HTML version with signature
      attachments: emailAttachments
    });
    
    console.log('[Email Send] Email sent successfully, messageId:', info.messageId);

    // Store email in MinIO for thread history and update EOI Time Sent
    if (interestId) {
      try {
        const emailData = {
          id: info.messageId,
          from: email,
          to: to,
          subject: subject,
          body: emailBody,
          html: htmlBody,
          timestamp: new Date().toISOString(),
          direction: 'sent',
          interestId: interestId
        };

        const objectName = `interest-${interestId}/${Date.now()}-sent.json`;
        const buffer = Buffer.from(JSON.stringify(emailData, null, 2));
        
        // Upload to the client-emails bucket
        const { getMinioClient } = await import('~/server/utils/minio');
        const client = getMinioClient();
        await client.putObject('client-emails', objectName, buffer, buffer.length, {
          'Content-Type': 'application/json',
        });
        
        // Update EOI Time Sent if the email contains an EOI link
        if (emailBody.includes('signatures.portnimara.dev/sign/')) {
          try {
            await updateInterest(interestId, {
              'EOI Time Sent': new Date().toISOString()
            });
          } catch (updateError) {
            console.error('Failed to update EOI Time Sent:', updateError);
            // Continue even if update fails
          }
        }
      } catch (storageError) {
        console.error('Failed to store email in MinIO:', storageError);
        // Continue even if storage fails
      }
    }

    return { 
      success: true, 
      message: "Email sent successfully",
      messageId: info.messageId
    };
  } catch (error) {
    console.error('[Email Send] Failed to send email:', error);
    console.error('[Email Send] Error stack:', error instanceof Error ? error.stack : 'No stack trace');
    if (error instanceof Error) {
      throw createError({ 
        statusCode: 500, 
        statusMessage: `Failed to send email: ${error.message}` 
      });
    } else {
      throw createError({
        statusCode: 500,
        statusMessage: "An unexpected error occurred",
      });
    }
  }
});
