import { requireAuth } from '~/server/utils/auth';
import { parseEmail, getIMAPConnection } from '~/server/utils/email-utils';
import { uploadFile } from '~/server/utils/minio';
import { getInterestByFieldAsync, updateInterest } from '~/server/utils/nocodb';
import type { ParsedMail } from 'mailparser';

interface ProcessedEOI {
  clientName: string;
  interestId?: string;
  fileName: string;
  processed: boolean;
  error?: string;
}

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

  try {
    console.log('[Process Sales EOIs] Starting email processing...');
    
    // Sales email credentials
    const credentials = {
      user: 'sales@portnimara.com',
      password: 'MDze7cSClQok8qWOf23X8Mb6lArdk0i42YnwJ1FskdtO2NCc9',
      host: 'mail.portnimara.com',
      port: 993,
      tls: true
    };

    const connection = await getIMAPConnection(credentials);
    const results: ProcessedEOI[] = [];

    try {
      // Open inbox
      await new Promise((resolve, reject) => {
        connection.openBox('INBOX', false, (err: any, box: any) => {
          if (err) reject(err);
          else resolve(box);
        });
      });

      // Search for unread emails with attachments
      const searchCriteria = ['UNSEEN'];
      
      const messages = await new Promise<number[]>((resolve, reject) => {
        connection.search(searchCriteria, (err: any, results: any) => {
          if (err) reject(err);
          else resolve(results || []);
        });
      });

      console.log(`[Process Sales EOIs] Found ${messages.length} unread messages`);

      for (const msgNum of messages) {
        try {
          const parsedEmail = await fetchAndParseEmail(connection, msgNum);
          
          if (parsedEmail.attachments && parsedEmail.attachments.length > 0) {
            // Process PDF attachments
            for (const attachment of parsedEmail.attachments) {
              if (attachment.contentType === 'application/pdf') {
                const result = await processEOIAttachment(
                  attachment,
                  parsedEmail.subject || '',
                  parsedEmail.from?.text || ''
                );
                results.push(result);
              }
            }
          }

          // Mark as read
          connection.addFlags(msgNum, '\\Seen', (err: any) => {
            if (err) console.error('Failed to mark message as read:', err);
          });
        } catch (error) {
          console.error(`[Process Sales EOIs] Error processing message ${msgNum}:`, error);
        }
      }

      connection.end();
    } catch (error) {
      connection.end();
      throw error;
    }

    return {
      success: true,
      processed: results.length,
      results
    };
  } catch (error: any) {
    console.error('[Process Sales EOIs] Failed to process emails:', error);
    throw createError({
      statusCode: 500,
      statusMessage: error.message || 'Failed to process sales emails',
    });
  }
});

async function fetchAndParseEmail(connection: any, msgNum: number): Promise<ParsedMail> {
  return new Promise((resolve, reject) => {
    const fetch = connection.fetch(msgNum, {
      bodies: '',
      struct: true
    });

    fetch.on('message', (msg: any) => {
      let buffer = '';
      
      msg.on('body', (stream: any) => {
        stream.on('data', (chunk: any) => {
          buffer += chunk.toString('utf8');
        });
        
        stream.once('end', async () => {
          try {
            const parsed = await parseEmail(buffer);
            resolve(parsed);
          } catch (err) {
            reject(err);
          }
        });
      });
    });

    fetch.once('error', reject);
  });
}

async function processEOIAttachment(
  attachment: any,
  subject: string,
  from: string
): Promise<ProcessedEOI> {
  const fileName = attachment.filename || 'unknown.pdf';
  
  try {
    console.log(`[Process Sales EOIs] Processing attachment: ${fileName}`);
    
    // Try to extract client name from filename or subject
    const clientName = extractClientName(fileName, subject);
    
    if (!clientName) {
      return {
        clientName: 'Unknown',
        fileName,
        processed: false,
        error: 'Could not identify client from filename or subject'
      };
    }

    // Find interest by client name
    const interest = await getInterestByFieldAsync('Full Name', clientName);
    
    if (!interest) {
      return {
        clientName,
        fileName,
        processed: false,
        error: `No interest found for client: ${clientName}`
      };
    }

    // Generate unique filename
    const timestamp = Date.now();
    const uploadFileName = `EOIs/${interest.Id}-${timestamp}-${fileName}`;
    
    // Upload to MinIO
    await uploadFile(uploadFileName, attachment.content, 'application/pdf');
    
    // Update interest with EOI document
    const documentData = {
      title: fileName,
      filename: uploadFileName,
      url: `/api/files/proxy-download?fileName=${encodeURIComponent(uploadFileName)}`,
      size: attachment.size,
      mimetype: 'application/pdf',
      icon: 'mdi-file-pdf-box',
      uploadedAt: new Date().toISOString(),
      source: 'email',
      from: from
    };

    // Get existing documents and add new one
    const existingDocs = interest['EOI Document'] || [];
    const updatedDocs = [...existingDocs, documentData];
    
    // Update interest
    await updateInterest(interest.Id.toString(), {
      'EOI Document': updatedDocs,
      'EOI Status': 'Signed',
      'Sales Process Level': 'Signed LOI and NDA'
    });

    console.log(`[Process Sales EOIs] Successfully processed EOI for ${clientName}`);
    
    return {
      clientName,
      interestId: interest.Id.toString(),
      fileName,
      processed: true
    };
  } catch (error: any) {
    console.error(`[Process Sales EOIs] Error processing attachment:`, error);
    return {
      clientName: 'Unknown',
      fileName,
      processed: false,
      error: error.message
    };
  }
}

function extractClientName(fileName: string, subject: string): string | null {
  // Try to extract from filename patterns like:
  // "John_Doe_EOI_signed.pdf"
  // "EOI_John_Doe.pdf"
  // "John Doe - EOI.pdf"
  
  // First try filename
  const filePatterns = [
    /^(.+?)[-_]EOI/i,
    /EOI[-_](.+?)\.pdf/i,
    /^(.+?)_signed/i,
    /^(.+?)\s*-\s*EOI/i
  ];

  for (const pattern of filePatterns) {
    const match = fileName.match(pattern);
    if (match && match[1]) {
      return match[1].replace(/[_-]/g, ' ').trim();
    }
  }

  // Then try subject
  const subjectPatterns = [
    /EOI\s+(?:for\s+)?(.+?)(?:\s+signed)?$/i,
    /Signed\s+EOI\s*[-:]?\s*(.+)$/i,
    /(.+?)\s*EOI\s*(?:signed|completed)/i
  ];

  for (const pattern of subjectPatterns) {
    const match = subject.match(pattern);
    if (match && match[1]) {
      return match[1].trim();
    }
  }

  return null;
}
