const nodemailer = require('nodemailer');
const Ticket = require('../models/Ticket');
const TicketComment = require('../models/TicketComment');
const ExternalAlert = require('../models/ExternalAlert');
const { parseNetgoAlert } = require('./netgoParser');
const { parseArcticWolfAlert } = require('./arcticWolfParser');
const AiService = require('./ai.service');
const User = require('../models/User');
const { getDatabase } = require('../config/database');
const { EmailTemplate } = require('../models/EmailTemplate');
const { EmailDesign } = require('../models/EmailDesign');

// ── SMTP Transporter ──────────────────────────────────────────────────────────

function createTransporter() {
    return nodemailer.createTransport({
        host: process.env.SMTP_HOST,
        port: parseInt(process.env.SMTP_PORT) || 587,
        secure: process.env.SMTP_SECURE === 'true',
        auth: {
            user: process.env.SMTP_USER,
            pass: process.env.SMTP_PASSWORD,
        },
        tls: { rejectUnauthorized: false },
    });
}

const BASE_URL = process.env.TICKET_BASE_URL || 'http://localhost';
const FROM = process.env.SMTP_FROM || process.env.SMTP_USER || 'IT Support';

function isEmailConfigured() {
    return !!(process.env.SMTP_HOST && process.env.SMTP_USER && process.env.SMTP_PASSWORD);
}

/**
 * Prüft ob der Empfänger (per E-Mail-Adresse) Benachrichtigungen aktiviert hat.
 * Externe Absender (kein User-Account) bekommen immer E-Mails.
 */
function hasNotificationsEnabled(email) {
    if (!email) return false;
    try {
        const user = User.getByEmail(email);
        if (!user) return true; // Kein Account = externer Nutzer → immer senden
        return !!user.email_notifications;
    } catch (_) {
        return true;
    }
}

/**
 * Prüft ob ein Staff-User eine bestimmte Notification-Art aktiviert hat.
 * @param {object} user - User-Objekt aus der DB
 * @param {'notif_ticket_created'|'notif_ticket_assigned'|'notif_new_comment'|'notif_weekly_report'} type
 */
function hasStaffNotif(user, type) {
    if (!user) return false;
    // Falls Spalte noch nicht existiert (alte DB): default einhalten
    if (user[type] === undefined || user[type] === null) {
        return type !== 'notif_ticket_created'; // ticket_created default=0, rest=1
    }
    return !!user[type];
}

async function sendMail(to, subject, html, attachments = []) {
    if (!isEmailConfigured()) {
        console.log(`[Email] SMTP not configured – skipping: ${subject}`);
        return;
    }
    try {
        const transporter = createTransporter();
        await transporter.sendMail({ from: FROM, to, subject, html, attachments });
        console.log(`[Email] Sent to ${to}: ${subject}`);
    } catch (err) {
        console.error(`[Email] Failed to send to ${to}:`, err.message);
    }
}

// ── Helpers ───────────────────────────────────────────────────────────────────

function ticketLink(ticket) {
    return `${BASE_URL}/tickets/${ticket.id}`;
}

const PRIORITY_MAP = {
    niedrig:  { label: 'Niedrig',  color: '#166534', bg: '#dcfce7', border: '#86efac' },
    mittel:   { label: 'Mittel',   color: '#1e40af', bg: '#dbeafe', border: '#93c5fd' },
    hoch:     { label: 'Hoch',     color: '#92400e', bg: '#fef3c7', border: '#fcd34d' },
    kritisch: { label: 'Kritisch', color: '#991b1b', bg: '#fee2e2', border: '#fca5a5' },
};

const STATUS_MAP = {
    offen:                  { label: 'Offen',                    color: '#92400e', bg: '#fef3c7' },
    in_bearbeitung:         { label: 'In Bearbeitung',           color: '#1e40af', bg: '#dbeafe' },
    warten_auf_mitarbeiter: { label: 'Warten auf Mitarbeiter',   color: '#6d28d9', bg: '#ede9fe' },
    warten_auf_support:     { label: 'Warten auf Support',       color: '#b45309', bg: '#fef3c7' },
    geschlossen:            { label: 'Geschlossen',              color: '#374151', bg: '#f3f4f6' },
};

function priorityBadge(p) {
    const m = PRIORITY_MAP[p] || { label: p, color: '#374151', bg: '#f3f4f6', border: '#d1d5db' };
    return `<span style="display:inline-block;padding:2px 10px;border-radius:12px;font-size:12px;font-weight:700;background-color:${m.bg};color:${m.color};border:1px solid ${m.border || m.bg};font-family:Inter,Helvetica,Arial,sans-serif;">${m.label}</span>`;
}

function statusBadge(s) {
    const m = STATUS_MAP[s] || { label: s, color: '#374151', bg: '#f3f4f6' };
    return `<span style="display:inline-block;padding:2px 10px;border-radius:12px;font-size:12px;font-weight:700;background-color:${m.bg};color:${m.color};font-family:Inter,Helvetica,Arial,sans-serif;">${m.label}</span>`;
}

// ── Info Card Helper ──────────────────────────────────────────────────────────
// Fluid width (100%) so it scales on mobile. Label col fixed at 120px.

function infoCard(rows) {
    const rowsHtml = rows.map(([label, value], i) => {
        const sep = i < rows.length - 1 ? 'border-bottom:1px solid #f3f4f6;' : '';
        return `
      <tr>
        <td width="115" style="width:115px;padding:12px 16px;font-size:10px;font-weight:700;color:#6b7280;font-family:Inter,Helvetica,Arial,sans-serif;white-space:nowrap;vertical-align:middle;text-transform:uppercase;letter-spacing:0.9px;${sep}">${label}</td>
        <td style="padding:12px 16px;font-size:13px;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;vertical-align:middle;${sep}">${value}</td>
      </tr>`;
    }).join('');

    return `<table width="100%" cellpadding="0" cellspacing="0" border="0"
      style="width:100%;background-color:#ffffff;border:1px solid #e5e7eb;border-radius:10px;overflow:hidden;margin:16px 0;">
      ${rowsHtml}
    </table>`;
}

// ── Base Template ─────────────────────────────────────────────────────────────
// Responsive: fluid card (max 600px), mobile-friendly via media queries.

