import nodemailer from 'nodemailer'; import path from 'path'; import { readFile } from 'fs/promises'; interface LocationSmtpConfig { host: string; port: number; user: string; password: string; secure: boolean; from: string; } function createTransporter(config: LocationSmtpConfig) { return nodemailer.createTransport({ host: config.host, port: config.port, secure: config.secure, auth: { user: config.user, pass: config.password, }, }); } interface SendEmailOptions { to: string; subject: string; text: string; html: string; smtpConfig: LocationSmtpConfig; attachments?: { filename: string; content?: Buffer; path?: string; }[]; } export async function sendEmail(options: SendEmailOptions) { const emailEnabled = process.env.EMAIL_ENABLED !== 'false'; const testMode = process.env.TEST_MODE === 'true'; const testRecipient = process.env.TEST_EMAIL_RECIPIENT; // E-Mail komplett deaktiviert if (!emailEnabled) { console.log('📧 [EMAIL DISABLED] E-Mail würde gesendet an:', options.to); console.log(' Betreff:', options.subject); console.log(' Von:', options.smtpConfig.from); console.log(' ⚠️ EMAIL_ENABLED=false - Kein echter Versand!'); return { success: true, messageId: 'test-disabled', mode: 'disabled' }; } // Test-Modus: Umleitung an Test-E-Mail let actualRecipient = options.to; if (testMode && testRecipient) { console.log('🧪 [TEST MODE] E-Mail umgeleitet!'); console.log(' Original-Empfänger:', options.to); console.log(' Test-Empfänger:', testRecipient); actualRecipient = testRecipient; // Füge Hinweis in Betreff ein options.subject = `[TEST] ${options.subject}`; // Füge Hinweis in E-Mail ein options.html = `

🧪 TEST-MODUS AKTIV

Diese E-Mail wäre ursprünglich an ${options.to} gegangen.

${options.html} `; } try { const transport = createTransporter(options.smtpConfig); const info = await transport.sendMail({ from: options.smtpConfig.from, to: actualRecipient, subject: options.subject, text: options.text, html: options.html, attachments: options.attachments, }); console.log('✅ Email sent:', info.messageId, 'from:', options.smtpConfig.from); if (testMode) { console.log(' 🧪 TEST MODE - E-Mail an:', actualRecipient, '(Original:', options.to, ')'); } return { success: true, messageId: info.messageId, mode: testMode ? 'test' : 'production' }; } catch (error: any) { console.error('❌ Email send error:', error); throw error; } } export async function sendContractEmail( booking: any, contractPdfPath: string ) { const location = booking.location; if (!location || !location.smtpHost || !location.smtpPassword) { throw new Error(`SMTP not configured for location: ${location?.name || 'Unknown'}`); } const smtpConfig: LocationSmtpConfig = { host: location.smtpHost, port: location.smtpPort || 465, user: location.smtpUser || location.contactEmail, password: location.smtpPassword, secure: location.smtpSecure !== false, from: `SaveTheMoment ${location.name} <${location.contactEmail}>`, }; const signToken = Buffer.from(`${booking.id}-${Date.now()}`).toString('base64url'); const signUrl = `${process.env.NEXTAUTH_URL}/contract/sign/${signToken}`; const subject = `Ihr Mietvertrag für ${booking.eventLocation || 'Ihr Event'}`; const html = `

🎉 SaveTheMoment ${location.name}

Ihr Mietvertrag ist bereit!

Hallo ${booking.customerName},

vielen Dank für Ihre Buchung bei SaveTheMoment ${location.name}! Wir freuen uns sehr, Teil Ihres besonderen Anlasses zu sein.

📋 Buchungsdetails

Buchungsnummer: ${booking.bookingNumber}

Event-Datum: ${new Date(booking.eventDate).toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' })}

Location: ${booking.eventLocation || booking.eventAddress}

Fotobox: ${booking.photobox?.model || 'N/A'}

Im Anhang finden Sie Ihren Mietvertrag als PDF-Datei.

Nächste Schritte:

  1. Bitte lesen Sie den Vertrag sorgfältig durch
  2. Signieren Sie den Vertrag online oder drucken Sie ihn aus und senden Sie ihn zurück
  3. Nach Erhalt der Unterschrift ist Ihre Buchung verbindlich bestätigt
✍️ Vertrag online signieren

Alternativ können Sie den Vertrag auch ausdrucken, unterschreiben und uns per E-Mail oder Post zurücksenden.

Bei Fragen stehen wir Ihnen jederzeit gerne zur Verfügung!

Mit freundlichen Grüßen
Ihr SaveTheMoment Team ${location.name}

`.trim(); const text = ` Hallo ${booking.customerName}, vielen Dank für Ihre Buchung bei SaveTheMoment ${location.name}! Buchungsdetails: - Buchungsnummer: ${booking.bookingNumber} - Event-Datum: ${new Date(booking.eventDate).toLocaleDateString('de-DE')} - Location: ${booking.eventLocation || booking.eventAddress} Im Anhang finden Sie Ihren Mietvertrag als PDF-Datei. Sie können den Vertrag online signieren unter: ${signUrl} Oder drucken Sie ihn aus und senden Sie ihn uns zurück. Bei Fragen stehen wir Ihnen jederzeit zur Verfügung! Mit freundlichen Grüßen Ihr SaveTheMoment Team ${location.name} --- SaveTheMoment ${location.name} E-Mail: ${location.contactEmail} Web: ${location.websiteUrl || 'www.savethemoment.photos'} `.trim(); let pdfBuffer: Buffer; try { pdfBuffer = await readFile(path.join(process.cwd(), 'public', contractPdfPath)); } catch (error) { console.error('Failed to read contract PDF:', error); throw new Error('Contract PDF not found'); } return sendEmail({ to: booking.customerEmail, subject, text, html, smtpConfig, attachments: [ { filename: `Mietvertrag_${booking.bookingNumber}.pdf`, content: pdfBuffer, }, ], }); } export async function sendInitialBookingEmail( booking: any, quotationPdf: Buffer, contractPdf: Buffer ) { const location = booking.location; if (!location || !location.smtpHost || !location.smtpPassword) { throw new Error(`SMTP not configured for location: ${location?.name || 'Unknown'}`); } const smtpConfig: LocationSmtpConfig = { host: location.smtpHost, port: location.smtpPort || 465, user: location.smtpUser || location.contactEmail, password: location.smtpPassword, secure: location.smtpSecure !== false, from: `SaveTheMoment ${location.name} <${location.contactEmail}>`, }; const signToken = Buffer.from(`${booking.id}-${Date.now()}`).toString('base64url'); const signUrl = `${process.env.NEXTAUTH_URL}/contract/sign/${signToken}`; const subject = `Ihre Anfrage bei SaveTheMoment ${location.name} - ${booking.bookingNumber}`; const html = `

🎉 SaveTheMoment ${location.name}

Vielen Dank für Ihre Anfrage!

Hallo ${booking.customerName},

herzlichen Dank für Ihre Anfrage! Wir freuen uns sehr, dass Sie sich für SaveTheMoment entschieden haben.

📋 Ihre Buchungsdetails

Buchungsnummer: ${booking.bookingNumber}

Event-Datum: ${new Date(booking.eventDate).toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' })}

Event-Location: ${booking.eventLocation || booking.eventAddress}

Fotobox: ${booking.photobox?.model || 'N/A'}

${booking.distance ? `

Entfernung: ${booking.distance.toFixed(1)} km (einfach)

` : ''}
${booking.calculatedPrice ? `

💰 Gesamtpreis

${booking.calculatedPrice.toFixed(2)} €

inkl. 19% MwSt.

` : ''}

📎 Im Anhang finden Sie:

  1. Ihr persönliches Angebot mit allen Details und Positionen
  2. Ihren Mietvertrag zum Durchlesen

✅ Nächste Schritte:

  1. Prüfen Sie bitte das Angebot und den Mietvertrag
  2. Signieren Sie den Vertrag online oder laden Sie ihn unterschrieben hoch
  3. Nach Ihrer Unterschrift wird Ihre Buchung verbindlich bestätigt
✍️ Vertrag jetzt online signieren

Alternativ können Sie den Vertrag auch ausdrucken, unterschreiben und uns per E-Mail zurücksenden.

Haben Sie Fragen oder Änderungswünsche?
Antworten Sie einfach auf diese E-Mail – wir sind für Sie da!

Mit freundlichen Grüßen
Ihr SaveTheMoment Team ${location.name}

`.trim(); const text = ` Hallo ${booking.customerName}, vielen Dank für Ihre Anfrage bei SaveTheMoment ${location.name}! Buchungsdetails: - Buchungsnummer: ${booking.bookingNumber} - Event-Datum: ${new Date(booking.eventDate).toLocaleDateString('de-DE')} - Location: ${booking.eventLocation || booking.eventAddress} - Fotobox: ${booking.photobox?.model || 'N/A'} ${booking.distance ? `- Entfernung: ${booking.distance.toFixed(1)} km` : ''} ${booking.calculatedPrice ? `\nGesamtpreis: ${booking.calculatedPrice.toFixed(2)} € (inkl. 19% MwSt.)` : ''} Im Anhang finden Sie: 1. Ihr persönliches Angebot 2. Ihren Mietvertrag Nächste Schritte: 1. Prüfen Sie bitte das Angebot und den Mietvertrag 2. Signieren Sie den Vertrag online: ${signUrl} 3. Nach Ihrer Unterschrift wird Ihre Buchung verbindlich bestätigt Bei Fragen stehen wir Ihnen jederzeit zur Verfügung! Mit freundlichen Grüßen Ihr SaveTheMoment Team ${location.name} --- SaveTheMoment ${location.name} E-Mail: ${location.contactEmail} Web: ${location.websiteUrl || 'www.savethemoment.photos'} `.trim(); return sendEmail({ to: booking.customerEmail, subject, text, html, smtpConfig, attachments: [ { filename: `Angebot_${booking.bookingNumber}.pdf`, content: quotationPdf, }, { filename: `Mietvertrag_${booking.bookingNumber}.pdf`, content: contractPdf, }, ], }); } export async function sendBookingConfirmationEmail(booking: any) { const location = booking.location; if (!location || !location.smtpHost || !location.smtpPassword) { throw new Error(`SMTP not configured for location: ${location?.name || 'Unknown'}`); } const smtpConfig: LocationSmtpConfig = { host: location.smtpHost, port: location.smtpPort || 465, user: location.smtpUser || location.contactEmail, password: location.smtpPassword, secure: location.smtpSecure !== false, from: `SaveTheMoment ${location.name} <${location.contactEmail}>`, }; const subject = `Buchungsbestätigung - ${booking.bookingNumber}`; const html = `

✅ Buchung bestätigt!

Hallo ${booking.customerName},

Ihre Buchung bei SaveTheMoment ${location.name} wurde erfolgreich bestätigt!

Buchungsdetails

Buchungsnummer: ${booking.bookingNumber}

Event-Datum: ${new Date(booking.eventDate).toLocaleDateString('de-DE')}

Location: ${booking.eventLocation || booking.eventAddress}

Wir freuen uns auf Ihr Event!

Mit freundlichen Grüßen
Ihr SaveTheMoment Team ${location.name}

`; const text = ` Hallo ${booking.customerName}, Ihre Buchung bei SaveTheMoment ${location.name} wurde erfolgreich bestätigt! Buchungsnummer: ${booking.bookingNumber} Event-Datum: ${new Date(booking.eventDate).toLocaleDateString('de-DE')} Location: ${booking.eventLocation || booking.eventAddress} Wir freuen uns auf Ihr Event! Mit freundlichen Grüßen Ihr SaveTheMoment Team ${location.name} `; return sendEmail({ to: booking.customerEmail, subject, text, html, smtpConfig, }); }