function baseTemplate({ title, preheader, content, ticketNumber, showButton, buttonUrl, buttonText = 'Ticket öffnen', design = {}, darkMode = false }) {
    const d = {
        brand_name:    'CEREDA SYSTEMS',
        brand_subtitle:'IT Support',
        brand_icon:    '💻',
        logo_url:      '',
        primary_color: '#0d9488',
        button_color:  '#0d9488',
        bg_color:      '#f1f5f9',
        company_name:  'Cereda Systems GmbH',
        footer_text:   'Automatisch generiert von IT Nexus · Bitte nicht direkt antworten.',
        ...design,
    };

    // Dark mode structural colors
    const dm = darkMode ? {
        outerBg:     '#0f172a',
        cardBg:      '#1e293b',
        footerBg:    '#162032',
        headerBorder:'#334155',
        headingColor:'#f1f5f9',
        textColor:   '#cbd5e1',
        mutedColor:  '#64748b',
        shadow:      '0 2px 20px rgba(0,0,0,0.5)',
    } : {
        outerBg:     d.bg_color,
        cardBg:      '#ffffff',
        footerBg:    '#f9fafb',
        headerBorder: d.bg_color,
        headingColor:'#111827',
        textColor:   '#6b7280',
        mutedColor:  '#9ca3af',
        shadow:      '0 2px 16px rgba(0,0,0,0.08)',
    };

    // Split brand_name: first word dark, rest in primary color
    const nameParts = d.brand_name.trim().split(/\s+/);
    const nameFirst = escHtml(nameParts[0] || '');
    const nameRest  = escHtml(nameParts.slice(1).join(' '));
    const iconBg    = lightenColor(d.primary_color, 0.92);
    const badgeBg   = darkenColor(d.primary_color, 0.8);

    // Logo cell: image if logo_url set, otherwise emoji icon
    const logoCellHtml = d.logo_url
        ? `<td style="vertical-align:middle;padding-right:10px;">
                    <img src="${escHtml(d.logo_url)}" style="height:36px;max-width:150px;display:block;object-fit:contain;" alt="${nameFirst}">
                  </td>`
        : `<td bgcolor="${iconBg}" style="background-color:${iconBg};border-radius:8px;padding:7px 10px;line-height:1;vertical-align:middle;">
                    <span style="font-size:18px;line-height:1;">${d.brand_icon}</span>
                  </td>`;

    const darkModeCSS = darkMode ? `
  /* ── Dark mode overrides ── */
  body, .outer-bg { background-color: ${dm.outerBg} !important; }
  .card-wrap { background-color: ${dm.cardBg} !important; box-shadow: ${dm.shadow} !important; }
  .card-header, .card-body { background-color: ${dm.cardBg} !important; }
  .card-footer { background-color: ${dm.footerBg} !important; }
  td[bgcolor="#ffffff"] { background-color: ${dm.cardBg} !important; }
  td[bgcolor="#f9fafb"] { background-color: ${dm.footerBg} !important; }
  td[bgcolor="#f8fafc"] { background-color: #1a2744 !important; }
  td[style*="background-color:#ffffff"] { background-color: ${dm.cardBg} !important; }
  td[style*="background-color:#f8fafc"] { background-color: #1a2744 !important; }
  td[style*="background-color:#f9fafb"] { background-color: ${dm.footerBg} !important; }
  td[style*="background-color:#ecfdf5"] { background-color: #0d2a20 !important; }
  td[style*="background:#ecfdf5"]       { background-color: #0d2a20 !important; }
  table[style*="background:#fff8f8"]    { background: #2a1a1a !important; }
  table[style*="background-color:#ecfdf5"] { background-color: #0d2a20 !important; }
  h2[style*="color:#111827"] { color: ${dm.headingColor} !important; }
  p[style*="color:#6b7280"]  { color: ${dm.textColor} !important; }
  p[style*="color:#374151"]  { color: #d1d5db !important; }
  p[style*="color:#1f2937"]  { color: #d1d5db !important; }
  td[style*="color:#1f2937"] { color: #d1d5db !important; }
  p[style*="color:#047857"]  { color: #34d399 !important; }
  p[style*="color:#9ca3af"]  { color: ${dm.mutedColor} !important; }
  div[style*="color:#111827"] { color: ${dm.headingColor} !important; }
  div[style*="color:#9ca3af"] { color: ${dm.mutedColor} !important; }
  span[style*="color:#9ca3af"] { color: ${dm.mutedColor} !important; }
  table[style*="border:1px solid #e5e7eb"] { border-color: #334155 !important; }
  table[style*="background-color:#f8fafc"] { background-color: #1a2744 !important; }
  td[style*="border-bottom:1px solid #e5e7eb"] { border-color: #334155 !important; }
  td[style*="background:#f8fafc"] { background: #1a2744 !important; }
  ` : '';

    return `<!DOCTYPE html>
<html lang="de" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="${darkMode ? 'dark' : 'light only'}">
<meta name="supported-color-schemes" content="${darkMode ? 'dark' : 'light'}">
<title>${escHtml(title)}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<!--[if mso]><xml><o:OfficeDocumentSettings><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->
<style>
  /* Reset */
  body, table, td, p, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
  table, td { mso-table-lspace: 0; mso-table-rspace: 0; border-collapse: collapse; }
  img { border: 0; -ms-interpolation-mode: bicubic; }
  body { margin: 0; padding: 0; background-color: ${dm.outerBg}; }
  a { color: ${d.primary_color}; }

  ${darkMode ? '' : `/* Force light mode */
  :root { color-scheme: light only; }
  @media (prefers-color-scheme: dark) {
    body, .outer-bg { background-color: #e2e8f0 !important; }
    .card-body, .card-header, .card-footer { background-color: inherit !important; }
  }`}

  ${darkModeCSS}

  /* ── Responsive ── */
  @media screen and (max-width: 620px) {
    .card-wrap  { width: 100% !important; max-width: 100% !important; }
    .body-pad   { padding: 24px 16px !important; }
    .header-pad { padding: 16px 20px !important; }
    .footer-pad { padding: 12px 16px !important; }
    .header-brand { display: block !important; width: 100% !important; }
    .header-badge { display: block !important; width: 100% !important; text-align: left !important; padding-top: 0 !important; }
    .btn-wrap   { width: 100% !important; }
    .btn-link   { display: block !important; text-align: center !important; }
    .status-td  { padding: 12px 6px !important; }
    .ft-right   { display: none !important; }
  }
</style>
</head>
<body class="outer-bg" style="margin:0;padding:0;background-color:${dm.outerBg};font-family:Inter,Helvetica,Arial,sans-serif;">

<!-- Hidden preheader -->
<div style="display:none;max-height:0;overflow:hidden;mso-hide:all;font-size:1px;line-height:1px;color:${dm.outerBg};">${escHtml(preheader || title)}&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;</div>

<!-- Outer: fluid, centers the card -->
<table width="100%" cellpadding="0" cellspacing="0" border="0" bgcolor="${dm.outerBg}" style="background-color:${dm.outerBg};">
<tr><td align="center" style="padding:32px 12px;">

  <!--[if mso]><table width="600" cellpadding="0" cellspacing="0" border="0"><tr><td><![endif]-->

  <!-- Card: fluid up to 600px -->
  <table class="card-wrap" cellpadding="0" cellspacing="0" border="0"
    style="width:100%;max-width:600px;background-color:${dm.cardBg};border-radius:12px;overflow:hidden;box-shadow:${dm.shadow};">

    <!-- ── Top accent bar ── -->
    <tr>
      <td bgcolor="${d.primary_color}" style="background-color:${d.primary_color};height:4px;line-height:4px;font-size:4px;">&nbsp;</td>
    </tr>

    <!-- ── Header ── -->
    <tr>
      <td class="card-header" bgcolor="${dm.cardBg}" style="background-color:${dm.cardBg};padding:0;border-bottom:1px solid ${dm.headerBorder};">
        <table width="100%" cellpadding="0" cellspacing="0" border="0">
          <tr>
            <!-- Brand -->
            <td class="header-brand header-pad" style="padding:18px 28px;vertical-align:middle;">
              <table cellpadding="0" cellspacing="0" border="0">
                <tr>
                  ${logoCellHtml}
                  <td style="padding-left:10px;vertical-align:middle;">
                    <div style="font-size:16px;font-weight:800;color:${dm.headingColor};letter-spacing:-0.3px;line-height:1.15;font-family:Inter,Helvetica,Arial,sans-serif;">
                      ${nameFirst}${nameRest ? ` <span style="color:${d.primary_color};font-weight:700;">${nameRest}</span>` : ''}
                    </div>
                    <div style="font-size:10px;color:${dm.mutedColor};letter-spacing:1.5px;text-transform:uppercase;margin-top:3px;font-family:Inter,Helvetica,Arial,sans-serif;">
                      ${escHtml(d.brand_subtitle)}
                    </div>
                  </td>
                </tr>
              </table>
            </td>
            ${ticketNumber ? `
            <!-- Ticket badge -->
            <td class="header-badge header-pad" align="right" style="padding:18px 28px;vertical-align:middle;white-space:nowrap;">
              <table cellpadding="0" cellspacing="0" border="0" style="display:inline-table;">
                <tr>
                  <td bgcolor="${badgeBg}" style="background-color:${badgeBg};border-radius:8px;padding:7px 14px;text-align:center;">
                    <div style="font-size:9px;color:rgba(255,255,255,0.6);font-weight:700;letter-spacing:1.5px;text-transform:uppercase;font-family:Inter,Helvetica,Arial,sans-serif;">Ticket</div>
                    <div style="font-size:13px;font-weight:800;color:#ffffff;font-family:'Courier New',Courier,monospace;letter-spacing:1px;margin-top:2px;">${ticketNumber}</div>
                  </td>
                </tr>
              </table>
            </td>` : ''}
          </tr>
        </table>
      </td>
    </tr>

    <!-- ── Body ── -->
    <tr>
      <td class="card-body body-pad" bgcolor="${dm.cardBg}" style="background-color:${dm.cardBg};padding:28px 28px 24px 28px;">
        ${content}
        ${showButton && buttonUrl ? `
        <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;margin-top:28px;">
          <tr>
            <td bgcolor="${d.button_color}" align="center"
                style="background-color:${d.button_color};border-radius:10px;">
              <a class="btn-link" href="${buttonUrl}"
                 style="display:block;padding:17px 24px;color:#ffffff;text-decoration:none;font-weight:700;font-size:15px;letter-spacing:0.5px;font-family:Inter,Helvetica,Arial,sans-serif;text-align:center;line-height:1.4;">
                ${escHtml(buttonText)} &nbsp;&#8594;
              </a>
            </td>
          </tr>
        </table>` : ''}
      </td>
    </tr>

    <!-- ── Footer ── -->
    <tr>
      <td class="card-footer footer-pad" bgcolor="${dm.footerBg}" style="background-color:${dm.footerBg};padding:14px 28px;border-top:1px solid ${dm.headerBorder};border-radius:0 0 12px 12px;">
        <table width="100%" cellpadding="0" cellspacing="0" border="0">
          <tr>
            <td style="vertical-align:middle;">
              <p style="margin:0;font-size:11px;color:${dm.mutedColor};line-height:1.6;font-family:Inter,Helvetica,Arial,sans-serif;">
                ${escHtml(d.footer_text)}
              </p>
            </td>
            <td class="ft-right" align="right" style="vertical-align:middle;white-space:nowrap;">
              <p style="margin:0;font-size:11px;font-weight:600;color:${dm.mutedColor};font-family:Inter,Helvetica,Arial,sans-serif;">
                ${escHtml(d.company_name)}
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>

  </table><!-- /Card -->

  <!--[if mso]></td></tr></table><![endif]-->

</td></tr>
</table><!-- /Outer -->
</body>
</html>`;
}

// ── Template Helpers ──────────────────────────────────────────────────────────

function escHtml(s) {
    return String(s || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

/** Replaces {{var}} placeholders; HTML-escapes each value. */
function renderTemplate(str, vars) {
    return str.replace(/\{\{(\w+)\}\}/g, (_, key) => escHtml(vars[key] ?? ''));
}

/** Renders intro template: replaces vars + converts newlines to <br>. */
function renderIntro(str, vars) {
    return renderTemplate(escHtml(str), vars).replace(/\n/g, '<br>');
}

function getTpl(type) {
    try { return EmailTemplate.getByType(type); } catch (_) { return null; }
}

function lightenColor(hex, ratio = 0.92) {
    try {
        const n = parseInt(hex.replace('#', ''), 16);
        const r = Math.round(((n >> 16) & 0xFF) + (255 - ((n >> 16) & 0xFF)) * ratio);
        const g = Math.round(((n >> 8) & 0xFF) + (255 - ((n >> 8) & 0xFF)) * ratio);
        const b = Math.round((n & 0xFF) + (255 - (n & 0xFF)) * ratio);
        return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
    } catch (_) { return '#ecfdf5'; }
}

function darkenColor(hex, ratio = 0.8) {
    try {
        const n = parseInt(hex.replace('#', ''), 16);
        const r = Math.round(((n >> 16) & 0xFF) * ratio);
        const g = Math.round(((n >> 8) & 0xFF) * ratio);
        const b = Math.round((n & 0xFF) * ratio);
        return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
    } catch (_) { return '#0f766e'; }
}

// ── Outbound Notifications ────────────────────────────────────────────────────

async function sendTicketCreatedConfirmation(ticket) {
    if (!ticket.requester_email) return;
    if (!hasNotificationsEnabled(ticket.requester_email)) return;

    const tpl = getTpl('ticket_created');
    const vars = {
        ticket_number: ticket.ticket_number,
        ticket_title: ticket.title,
        requester_name: ticket.requester_name || '',
        category: ticket.category || '',
        priority: PRIORITY_MAP[ticket.priority]?.label || ticket.priority || '',
    };
    const introHtml = tpl
        ? renderIntro(tpl.intro, vars)
        : `Danke${ticket.requester_name ? `, <strong style="color:#111827;">${escHtml(ticket.requester_name)}</strong>` : ''}! Wir haben Ihre Anfrage erhalten und melden uns so schnell wie möglich.`;
    const subject = tpl
        ? renderTemplate(tpl.subject, vars)
        : `[${ticket.ticket_number}] Ticket erstellt: ${ticket.title}`;

    const content = `
      <h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">
        Ticket erstellt &#10003;
      </h2>
      <p style="margin:0 0 20px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">
        ${introHtml}
      </p>

      ${infoCard([
          ['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:#0d9488;font-size:13px;">${ticket.ticket_number}</strong>`],
          ['Betreff', `<strong style="color:#111827;">${ticket.title}</strong>`],
          ['Kategorie', `<span style="color:#374151;">${ticket.category}</span>`],
          ['Priorität', priorityBadge(ticket.priority)],
          ['Status', statusBadge(ticket.status)],
      ])}

      <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;background-color:#ecfdf5;border:1px solid #a7f3d0;border-radius:8px;margin-top:4px;">
        <tr>
          <td style="padding:13px 16px;">
            <p style="margin:0;font-size:13px;color:#047857;line-height:1.6;font-family:Inter,Helvetica,Arial,sans-serif;">
              <strong>Was passiert als Nächstes?</strong><br>
              Unser Support-Team prüft Ihre Anfrage und meldet sich bei Ihnen. Sie erhalten bei jeder Aktualisierung eine E-Mail.
            </p>
          </td>
        </tr>
      </table>`;

    await sendMail(
        ticket.requester_email,
        subject,
        baseTemplate({
            title: 'Ticket erstellt',
            preheader: `Ihr Ticket ${ticket.ticket_number} wurde erfolgreich erstellt.`,
            ticketNumber: ticket.ticket_number,
            content,
            showButton: false,
            design: EmailDesign.getDesign(),
        })
    );
}

async function sendTicketAssignedNotification(ticket, assignedUser) {
    if (!assignedUser?.email) return;
    if (!hasStaffNotif(assignedUser, 'notif_ticket_assigned')) return;

    const name = assignedUser.first_name || assignedUser.username;
    const tpl = getTpl('ticket_assigned');
    const vars = {
        ticket_number: ticket.ticket_number,
        ticket_title: ticket.title,
        assignee_name: name,
        requester_name: ticket.requester_name || '',
        requester_email: ticket.requester_email || '',
        category: ticket.category || '',
        priority: PRIORITY_MAP[ticket.priority]?.label || ticket.priority || '',
    };
    const introHtml = tpl
        ? renderIntro(tpl.intro, vars)
        : `Hallo <strong style="color:#111827;">${escHtml(name)}</strong>, dir wurde ein neues Ticket zugewiesen. Bitte bearbeite es zeitnah.`;
    const subject = tpl
        ? renderTemplate(tpl.subject, vars)
        : `[${ticket.ticket_number}] Ticket zugewiesen: ${ticket.title}`;

    const content = `
      <h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">
        Neues Ticket zugewiesen
      </h2>
      <p style="margin:0 0 20px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">
        ${introHtml}
      </p>

      ${infoCard([
          ['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:#0d9488;font-size:13px;">${ticket.ticket_number}</strong>`],
          ['Betreff', `<strong style="color:#111827;">${ticket.title}</strong>`],
          ['Kategorie', `<span style="color:#374151;">${ticket.category}</span>`],
          ['Priorität', priorityBadge(ticket.priority)],
          ['Von', `<span style="color:#374151;">${ticket.requester_name || 'Unbekannt'}${ticket.requester_email ? ` &lt;${ticket.requester_email}&gt;` : ''}</span>`],
      ])}`;

    await sendMail(
        assignedUser.email,
        subject,
        baseTemplate({
            title: 'Ticket zugewiesen',
            preheader: `Dir wurde Ticket ${ticket.ticket_number} zugewiesen.`,
            ticketNumber: ticket.ticket_number,
            content,
            showButton: true,
            buttonUrl: ticketLink(ticket),
            buttonText: 'Ticket öffnen',
            design: EmailDesign.getDesign(),
        })
    );
}

async function sendCommentNotification(ticket, comment) {
    if (!ticket.requester_email || comment.is_internal) return;
    if (!hasNotificationsEnabled(ticket.requester_email)) return;

    const authorName = comment.first_name
        ? `${comment.first_name} ${comment.last_name || ''}`.trim()
        : comment.username || 'Support-Team';

    const tpl = getTpl('comment_added');
    const vars = {
        ticket_number: ticket.ticket_number,
        ticket_title: ticket.title,
        author_name: authorName,
    };
    const introHtml = tpl
        ? renderIntro(tpl.intro, vars)
        : `Das Support-Team hat auf Ihr Ticket <strong style="color:#0d9488;">${ticket.ticket_number}</strong> geantwortet.`;
    const subject = tpl
        ? renderTemplate(tpl.subject, vars)
        : `[${ticket.ticket_number}] Neue Antwort: ${ticket.title}`;

    const content = `
      <h2 style="margin:0 0 6px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">
        Neue Antwort vom IT&#8209;Support
      </h2>
      <p style="margin:0 0 22px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">
        ${introHtml}
      </p>

      <!-- Comment card -->
      <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;border:1px solid #e5e7eb;border-radius:10px;overflow:hidden;margin-bottom:22px;">
        <!-- Author header -->
        <tr>
          <td bgcolor="#f8fafc" style="background-color:#f8fafc;padding:10px 16px;border-bottom:1px solid #e5e7eb;">
            <table cellpadding="0" cellspacing="0" border="0">
              <tr>
                <td bgcolor="#0d9488" style="background-color:#0d9488;border-radius:6px;width:28px;height:28px;text-align:center;vertical-align:middle;padding:0 8px;">
                  <span style="font-size:13px;font-weight:800;color:#ffffff;font-family:Inter,Helvetica,Arial,sans-serif;line-height:28px;">${authorName.charAt(0).toUpperCase()}</span>
                </td>
                <td style="padding-left:10px;vertical-align:middle;">
                  <span style="font-size:13px;font-weight:700;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">${authorName}</span>
                  <span style="font-size:11px;color:#9ca3af;font-family:Inter,Helvetica,Arial,sans-serif;padding-left:6px;">· IT Support</span>
                </td>
              </tr>
            </table>
          </td>
        </tr>
        <!-- Message body -->
        <tr>
          <td bgcolor="#ffffff" style="background-color:#ffffff;padding:16px;font-size:14px;color:#1f2937;line-height:1.75;white-space:pre-line;font-family:Inter,Helvetica,Arial,sans-serif;">
            ${comment.comment.replace(/</g, '&lt;').replace(/>/g, '&gt;')}
          </td>
        </tr>
      </table>

      ${infoCard([
          ['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:#0d9488;font-size:13px;">${ticket.ticket_number}</strong>`],
          ['Betreff', `<span style="color:#374151;">${ticket.title}</span>`],
          ['Status', statusBadge(ticket.status)],
      ])}`;

    await sendMail(
        ticket.requester_email,
        subject,
        baseTemplate({
            title: 'Neue Antwort',
            preheader: `Das Support-Team hat auf Ticket ${ticket.ticket_number} geantwortet.`,
            ticketNumber: ticket.ticket_number,
            content,
            showButton: true,
            buttonUrl: ticketLink(ticket),
            buttonText: 'Ticket anzeigen',
            design: EmailDesign.getDesign(),
        })
    );
}

/**
 * Benachrichtigt zugewiesene Staff-Mitglieder wenn der Requester eine neue Antwort schreibt.
 */
async function sendStaffCommentNotification(ticket, comment) {
    if (comment.is_internal) return;
    const assignees = ticket.assignees || [];
    for (const assignee of assignees) {
        if (!assignee.email) continue;
        const staffUser = User.getById(assignee.id || assignee.user_id);
        if (!staffUser) continue;
        if (!hasStaffNotif(staffUser, 'notif_new_comment')) continue;

        const requesterName = ticket.requester_name || ticket.requester_email || 'Mitarbeiter';
        const subject = `[${ticket.ticket_number}] Neue Antwort von ${requesterName}`;
        const content = `
      <h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">Neue Antwort im Ticket</h2>
      <p style="margin:0 0 20px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">
        <strong>${requesterName}</strong> hat auf Ticket <strong style="color:#0d9488;">${ticket.ticket_number}</strong> geantwortet.
      </p>
      <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;border:1px solid #e5e7eb;border-radius:10px;overflow:hidden;margin-bottom:22px;">
        <tr><td bgcolor="#f8fafc" style="background-color:#f8fafc;padding:10px 16px;border-bottom:1px solid #e5e7eb;">
          <span style="font-size:13px;font-weight:700;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">${requesterName}</span>
        </td></tr>
        <tr><td bgcolor="#ffffff" style="background-color:#ffffff;padding:16px;font-size:14px;color:#1f2937;line-height:1.75;white-space:pre-line;font-family:Inter,Helvetica,Arial,sans-serif;">
          ${comment.comment.replace(/</g, '&lt;').replace(/>/g, '&gt;')}
        </td></tr>
      </table>
      ${infoCard([
          ['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:#0d9488;font-size:13px;">${ticket.ticket_number}</strong>`],
          ['Betreff', `<span style="color:#374151;">${ticket.title}</span>`],
          ['Status', statusBadge(ticket.status)],
      ])}`;

        await sendMail(
            staffUser.email,
            subject,
            baseTemplate({
                title: 'Neue Antwort im Ticket',
                preheader: `${requesterName} hat auf Ticket ${ticket.ticket_number} geantwortet.`,
                ticketNumber: ticket.ticket_number,
                content,
                showButton: true,
                buttonUrl: ticketLink(ticket),
                buttonText: 'Ticket öffnen',
                design: EmailDesign.getDesign(),
            })
        );
    }
}

/**
 * Benachrichtigt alle Staff-Mitglieder mit notif_ticket_created=1 bei neuem Ticket.
 */
async function sendStaffTicketCreatedNotification(ticket) {
    const db = getDatabase();
    const staffUsers = db.prepare(`
        SELECT u.* FROM users u JOIN roles r ON u.role_id = r.id
        WHERE r.name IN ('super_admin','admin','support','bearbeiter')
          AND u.is_active = 1 AND u.email IS NOT NULL AND u.notif_ticket_created = 1
    `).all();

    for (const staffUser of staffUsers) {
        const subject = `[${ticket.ticket_number}] Neues Ticket: ${ticket.title}`;
        const content = `
      <h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">Neues Ticket eingegangen</h2>
      ${infoCard([
          ['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:#0d9488;font-size:13px;">${ticket.ticket_number}</strong>`],
          ['Betreff', `<strong style="color:#111827;">${ticket.title}</strong>`],
          ['Von', `<span style="color:#374151;">${ticket.requester_name || ''}${ticket.requester_email ? ` &lt;${ticket.requester_email}&gt;` : ''}</span>`],
          ['Kategorie', `<span style="color:#374151;">${ticket.category || '—'}</span>`],
          ['Priorität', priorityBadge(ticket.priority)],
      ])}`;

        await sendMail(
            staffUser.email,
            subject,
            baseTemplate({
                title: 'Neues Ticket',
                preheader: `Neues Ticket ${ticket.ticket_number}: ${ticket.title}`,
                ticketNumber: ticket.ticket_number,
                content,
                showButton: true,
                buttonUrl: ticketLink(ticket),
                buttonText: 'Ticket öffnen',
                design: EmailDesign.getDesign(),
            })
        );
    }
}

async function sendStatusChangeNotification(ticket, oldStatus, newStatus) {
    if (!ticket.requester_email || oldStatus === newStatus) return;
    if (!hasNotificationsEnabled(ticket.requester_email)) return;

    const oldS = STATUS_MAP[oldStatus] || { label: oldStatus };
    const newS = STATUS_MAP[newStatus] || { label: newStatus };
    const isSolved = newStatus === 'geschlossen';

    const tpl = getTpl('status_changed');
    const vars = {
        ticket_number: ticket.ticket_number,
        ticket_title: ticket.title,
        old_status: oldS.label,
        new_status: newS.label,
    };
    const introHtml = tpl
        ? renderIntro(tpl.intro, vars)
        : (isSolved
            ? `Ihr Ticket <strong style="color:#0d9488;">${ticket.ticket_number}</strong> wurde als <strong style="color:#111827;">gel&ouml;st</strong> markiert.`
            : `Der Status Ihres Tickets <strong style="color:#0d9488;">${ticket.ticket_number}</strong> hat sich ge&auml;ndert.`);
    const subject = tpl
        ? renderTemplate(tpl.subject, vars)
        : `[${ticket.ticket_number}] Status: ${newS.label} – ${ticket.title}`;

    // Status change visual: inline badges on one row — works on any screen width
    const statusChangeVisual = `
    <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;background-color:#f8fafc;border:1px solid #e5e7eb;border-radius:8px;margin:0 0 20px;">
      <tr>
        <td class="status-td" align="center" style="padding:18px 16px;">
          <div style="font-size:10px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;font-family:Inter,Helvetica,Arial,sans-serif;">Vorher</div>
          ${statusBadge(oldStatus)}
          <span style="display:inline-block;margin:0 12px;font-size:18px;color:#d1d5db;vertical-align:middle;line-height:1;">&#8594;</span>
          <div style="display:inline-block;vertical-align:middle;">
            <div style="font-size:10px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;font-family:Inter,Helvetica,Arial,sans-serif;">Jetzt</div>
            ${statusBadge(newStatus)}
          </div>
        </td>
      </tr>
    </table>`;

    const content = `
      <h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">
        ${isSolved ? 'Ticket gel&ouml;st &#10003;' : 'Status&auml;nderung'}
      </h2>
      <p style="margin:0 0 20px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">
        ${introHtml}
      </p>

      ${statusChangeVisual}

      ${infoCard([
          ['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:#0d9488;font-size:13px;">${ticket.ticket_number}</strong>`],
          ['Betreff', `<span style="color:#374151;">${ticket.title}</span>`],
          ['Priorität', priorityBadge(ticket.priority)],
      ])}

      ${isSolved ? `
      <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;background-color:#ecfdf5;border:1px solid #a7f3d0;border-radius:8px;margin-top:8px;">
        <tr>
          <td style="padding:13px 16px;">
            <p style="margin:0;font-size:13px;color:#047857;line-height:1.6;font-family:Inter,Helvetica,Arial,sans-serif;">
              Falls das Problem weiterhin besteht, antworten Sie einfach auf diese E-Mail oder er&ouml;ffnen Sie ein neues Ticket.
            </p>
          </td>
        </tr>
      </table>` : ''}`;

    await sendMail(
        ticket.requester_email,
        subject,
        baseTemplate({
            title: 'Statusänderung',
            preheader: `Status von Ticket ${ticket.ticket_number}: ${oldS.label} → ${newS.label}`,
            ticketNumber: ticket.ticket_number,
            content,
            showButton: true,
            buttonUrl: ticketLink(ticket),
            buttonText: 'Ticket anzeigen',
            design: EmailDesign.getDesign(),
        })
    );
}

// ── Bounce/Auto-Reply-Erkennung ───────────────────────────────────────────────

// Betreff-Muster die auf Bounce oder Auto-Reply hindeuten
const BOUNCE_SUBJECT_PATTERNS = [
    /^undeliverable:/i,
    /^unzustellbar:/i,
    /^delivery\s+(status\s+notification|failed|failure)/i,
    /^mail\s+delivery\s+(failed|subsystem)/i,
    /^failure\s+notice/i,
    /^non.?delivery/i,
    /^returned\s+mail/i,
    /^auto.?reply:/i,
    /^automatic\s+reply:/i,
    /^out\s+of\s+(office|the\s+office)/i,
    /^abwesenheit/i,
    /^abwesenheitsnotiz/i,
];

// From-Adressen die typischerweise Mailer-Daemons sind
const MAILER_DAEMON_PATTERNS = [
    /^mailer-daemon@/i,
    /^postmaster@/i,
    /^noreply@/i,
    /^no-reply@/i,
    /^do-not-reply@/i,
    /^donotreply@/i,
    /^mail-daemon@/i,
    /^bounce@/i,
    /^bounce\+/i,
];

function isBounceOrAutoReply(subject, fromAddress) {
    const subj = (subject || '').trim();
    const from = (fromAddress || '').toLowerCase();

    if (BOUNCE_SUBJECT_PATTERNS.some(p => p.test(subj))) {
        console.log(`[IMAP] Bounce/Auto-Reply erkannt (Betreff): ${subj}`);
        return true;
    }
    if (MAILER_DAEMON_PATTERNS.some(p => p.test(from))) {
        console.log(`[IMAP] Mailer-Daemon erkannt (From): ${from}`);
        return true;
    }
    return false;
}

// ── Inbound IMAP Polling (Fallback) ──────────────────────────────────────────

async function pollMailbox() {
    if (!process.env.IMAP_HOST || !process.env.IMAP_USER || !process.env.IMAP_PASSWORD) {
        return;
    }

    let client;
    try {
        const { ImapFlow } = require('imapflow');
        client = new ImapFlow({
            host: process.env.IMAP_HOST,
            port: parseInt(process.env.IMAP_PORT) || 993,
            secure: process.env.IMAP_PORT === '993' || process.env.IMAP_SECURE !== 'false',
            auth: { user: process.env.IMAP_USER, pass: process.env.IMAP_PASSWORD },
            logger: false,
            tls: { rejectUnauthorized: false },
        });

        await client.connect();
        const lock = await client.getMailboxLock(process.env.IMAP_MAILBOX || 'INBOX');
        try {
            const messages = await client.search({ seen: false });
            if (!messages || messages.length === 0) return;

            for (const uid of messages) {
                try {
                    const msg = await client.fetchOne(uid, { envelope: true, source: true });
                    if (!msg?.envelope) continue;

                    const messageId = msg.envelope.messageId;
                    const subject   = msg.envelope.subject || '';
                    const from      = msg.envelope.from?.[0] || {};
                    const fromAddr  = (from.address || '').toLowerCase();

                    // Bereits verarbeitet?
                    if (messageId && Ticket.getByEmailMessageId(messageId)) {
                        await client.messageFlagsAdd(uid, ['\\Seen']);
                        continue;
                    }

                    // Bounce / Auto-Reply → ignorieren, nur als gelesen markieren
                    if (isBounceOrAutoReply(subject, fromAddr)) {
                        await client.messageFlagsAdd(uid, ['\\Seen']);
                        continue;
                    }

                    // Reply auf bestehendes Ticket? → Ticketnummer aus Betreff lesen [TK-YYYY-NNNN]
                    const ticketRefMatch = subject.match(/\[?(TK-\d{4}-\d{4})\]?/i);
                    if (ticketRefMatch) {
                        const existing = Ticket.getByTicketNumber(ticketRefMatch[1].toUpperCase());
                        if (existing) {
                            const body = msg.source ? msg.source.toString('utf8').replace(/\r\n/g, '\n').split('\n\n').slice(1).join('\n\n').substring(0, 2000).trim() : '(E-Mail Antwort)';
                            TicketComment.create(existing.id, null, body || '(E-Mail Antwort)', false);
                            if (existing.status === 'geschlossen') {
                                Ticket.update(existing.id, { status: 'offen' });
                                console.log(`[IMAP] Ticket ${ticketRefMatch[1]} durch E-Mail-Antwort wieder geöffnet`);
                            }
                            await client.messageFlagsAdd(uid, ['\\Seen']);
                            continue;
                        }
                    }

                    // Check for Netgo monitoring email
                    const bodyText = msg.source ? msg.source.toString('utf8') : '';
                    const netgoAlert = parseNetgoAlert(fromAddr, subject, bodyText);
                    if (netgoAlert) {
                        if (!messageId || !ExternalAlert.getByEmailMessageId(messageId)) {
                            ExternalAlert.create({ ...netgoAlert, raw_body: bodyText.substring(0, 5000), email_message_id: messageId || null });
                            console.log(`[IMAP] Netgo Alert gespeichert: ${netgoAlert.device} – ${netgoAlert.severity}`);
                        }
                        await client.messageFlagsAdd(uid, ['\\Seen']);
                        continue;
                    }

                    // Check for Arctic Wolf security email
                    const awAlert = parseArcticWolfAlert(fromAddr, subject, bodyText);
                    if (awAlert) {
                        if (!messageId || !ExternalAlert.getByEmailMessageId(messageId)) {
                            ExternalAlert.create({ ...awAlert, raw_body: bodyText.substring(0, 5000), email_message_id: messageId || null });
                            console.log(`[IMAP] Arctic Wolf Alert gespeichert: ${awAlert.device} – ${awAlert.severity}`);
                        }
                        await client.messageFlagsAdd(uid, ['\\Seen']);
                        continue;
                    }

                    const ticket = Ticket.create({
                        title: subject.replace(/^(re:|fwd?:)\s*/i, '').trim() || 'E-Mail Anfrage',
                        description: '',
                        source: 'email',
                        requester_name: from.name || fromAddr || 'Unbekannt',
                        requester_email: fromAddr || null,
                        email_message_id: messageId || null,
                        priority: 'mittel',
                        category: 'Allgemein',
                    });

                    console.log(`[IMAP] Ticket created: ${ticket.ticket_number}`);

                    // AI-Analyse: Kategorie, Priorität und Lösungsvorschlag
                    try {
                        if (AiService.isConfigured()) {
                            const analysis = await AiService.analyzeTicket(ticket.title, ticket.description);
                            Ticket.update(ticket.id, {
                                category: analysis.category,
                                priority: analysis.priority,
                                ai_suggestion: analysis.suggestion,
                            });
                            console.log(`[IMAP] AI-Analyse für ${ticket.ticket_number}: ${analysis.category}/${analysis.priority}`);
                        }
                    } catch (aiErr) {
                        console.error('[IMAP] AI-Analyse fehlgeschlagen:', aiErr.message);
                    }

                    await sendTicketCreatedConfirmation(ticket);
                    await client.messageFlagsAdd(uid, ['\\Seen']);
                } catch (msgErr) {
                    console.error('[IMAP] Message error:', msgErr.message);
                }
            }
        } finally {
            lock.release();
        }
        await client.logout();
    } catch (err) {
        console.error('[IMAP] Poll error:', err.message);
        if (err.responseText) console.error('[IMAP] Server:', err.responseText);
        if (client) { try { await client.logout(); } catch (_) {} }
    }
}

// ── Zufriedenheits-Feedback ───────────────────────────────────────────────────

async function sendSatisfactionEmail(ticket) {
    if (!ticket.requester_email) return;
    if (!hasNotificationsEnabled(ticket.requester_email)) return;

    const goodLink  = `${BASE_URL}/api/tickets/${ticket.id}/feedback?rating=gut`;
    const badLink   = `${BASE_URL}/api/tickets/${ticket.id}/feedback?rating=schlecht`;
    const requester = ticket.requester_name || ticket.requester_email;

    const tpl = getTpl('satisfaction');
    const vars = {
        ticket_number: ticket.ticket_number,
        ticket_title: ticket.title,
        requester_name: requester,
    };
    const introHtml = tpl
        ? renderIntro(tpl.intro, vars)
        : `Hallo ${escHtml(requester)},<br><br>Ihr Ticket <strong>${ticket.ticket_number}</strong> – <em>${escHtml(ticket.title)}</em> – wurde soeben geschlossen.<br>War die Lösung hilfreich?`;
    const subject = tpl
        ? renderTemplate(tpl.subject, vars)
        : `War Ihr Problem gelöst? – Ticket ${ticket.ticket_number}`;

    const content = `
    <p style="margin:0 0 16px;color:#374151;font-size:15px;line-height:1.6;">
        ${introHtml}
    </p>
    <table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:24px 0;">
      <tr>
        <td align="center" style="padding:0 8px;">
          <a href="${goodLink}" style="display:inline-block;padding:14px 32px;background:#16a34a;color:#ffffff;text-decoration:none;border-radius:8px;font-weight:700;font-size:15px;">👍 Ja, Problem gelöst</a>
        </td>
        <td align="center" style="padding:0 8px;">
          <a href="${badLink}" style="display:inline-block;padding:14px 32px;background:#dc2626;color:#ffffff;text-decoration:none;border-radius:8px;font-weight:700;font-size:15px;">👎 Nein, Problem besteht</a>
        </td>
      </tr>
    </table>
    <p style="margin:16px 0 0;color:#9ca3af;font-size:12px;">
        Bei einem Klick auf "Nein" nehmen wir das Ticket erneut in Bearbeitung.
    </p>`;

    await sendMail(
        ticket.requester_email,
        subject,
        baseTemplate({
            title: 'Feedback erbeten',
            preheader: `Ticket ${ticket.ticket_number} wurde geschlossen – War die Lösung hilfreich?`,
            ticketNumber: ticket.ticket_number,
            content,
            showButton: false,
            design: EmailDesign.getDesign(),
        })
    );
}

// ── Eskalation ────────────────────────────────────────────────────────────────

async function sendEscalationEmail(ticket) {
    const db = getDatabase();
    const admins = db.prepare(`
        SELECT u.email FROM users u
        JOIN roles r ON u.role_id = r.id
        WHERE r.name IN ('super_admin','admin') AND u.email IS NOT NULL AND u.is_active = 1
    `).all();

    const prio = PRIORITY_MAP[ticket.priority] || { label: ticket.priority, color: '#991b1b', bg: '#fee2e2', border: '#fca5a5' };
    const age = Math.round((Date.now() - new Date(ticket.created_at + 'Z')) / 3600000);

    const tpl = getTpl('escalation');
    const vars = {
        ticket_number: ticket.ticket_number,
        ticket_title: ticket.title,
        priority: prio.label,
        requester_name: ticket.requester_name || ticket.requester_email || 'Unbekannt',
        age_hours: String(age),
    };
    const introHtml = tpl
        ? renderIntro(tpl.intro, vars)
        : `Ein Ticket mit hoher Priorität wartet seit <strong>${age} Stunden</strong> auf Bearbeitung und wurde noch nicht eskaliert.`;
    const escalationSubject = tpl
        ? renderTemplate(tpl.subject, vars)
        : `⚠️ ESKALATION: ${ticket.ticket_number} – ${prio.label} seit ${age}h offen`;

    const content = `
    <p style="margin:0 0 16px;color:#374151;font-size:15px;line-height:1.6;">
        ${introHtml}
    </p>
    <table width="100%" cellpadding="12" style="background:#fff8f8;border:1px solid #fca5a5;border-radius:8px;margin:0 0 16px;">
      <tr><td><strong>Ticket:</strong> ${ticket.ticket_number}</td></tr>
      <tr><td><strong>Titel:</strong> ${ticket.title}</td></tr>
      <tr><td><strong>Priorität:</strong> ${priorityBadge(ticket.priority)}</td></tr>
      <tr><td><strong>Ersteller:</strong> ${ticket.requester_name || ticket.requester_email || 'Unbekannt'}</td></tr>
      <tr><td><strong>Erstellt:</strong> ${new Date(ticket.created_at + 'Z').toLocaleString('de-DE')}</td></tr>
    </table>`;

    const escalationDesign = EmailDesign.getDesign();
    for (const admin of admins) {
        await sendMail(
            admin.email,
            escalationSubject,
            baseTemplate({
                title: '⚠️ Ticket Eskalation',
                preheader: `Ticket ${ticket.ticket_number} wurde nicht rechtzeitig bearbeitet`,
                ticketNumber: ticket.ticket_number,
                content,
                showButton: true,
                buttonUrl: ticketLink(ticket),
                buttonText: 'Ticket jetzt bearbeiten',
                design: escalationDesign,
            })
        );
    }
}

async function runEscalationCheck() {
    const db = getDatabase();
    const toEscalate = db.prepare(`
        SELECT * FROM tickets
        WHERE status = 'offen'
          AND escalated_at IS NULL
          AND (
            (priority = 'kritisch' AND created_at <= datetime('now', '-4 hours'))
            OR
            (priority = 'hoch' AND created_at <= datetime('now', '-24 hours'))
          )
    `).all();

    for (const ticket of toEscalate) {
        await sendEscalationEmail(ticket);
        db.prepare('UPDATE tickets SET escalated_at = CURRENT_TIMESTAMP WHERE id = ?').run(ticket.id);
        console.log(`[Escalation] Ticket ${ticket.ticket_number} eskaliert`);
    }
}

// ── Wöchentlicher Report ──────────────────────────────────────────────────────

async function sendWeeklyReport() {
    const db = getDatabase();

    const total   = db.prepare("SELECT COUNT(*) as c FROM tickets").get().c;
    const open    = db.prepare("SELECT COUNT(*) as c FROM tickets WHERE status NOT IN ('geschlossen')").get().c;
    const closed  = db.prepare("SELECT COUNT(*) as c FROM tickets WHERE status='geschlossen' AND closed_at >= datetime('now','-7 days')").get().c;
    const critical= db.prepare("SELECT COUNT(*) as c FROM tickets WHERE priority='kritisch' AND status NOT IN ('geschlossen')").get().c;
    const sla     = db.prepare(`SELECT COUNT(*) as c FROM tickets WHERE status NOT IN ('geschlossen') AND (
        (priority='kritisch' AND created_at <= datetime('now','-24 hours')) OR
        (priority='hoch'     AND created_at <= datetime('now','-48 hours')) OR
        (priority='mittel'   AND created_at <= datetime('now','-168 hours'))
    )`).get().c;
    const topAssignee = db.prepare(`
        SELECT u.first_name || ' ' || COALESCE(u.last_name,'') as name, COUNT(*) as c
        FROM tickets t JOIN users u ON t.assigned_to_user_id = u.id
        WHERE t.closed_at >= datetime('now','-7 days')
        GROUP BY t.assigned_to_user_id ORDER BY c DESC LIMIT 1
    `).get();
    const satisfGood = db.prepare("SELECT COUNT(*) as c FROM tickets WHERE satisfaction_rating='gut'").get().c;
    const satisfBad  = db.prepare("SELECT COUNT(*) as c FROM tickets WHERE satisfaction_rating='schlecht'").get().c;

    const content = `
    <p style="margin:0 0 20px;color:#374151;font-size:15px;">Guten Morgen! Hier ist Ihr wöchentlicher IT-Support Überblick:</p>
    <table width="100%" cellpadding="0" cellspacing="8" border="0" style="margin-bottom:20px;">
      <tr>
        <td style="width:50%;padding:12px;background:#f0f9ff;border-radius:8px;border:1px solid #bae6fd;text-align:center;">
          <div style="font-size:28px;font-weight:800;color:#0369a1;">${open}</div>
          <div style="font-size:12px;color:#0369a1;font-weight:600;">Offene Tickets</div>
        </td>
        <td style="width:50%;padding:12px;background:#f0fdf4;border-radius:8px;border:1px solid #bbf7d0;text-align:center;">
          <div style="font-size:28px;font-weight:800;color:#15803d;">${closed}</div>
          <div style="font-size:12px;color:#15803d;font-weight:600;">Diese Woche geschlossen</div>
        </td>
      </tr>
      <tr><td colspan="2" style="padding:4px;"></td></tr>
      <tr>
        <td style="padding:12px;background:${critical > 0 ? '#fff8f8' : '#f9fafb'};border-radius:8px;border:1px solid ${critical > 0 ? '#fca5a5' : '#e5e7eb'};text-align:center;">
          <div style="font-size:28px;font-weight:800;color:${critical > 0 ? '#dc2626' : '#374151'};">${critical}</div>
          <div style="font-size:12px;color:${critical > 0 ? '#dc2626' : '#6b7280'};font-weight:600;">Kritische Tickets offen</div>
        </td>
        <td style="padding:12px;background:${sla > 0 ? '#fffbeb' : '#f9fafb'};border-radius:8px;border:1px solid ${sla > 0 ? '#fcd34d' : '#e5e7eb'};text-align:center;">
          <div style="font-size:28px;font-weight:800;color:${sla > 0 ? '#d97706' : '#374151'};">${sla}</div>
          <div style="font-size:12px;color:${sla > 0 ? '#d97706' : '#6b7280'};font-weight:600;">SLA-Verletzungen</div>
        </td>
      </tr>
    </table>
    ${topAssignee ? `<p style="color:#374151;font-size:14px;">🏆 <strong>Beste(r) Bearbeiter diese Woche:</strong> ${topAssignee.name.trim()} (${topAssignee.c} Tickets geschlossen)</p>` : ''}
    ${(satisfGood + satisfBad) > 0 ? `<p style="color:#374151;font-size:14px;">😊 <strong>Zufriedenheit:</strong> ${satisfGood} positiv · ${satisfBad} negativ</p>` : ''}
    `;

    const recipients = db.prepare(`
        SELECT u.email FROM users u JOIN roles r ON u.role_id = r.id
        WHERE r.name IN ('super_admin','admin','support') AND u.email IS NOT NULL
          AND (u.notif_weekly_report = 1 OR (u.notif_weekly_report IS NULL AND u.email_notifications = 1)) AND u.is_active = 1
    `).all();

    const weekStr = new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
    for (const r of recipients) {
        await sendMail(
            r.email,
            `📊 Wöchentlicher IT-Report – KW ${weekStr}`,
            baseTemplate({ title: '📊 Wöchentlicher IT-Report', preheader: `${open} offene Tickets · ${closed} diese Woche geschlossen`, content, showButton: true, buttonUrl: BASE_URL + '/tickets', buttonText: 'Tickets öffnen' })
        );
    }
    console.log(`[Weekly] Report an ${recipients.length} Empfänger gesendet`);
}

// ── Preview Builder ───────────────────────────────────────────────────────────

function buildPreviewHtml(type, design = {}, darkMode = false) {
    const tpl = getTpl(type);
    const d = { ...EmailDesign.getDesign(), ...design };

    const sampleTicket = {
        ticket_number: 'TK-2026-0042',
        title: 'Microsoft 365 Login funktioniert nicht',
        category: 'Software',
        priority: 'hoch',
        status: 'in_bearbeitung',
        requester_name: 'Max Mustermann',
        requester_email: 'max.mustermann@firma.de',
        id: 42,
    };

    const opts = { design: d, darkMode };

    if (type === 'ticket_created') {
        const vars = { ticket_number: sampleTicket.ticket_number, ticket_title: sampleTicket.title, requester_name: sampleTicket.requester_name, category: sampleTicket.category, priority: 'Hoch' };
        const introHtml = tpl ? renderIntro(tpl.intro, vars) : `Danke, <strong style="color:#111827;">Max Mustermann</strong>! Wir haben Ihre Anfrage erhalten und melden uns so schnell wie möglich.`;
        const content = `<h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">Ticket erstellt &#10003;</h2>
          <p style="margin:0 0 20px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">${introHtml}</p>
          ${infoCard([['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:${d.primary_color};font-size:13px;">${sampleTicket.ticket_number}</strong>`], ['Betreff', `<strong>${sampleTicket.title}</strong>`], ['Kategorie', sampleTicket.category], ['Priorität', priorityBadge(sampleTicket.priority)], ['Status', statusBadge(sampleTicket.status)]])}
          <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;background-color:#ecfdf5;border:1px solid #a7f3d0;border-radius:8px;margin-top:4px;"><tr><td style="padding:13px 16px;"><p style="margin:0;font-size:13px;color:#047857;line-height:1.6;font-family:Inter,Helvetica,Arial,sans-serif;"><strong>Was passiert als Nächstes?</strong><br>Unser Support-Team prüft Ihre Anfrage und meldet sich bei Ihnen.</p></td></tr></table>`;
        return baseTemplate({ title: 'Ticket erstellt', preheader: 'Ihr Ticket wurde erstellt.', ticketNumber: sampleTicket.ticket_number, content, showButton: false, ...opts });
    }

    if (type === 'ticket_assigned') {
        const vars = { ticket_number: sampleTicket.ticket_number, ticket_title: sampleTicket.title, assignee_name: 'Anna Schmidt', requester_name: sampleTicket.requester_name, requester_email: sampleTicket.requester_email, category: sampleTicket.category, priority: 'Hoch' };
        const introHtml = tpl ? renderIntro(tpl.intro, vars) : `Hallo <strong style="color:#111827;">Anna Schmidt</strong>, dir wurde ein neues Ticket zugewiesen. Bitte bearbeite es zeitnah.`;
        const content = `<h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">Neues Ticket zugewiesen</h2>
          <p style="margin:0 0 20px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">${introHtml}</p>
          ${infoCard([['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:${d.primary_color};font-size:13px;">${sampleTicket.ticket_number}</strong>`], ['Betreff', `<strong>${sampleTicket.title}</strong>`], ['Kategorie', sampleTicket.category], ['Priorität', priorityBadge(sampleTicket.priority)], ['Von', `${sampleTicket.requester_name} &lt;${sampleTicket.requester_email}&gt;`]])}`;
        return baseTemplate({ title: 'Ticket zugewiesen', preheader: 'Dir wurde ein Ticket zugewiesen.', ticketNumber: sampleTicket.ticket_number, content, showButton: true, buttonUrl: '#', buttonText: 'Ticket öffnen', ...opts });
    }

    if (type === 'comment_added') {
        const vars = { ticket_number: sampleTicket.ticket_number, ticket_title: sampleTicket.title, author_name: 'Anna Schmidt' };
        const introHtml = tpl ? renderIntro(tpl.intro, vars) : `Das Support-Team hat auf Ihr Ticket <strong style="color:${d.primary_color};">${sampleTicket.ticket_number}</strong> geantwortet.`;
        const commentText = 'Hallo Max,\n\nwir haben das Problem identifiziert. Bitte setzen Sie Ihr Microsoft 365 Passwort über Ihr Benutzerportal zurück.\n\nBei Rückfragen stehen wir gerne zur Verfügung.\n\nMit freundlichen Grüßen\nIT-Support';
        const content = `<h2 style="margin:0 0 6px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">Neue Antwort vom IT&#8209;Support</h2>
          <p style="margin:0 0 22px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">${introHtml}</p>
          <table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;border:1px solid #e5e7eb;border-radius:10px;overflow:hidden;margin-bottom:22px;"><tr><td bgcolor="#f8fafc" style="background-color:#f8fafc;padding:10px 16px;border-bottom:1px solid #e5e7eb;"><table cellpadding="0" cellspacing="0" border="0"><tr><td bgcolor="${d.primary_color}" style="background-color:${d.primary_color};border-radius:6px;width:28px;height:28px;text-align:center;vertical-align:middle;padding:0 8px;"><span style="font-size:13px;font-weight:800;color:#ffffff;font-family:Inter,Helvetica,Arial,sans-serif;line-height:28px;">A</span></td><td style="padding-left:10px;vertical-align:middle;"><span style="font-size:13px;font-weight:700;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">Anna Schmidt</span><span style="font-size:11px;color:#9ca3af;font-family:Inter,Helvetica,Arial,sans-serif;padding-left:6px;">· IT Support</span></td></tr></table></td></tr><tr><td bgcolor="#ffffff" style="background-color:#ffffff;padding:16px;font-size:14px;color:#1f2937;line-height:1.75;white-space:pre-line;font-family:Inter,Helvetica,Arial,sans-serif;">${commentText.replace(/</g,'&lt;').replace(/>/g,'&gt;')}</td></tr></table>
          ${infoCard([['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:${d.primary_color};font-size:13px;">${sampleTicket.ticket_number}</strong>`], ['Betreff', sampleTicket.title], ['Status', statusBadge(sampleTicket.status)]])}`;
        return baseTemplate({ title: 'Neue Antwort', preheader: 'Das Support-Team hat geantwortet.', ticketNumber: sampleTicket.ticket_number, content, showButton: true, buttonUrl: '#', buttonText: 'Ticket anzeigen', ...opts });
    }

    if (type === 'status_changed') {
        const oldStatus = 'offen', newStatus = 'in_bearbeitung';
        const oldS = STATUS_MAP[oldStatus] || { label: oldStatus };
        const newS = STATUS_MAP[newStatus] || { label: newStatus };
        const vars = { ticket_number: sampleTicket.ticket_number, ticket_title: sampleTicket.title, old_status: oldS.label, new_status: newS.label };
        const introHtml = tpl ? renderIntro(tpl.intro, vars) : `Der Status Ihres Tickets <strong style="color:${d.primary_color};">${sampleTicket.ticket_number}</strong> hat sich geändert.`;
        const statusVis = `<table width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;background-color:#f8fafc;border:1px solid #e5e7eb;border-radius:8px;margin:0 0 20px;"><tr><td class="status-td" align="center" style="padding:18px 16px;"><div style="font-size:10px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;font-family:Inter,Helvetica,Arial,sans-serif;">Vorher</div>${statusBadge(oldStatus)}<span style="display:inline-block;margin:0 12px;font-size:18px;color:#d1d5db;vertical-align:middle;line-height:1;">&#8594;</span><div style="display:inline-block;vertical-align:middle;"><div style="font-size:10px;font-weight:700;color:#9ca3af;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;font-family:Inter,Helvetica,Arial,sans-serif;">Jetzt</div>${statusBadge(newStatus)}</div></td></tr></table>`;
        const content = `<h2 style="margin:0 0 8px;font-size:21px;font-weight:800;color:#111827;font-family:Inter,Helvetica,Arial,sans-serif;">Status&auml;nderung</h2>
          <p style="margin:0 0 20px;font-size:14px;color:#6b7280;line-height:1.7;font-family:Inter,Helvetica,Arial,sans-serif;">${introHtml}</p>
          ${statusVis}
          ${infoCard([['Ticket-Nr.', `<strong style="font-family:'Courier New',Courier,monospace;color:${d.primary_color};font-size:13px;">${sampleTicket.ticket_number}</strong>`], ['Betreff', sampleTicket.title], ['Priorität', priorityBadge(sampleTicket.priority)]])}`;
        return baseTemplate({ title: 'Statusänderung', preheader: 'Ihr Ticket-Status hat sich geändert.', ticketNumber: sampleTicket.ticket_number, content, showButton: true, buttonUrl: '#', buttonText: 'Ticket anzeigen', ...opts });
    }

    if (type === 'escalation') {
        const prio = PRIORITY_MAP[sampleTicket.priority] || { label: sampleTicket.priority };
        const vars = { ticket_number: sampleTicket.ticket_number, ticket_title: sampleTicket.title, priority: prio.label, requester_name: sampleTicket.requester_name, age_hours: '6' };
        const introHtml = tpl ? renderIntro(tpl.intro, vars) : `Ein Ticket mit hoher Priorität wartet seit <strong>6 Stunden</strong> auf Bearbeitung und wurde noch nicht bearbeitet.`;
        const content = `<p style="margin:0 0 16px;color:#374151;font-size:15px;line-height:1.6;">${introHtml}</p>
          <table width="100%" cellpadding="12" style="background:#fff8f8;border:1px solid #fca5a5;border-radius:8px;margin:0 0 16px;"><tr><td><strong>Ticket:</strong> ${sampleTicket.ticket_number}</td></tr><tr><td><strong>Titel:</strong> ${sampleTicket.title}</td></tr><tr><td><strong>Priorität:</strong> ${priorityBadge(sampleTicket.priority)}</td></tr><tr><td><strong>Ersteller:</strong> ${sampleTicket.requester_name}</td></tr></table>`;
        return baseTemplate({ title: '⚠️ Ticket Eskalation', preheader: 'Ein Ticket wurde eskaliert.', ticketNumber: sampleTicket.ticket_number, content, showButton: true, buttonUrl: '#', buttonText: 'Ticket jetzt bearbeiten', ...opts });
    }

    if (type === 'satisfaction') {
        const vars = { ticket_number: sampleTicket.ticket_number, ticket_title: sampleTicket.title, requester_name: sampleTicket.requester_name };
        const introHtml = tpl ? renderIntro(tpl.intro, vars) : `Hallo ${sampleTicket.requester_name},<br><br>Ihr Ticket <strong>${sampleTicket.ticket_number}</strong> – <em>${sampleTicket.title}</em> – wurde soeben geschlossen.<br>War die Lösung hilfreich?`;
        const content = `<p style="margin:0 0 16px;color:#374151;font-size:15px;line-height:1.6;">${introHtml}</p>
          <table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:24px 0;"><tr><td align="center" style="padding:0 8px;"><a href="#" style="display:inline-block;padding:14px 32px;background:#16a34a;color:#ffffff;text-decoration:none;border-radius:8px;font-weight:700;font-size:15px;">👍 Ja, Problem gelöst</a></td><td align="center" style="padding:0 8px;"><a href="#" style="display:inline-block;padding:14px 32px;background:#dc2626;color:#ffffff;text-decoration:none;border-radius:8px;font-weight:700;font-size:15px;">👎 Nein, Problem besteht</a></td></tr></table>`;
        return baseTemplate({ title: 'Feedback erbeten', preheader: 'War Ihr Problem gelöst?', ticketNumber: sampleTicket.ticket_number, content, showButton: false, ...opts });
    }

    return baseTemplate({ title: 'Vorschau', preheader: 'E-Mail Vorschau', content: '<p>Unbekannter E-Mail-Typ.</p>', showButton: false, ...opts });
}

// ── Onboarding Bestätigungsmail ───────────────────────────────────────────────

async function sendOnboardingConfirmationEmail(protocol, confirmToken) {
    const to = protocol.emp_private_email;
    if (!to) throw new Error('Keine private E-Mail-Adresse beim Mitarbeiter hinterlegt');

    const firstName  = protocol.emp_first_name || '';
    const lastName   = protocol.emp_last_name  || '';
    const fullName   = `${firstName} ${lastName}`.trim() || 'Mitarbeiter/in';
    const startDate  = protocol.start_date
        ? new Date(protocol.start_date).toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' })
        : '';
    const dept       = protocol.department || '';
    const confirmUrl = `${BASE_URL}/onboarding-confirm/${confirmToken}`;

    const html = `
<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"></head><body style="margin:0;padding:0;background:#f3f4f6;font-family:Arial,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f3f4f6;padding:32px 0;">
  <tr><td align="center">
    <table width="600" cellpadding="0" cellspacing="0" style="background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.08);">
      <tr><td style="background:#0ea5e9;padding:28px 36px;">
        <h1 style="margin:0;color:#fff;font-size:22px;font-weight:700;">Willkommen bei Cereda Systems!</h1>
        <p style="margin:6px 0 0;color:#bae6fd;font-size:14px;">Bitte bestätigen Sie Ihr Onboarding</p>
      </td></tr>
      <tr><td style="padding:32px 36px;">
        <p style="color:#374151;font-size:15px;line-height:1.6;">Guten Tag <strong>${fullName}</strong>,</p>
        <p style="color:#374151;font-size:15px;line-height:1.6;">
          Ihr Onboarding${dept ? ` in der Abteilung <strong>${dept}</strong>` : ''}${startDate ? ` (Arbeitsbeginn: <strong>${startDate}</strong>)` : ''} wurde durch unser Team abgeschlossen.
        </p>
        <p style="color:#374151;font-size:15px;line-height:1.6;">
          Bitte bestätigen Sie die Übergabe mit einem Klick auf den Button. Dies markiert Ihr Onboarding als vollständig abgeschlossen.
        </p>
        <table width="100%" cellpadding="0" cellspacing="0" style="margin:28px 0;">
          <tr><td align="center">
            <a href="${confirmUrl}" style="display:inline-block;padding:16px 40px;background:#16a34a;color:#ffffff;text-decoration:none;border-radius:8px;font-weight:700;font-size:16px;">
              ✅ Übergabe bestätigen
            </a>
          </td></tr>
        </table>
        <p style="color:#6b7280;font-size:13px;">
          Wenn der Button nicht funktioniert, kopieren Sie diesen Link in Ihren Browser:<br>
          <a href="${confirmUrl}" style="color:#0ea5e9;">${confirmUrl}</a>
        </p>
        <p style="color:#6b7280;font-size:13px;margin-top:24px;">
          Bei Fragen wenden Sie sich bitte an Ihre IT-Abteilung.<br>
          <em>Diese E-Mail wurde automatisch generiert.</em>
        </p>
      </td></tr>
      <tr><td style="background:#f9fafb;padding:16px 36px;border-top:1px solid #e5e7eb;">
        <p style="margin:0;color:#9ca3af;font-size:12px;">Cereda Systems GmbH · IT-Nexus Onboarding-System</p>
      </td></tr>
    </table>
  </td></tr>
</table>
</body></html>`;

    await sendMail(to, `Bitte bestätigen Sie Ihr Onboarding – ${fullName}`, html);
}

// ── Wartungs-Fälligkeits-Benachrichtigung ─────────────────────────────────────

async function sendMaintenanceDueNotifications() {
    if (!isEmailConfigured()) return;
    const db = getDatabase();
    const today = new Date().toISOString().split('T')[0];

    // Get assets due today
    const dueAssets = db.prepare(`
        SELECT a.*, u.username as assigned_username
        FROM assets a
        LEFT JOIN users u ON a.assigned_to_user_id = u.id
        WHERE a.next_maintenance_date = ? AND a.department IN ('Produktion', 'Techniker')
    `).all(today);

    if (dueAssets.length === 0) return;

    // Get all Produktion role users with email
    const recipients = db.prepare(`
        SELECT u.email, u.first_name, u.last_name
        FROM users u
        JOIN roles r ON u.role_id = r.id
        WHERE r.name = 'produktion' AND u.email IS NOT NULL AND u.email != '' AND u.is_active = 1
    `).all();

    if (recipients.length === 0) return;

    const transporter = createTransporter();
    const assetList = dueAssets.map(a => `• ${a.name} (${a.type}) – Bereich: ${a.department}`).join('\n');

    for (const recipient of recipients) {
        try {
            await transporter.sendMail({
                from: FROM,
                to: recipient.email,
                subject: `🔧 Wartung fällig heute: ${dueAssets.length} Asset(s)`,
                text: `Hallo ${recipient.first_name || ''},\n\nfolgende Assets haben heute eine fällige Wartung/Prüfung:\n\n${assetList}\n\nBitte die Prüfungen zeitnah durchführen und im IT Nexus dokumentieren.\n\nIT Nexus`,
                html: `<p>Hallo ${recipient.first_name || ''},</p><p>folgende Assets haben heute eine fällige Wartung/Prüfung:</p><ul>${dueAssets.map(a => `<li><strong>${a.name}</strong> (${a.type}) – Bereich: ${a.department}</li>`).join('')}</ul><p>Bitte die Prüfungen zeitnah durchführen und im IT Nexus dokumentieren.</p><p>IT Nexus</p>`,
            });
        } catch (e) {
            console.error('[Maintenance] Mail to', recipient.email, 'failed:', e.message);
        }
    }
    console.log(`[Maintenance] Sent due notifications to ${recipients.length} recipient(s) for ${dueAssets.length} asset(s)`);
}

module.exports = {
    sendTicketCreatedConfirmation,
    sendTicketAssignedNotification,
    sendCommentNotification,
    sendStaffCommentNotification,
    sendStaffTicketCreatedNotification,
    sendStatusChangeNotification,
    sendSatisfactionEmail,
    sendEscalationEmail,
    runEscalationCheck,
    sendWeeklyReport,
    pollMailbox,
    buildPreviewHtml,
    sendOnboardingConfirmationEmail,
    sendMaintenanceDueNotifications,
};
