// ============================================
// NextJobs - Client-side JavaScript
// ============================================

// DOM Elements
const body = document.getElementById('body');

// Modal Elements
const applicationModal = document.getElementById('applicationModal');
const deleteModal = document.getElementById('deleteModal');
const pdfExportModal = document.getElementById('pdfExportModal');

// Form Elements
const applicationForm = document.getElementById('applicationForm');
const pdfExportForm = document.getElementById('pdfExportForm');

// Button Elements
const addApplicationBtn = document.getElementById('addApplicationBtn');
const exportPdfBtn = document.getElementById('exportPdfBtn');

// Close Modal Buttons
const closeApplicationModal = document.getElementById('closeApplicationModal');
const closeDeleteModal = document.getElementById('closeDeleteModal');
const closePdfModal = document.getElementById('closePdfModal');

const cancelApplication = document.getElementById('cancelApplication');
const cancelDelete = document.getElementById('cancelDelete');
const cancelPdfExport = document.getElementById('cancelPdfExport');
const confirmDelete = document.getElementById('confirmDelete');

// Global variables
let currentApplicationId = null;
let currentDeleteId = null;
let pdfLibrariesLoaded = false;

// ============================================
// Modal Functions
// ============================================

function showModal(modal) {
    modal.classList.remove('hidden');
    body.style.overflow = 'hidden';
}

function hideModal(modal) {
    modal.classList.add('hidden');
    body.style.overflow = '';
}

function resetApplicationForm() {
    applicationForm.reset();
    document.getElementById('modalTitle').textContent = 'Bewerbung hinzufügen';
    currentApplicationId = null;
}

// ============================================
// Application Management (CRUD)
// ============================================

function openAddApplicationModal() {
    resetApplicationForm();
    // Set default date to today
    const today = new Date().toISOString().split('T')[0];
    document.getElementById('applicationDatum').value = today;
    showModal(applicationModal);
}

function openEditApplicationModal(id) {
    // Fetch application data
    fetch(`/api/bewerbungen/${id}`)
        .then(response => response.json())
        .then(application => {
            currentApplicationId = application.id;
            document.getElementById('modalTitle').textContent = 'Bewerbung bearbeiten';
            document.getElementById('applicationId').value = application.id;
            document.getElementById('applicationDatum').value = application.datum;
            document.getElementById('applicationFirma').value = application.firma;
            document.getElementById('applicationStelle').value = application.stelle;
            document.getElementById('applicationArt').value = application.art || '';
            document.getElementById('applicationStatus').value = application.status || '';
            document.getElementById('applicationNotizen').value = application.notizen || '';
            showModal(applicationModal);
        })
        .catch(error => console.error('Error loading application:', error));
}

function saveApplication(event) {
    event.preventDefault();
    
    const formData = new FormData(applicationForm);
    const application = {
        datum: formData.get('datum'),
        firma: formData.get('firma'),
        stelle: formData.get('stelle'),
        art: formData.get('art'),
        status: formData.get('status'),
        notizen: formData.get('notizen'),
        interne_notizen: formData.get('interne_notizen'),
        kommentar: formData.get('kommentar'),
        labels: formData.getAll('labels')
    };
    
    let url = '/api/bewerbungen';
    let method = 'POST';

    if (currentApplicationId) {
        url = `/api/bewerbungen/${currentApplicationId}`;
        method = 'PUT';
    }

    const send = (payload) => fetch(url, {
        method: method,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
    });

    send(application)
        .then(async (response) => {
            // Duplicate guard: the server flags a likely double application (409).
            if (response.status === 409) {
                const info = await response.json().catch(() => ({}));
                if (info.duplicate) {
                    if (confirm(duplicateWarning(info.matches))) {
                        return send(Object.assign({}, application, { force: true })).then(r => r.json());
                    }
                    return null; // user cancelled — keep the form open
                }
            }
            return response.json();
        })
        .then(data => {
            if (data && data.success) {
                hideModal(applicationModal);
                resetApplicationForm();
                location.reload();
            }
        })
        .catch(error => console.error('Error saving application:', error));
}

// Human-readable warning listing the existing application(s) that look like the
// same job, shown before a possible double application is created.
function duplicateWarning(matches) {
    const lines = (matches || []).slice(0, 5).map(m => {
        const parts = [m.firma, m.stelle].filter(Boolean).join(' — ');
        const meta = [m.datum, m.status].filter(Boolean).join(', ');
        return '• ' + parts + (meta ? ' (' + meta + ')' : '');
    });
    return 'Es gibt bereits eine passende Bewerbung:\n\n' + lines.join('\n') +
        '\n\nTrotzdem eine weitere Bewerbung für diese Stelle anlegen?';
}

function openDeleteModal(id) {
    currentDeleteId = id;
    showModal(deleteModal);
}

function deleteApplication() {
    if (!currentDeleteId) return;
    
    fetch(`/api/bewerbungen/${currentDeleteId}`, {
        method: 'DELETE'
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            hideModal(deleteModal);
            currentDeleteId = null;
            // Refresh the page
            location.reload();
        }
    })
    .catch(error => console.error('Error deleting application:', error));
}

// ============================================
// PDF Export
// ============================================

function openPdfExportModal() {
    // Load PDF libraries if not already loaded
    loadPdfLibraries().then(() => {
        showModal(pdfExportModal);
    });
}

function generatePDF(event) {
    event.preventDefault();
    
    // The month option encodes its year ("YYYY-MM"), so a chosen month always
    // exports exactly that month of that year, regardless of the year select.
    const monthRaw = document.getElementById('pdfMonth').value;
    let year = document.getElementById('pdfYear').value;
    let month = '';
    if (monthRaw) {
        if (monthRaw.indexOf('-') !== -1) {
            const parts = monthRaw.split('-');
            year = parts[0];
            month = parts[1];
        } else {
            month = monthRaw;
        }
    }

    // Fetch data for PDF
    let url = '/api/export?';
    const params = [];
    if (month) params.push(`month=${month}`);
    if (year) params.push(`year=${year}`);

    if (params.length > 0) {
        url += params.join('&') + '&';
    }

    // loadPdfLibraries() is awaited here too (not only when the modal opens) so
    // the autotable plugin is guaranteed to be attached before we build the doc.
    // Without this, opening the modal and submitting before the plugin script
    // finished loading would reach generatePdfDocument() with doc.autoTable
    // still undefined ("doc.autoTable is not a function").
    Promise.all([
        loadPdfLibraries(),
        fetch('/api/settings').then(res => res.json()),
        fetch(url).then(res => res.json())
    ])
    .then(([_loaded, settings, applications]) => {
        // /api/export returns an array of applications; on a server error it
        // returns { error: '...' } instead. Guard so we surface a real message
        // rather than crashing inside generatePdfDocument with "applications.map
        // is not a function".
        if (!Array.isArray(applications)) {
            alert('Export fehlgeschlagen: ' + ((applications && applications.error) || 'Unbekannter Serverfehler'));
            return;
        }
        generatePdfDocument(settings, applications, month, year);
        hideModal(pdfExportModal);
    })
    .catch(error => {
        console.error('Error generating PDF:', error);
        alert('Export fehlgeschlagen. Bitte erneut versuchen.');
    });
}

// PDF Generation with jsPDF
function generatePdfDocument(settings, applications, month, year) {
    // The UMD build exposes the constructor as window.jspdf.jsPDF, not as a global jsPDF
    const jsPDF = window.jspdf && window.jspdf.jsPDF;
    if (typeof jsPDF === 'undefined') {
        console.error('jsPDF not loaded, please wait for libraries to load');
        alert('Bitte warten Sie einen Moment und versuchen Sie es erneut.');
        return;
    }

    const doc = new jsPDF({
        orientation: 'portrait',
        unit: 'mm',
        format: 'a4'
    });
    
    const monthNames = ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
                       'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
    
    const monthName = month ? monthNames[parseInt(month) - 1] : 'alle';

    // The status history is sorted ascending, so its last entry is the most recent
    // status change. The export keys date + status off that entry (falling back to
    // the application's own date/status when there is no history).
    const lastVerlauf = (app) => {
        const v = Array.isArray(app.verlauf) ? app.verlauf : [];
        return v.length ? v[v.length - 1] : null;
    };
    const lastStatusOf = (app) => {
        const lv = lastVerlauf(app);
        const s = (lv && lv.status) || app.status;
        return (s && s.trim()) ? s.trim() : 'Ohne Status';
    };
    const effDateOf = (app) => {
        const lv = lastVerlauf(app);
        return new Date(lv ? lv.datum : app.datum);
    };

    // Imported/scraped values can contain HTML entities (e.g. "GmbH &amp; Co. KG")
    // and sanitizeInput() stores "< > \" '" escaped — decode them so the PDF shows
    // real characters instead of the raw entity text.
    const decodeEntities = (str) => {
        if (str == null) return '';
        return String(str)
            .replace(/&#(\d+);/g, (_, n) => String.fromCharCode(parseInt(n, 10)))
            .replace(/&#x([0-9a-fA-F]+);/g, (_, n) => String.fromCharCode(parseInt(n, 16)))
            .replace(/&quot;/g, '"')
            .replace(/&apos;/g, "'")
            .replace(/&lt;/g, '<')
            .replace(/&gt;/g, '>')
            .replace(/&nbsp;/g, ' ')
            .replace(/&amp;/g, '&');
    };
    // Cleaned cell text with an em-dash fallback for missing/empty values.
    const cell = (v) => decodeEntities(v).trim() || '—';

    // Determine the year shown in the title. When no year was picked in the form,
    // derive it from the data so the title still reads e.g. "Juni 2026".
    const yearsInData = [...new Set(
        applications.map((a) => effDateOf(a).getFullYear()).filter((y) => !isNaN(y))
    )].sort((a, b) => a - b);
    const displayYear = year
        || (yearsInData.length === 1 ? String(yearsInData[0])
            : yearsInData.length > 1 ? `${yearsInData[0]}–${yearsInData[yearsInData.length - 1]}` : '');
    const period = month
        ? `${monthName}${displayYear ? ' ' + displayYear : ''}`
        : (displayYear || 'alle Zeiträume');
    const title = `Bewerbungsaktivitäten - ${period}`;
    const dateStr = new Date().toLocaleDateString('de-DE');
    
    // Page geometry
    const pageWidth = doc.internal.pageSize.getWidth();    // 210 mm
    const pageHeight = doc.internal.pageSize.getHeight();   // 297 mm
    const margin = 15;
    const contentWidth = pageWidth - margin * 2;            // 180 mm
    const bottomLimit = pageHeight - margin;

    let yPos = 20;

    // Start a new page if the next block would not fit
    function ensureSpace(needed) {
        if (yPos + needed > bottomLimit) {
            doc.addPage();
            yPos = margin;
        }
    }

    // Header with user data
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(16);
    doc.text(title, pageWidth / 2, yPos, { align: 'center' });
    yPos += 12;

    // User information. Values like the address can span multiple lines, so we
    // split them and advance yPos by the actual number of rendered lines –
    // otherwise the next field overlaps the wrapped text.
    doc.setFontSize(12);
    doc.setFont('helvetica', 'normal');
    const lineHeight = 7;
    function drawField(label, value) {
        if (!value) return;
        const lines = doc.splitTextToSize(`${label}: ${value}`, contentWidth);
        doc.text(lines, margin, yPos);
        yPos += lineHeight * lines.length;
    }
    if (settings) {
        drawField('Name', settings.name);
        drawField('Adresse', settings.adresse);
        drawField('Kundennummer', settings.kundennummer);
    }

    yPos += 6;

    // ---- Group entries by status (order kept in sync with views/index.ejs) ----
    const statusOrder = ['Entwurf', 'Gesendet', 'Eingangsbestätigung',
                         'In Bearbeitung', 'Interessiert', 'Telefonat', 'Warten auf Rückmeldung', 'Warten auf meine Antwort',
                         'Vorstellungsgespräch', 'Vertragsverhandlung', 'Einstellung', 'Absage', 'Absage von meiner Seite', 'Keine Rückmeldung'];
    // Accent colour per status (RGB) – reused by the chart and the list headings
    const statusColors = {
        'Entwurf': [168, 85, 247],
        'Gesendet': [59, 130, 246],
        'Eingangsbestätigung': [14, 165, 233],
        'In Bearbeitung': [20, 184, 166],
        'Interessiert': [236, 72, 153],
        'Telefonat': [244, 114, 182],
        'Warten auf Rückmeldung': [249, 115, 22],
        'Warten auf meine Antwort': [217, 70, 239],
        'Vorstellungsgespräch': [245, 158, 11],
        'Vertragsverhandlung': [132, 204, 22],
        'Einstellung': [34, 197, 94],
        'Absage': [239, 68, 68],
        'Absage von meiner Seite': [225, 29, 72],
        'Keine Rückmeldung': [107, 114, 128],
        'Ohne Status': [148, 163, 184]
    };
    const fallbackColor = [99, 102, 241];
    const colorFor = (s) => statusColors[s] || fallbackColor;

    const groups = {};
    applications.forEach((app) => {
        const key = lastStatusOf(app);
        (groups[key] = groups[key] || []).push(app);
    });
    const orderedKeys = [
        ...statusOrder.filter((s) => groups[s]),
        ...Object.keys(groups).filter((k) => !statusOrder.includes(k))
    ];

    const totalApplications = applications.length;
    const countOf = (s) => (groups[s] ? groups[s].length : 0);
    const pct = (n) => (totalApplications ? Math.round((n / totalApplications) * 100) : 0);

    // ============================================================
    // Statistics overview: KPI cards + distribution charts
    // ============================================================
    function sectionHeading(text) {
        ensureSpace(12);
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(12);
        doc.setTextColor(31, 41, 55);
        doc.text(text, margin, yPos);
        yPos += 2.5;
        doc.setDrawColor(209, 213, 219);
        doc.setLineWidth(0.4);
        doc.line(margin, yPos, margin + contentWidth, yPos);
        yPos += 6;
    }

    sectionHeading('Übersicht');

    // --- KPI cards ---
    const answered = totalApplications - countOf('Gesendet')
        - countOf('Keine Rückmeldung') - countOf('Ohne Status');
    const kpis = [
        { label: 'Bewerbungen', value: String(totalApplications), color: [55, 65, 81] },
        { label: 'Gespräche', value: String(countOf('Vorstellungsgespräch')), color: statusColors['Vorstellungsgespräch'] },
        { label: 'Einstellungen', value: String(countOf('Einstellung')), color: statusColors['Einstellung'] },
        { label: 'Absagen', value: String(countOf('Absage')), color: statusColors['Absage'] },
        { label: 'Antwortquote', value: pct(answered) + '%', color: [59, 130, 246] }
    ];
    const cardGap = 3.5;
    const cardW = (contentWidth - cardGap * (kpis.length - 1)) / kpis.length;
    const cardH = 22;
    ensureSpace(cardH + 4);
    const cardTop = yPos;
    kpis.forEach((kpi, i) => {
        const x = margin + i * (cardW + cardGap);
        doc.setFillColor(248, 250, 252);
        doc.roundedRect(x, cardTop, cardW, cardH, 2, 2, 'F');
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(19);
        doc.setTextColor(kpi.color[0], kpi.color[1], kpi.color[2]);
        doc.text(kpi.value, x + cardW / 2, cardTop + 11, { align: 'center' });
        doc.setFillColor(kpi.color[0], kpi.color[1], kpi.color[2]);
        doc.roundedRect(x + cardW / 2 - 5, cardTop + 13.5, 10, 1.1, 0.5, 0.5, 'F');
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(8);
        doc.setTextColor(107, 114, 128);
        doc.text(kpi.label, x + cardW / 2, cardTop + 18.5, { align: 'center' });
    });
    yPos = cardTop + cardH + 10;

    // --- Status distribution as a horizontal bar chart ---
    if (totalApplications > 0) {
        sectionHeading('Status-Verteilung');
        const maxCount = Math.max(...orderedKeys.map((k) => groups[k].length));
        const labelW = 46;
        const valueW = 24;
        const trackX = margin + labelW;
        const trackW = contentWidth - labelW - valueW;
        const rowH = 8;
        orderedKeys.forEach((key) => {
            const count = groups[key].length;
            ensureSpace(rowH);
            const barY = yPos + 1.4;
            const barH = 5;
            doc.setFont('helvetica', 'normal');
            doc.setFontSize(9);
            doc.setTextColor(55, 65, 81);
            doc.text(doc.splitTextToSize(key, labelW - 3)[0], margin, barY + barH - 1.2);
            doc.setFillColor(237, 240, 244);
            doc.roundedRect(trackX, barY, trackW, barH, 1, 1, 'F');
            const c = colorFor(key);
            const w = maxCount ? Math.max(1.5, (count / maxCount) * trackW) : 1.5;
            doc.setFillColor(c[0], c[1], c[2]);
            doc.roundedRect(trackX, barY, w, barH, 1, 1, 'F');
            doc.setFont('helvetica', 'bold');
            doc.setFontSize(8.5);
            doc.setTextColor(55, 65, 81);
            doc.text(`${count}  (${pct(count)}%)`, margin + contentWidth, barY + barH - 1.2, { align: 'right' });
            yPos += rowH;
        });
        yPos += 9;
    }

    // --- Application type (Art) as a single 100% stacked bar with legend ---
    const artCounts = {};
    applications.forEach((app) => {
        const k = (app.art && app.art.trim()) ? app.art.trim() : 'Sonstige';
        artCounts[k] = (artCounts[k] || 0) + 1;
    });
    const artKeys = Object.keys(artCounts);
    if (totalApplications > 0 && artKeys.length > 0) {
        const artPalette = [[37, 99, 235], [13, 148, 136], [217, 119, 6], [219, 39, 119],
                            [124, 58, 237], [5, 150, 105], [156, 163, 175]];
        ensureSpace(24);
        sectionHeading('Bewerbungsart');
        const barY = yPos;
        const barH = 7;
        let cum = 0;
        artKeys.forEach((key, i) => {
            const seg = (artCounts[key] / totalApplications) * contentWidth;
            const c = artPalette[i % artPalette.length];
            doc.setFillColor(c[0], c[1], c[2]);
            doc.rect(margin + cum, barY, seg, barH, 'F');
            cum += seg;
            if (i < artKeys.length - 1) {
                doc.setFillColor(255, 255, 255);
                doc.rect(margin + cum - 0.4, barY, 0.8, barH, 'F');
            }
        });
        yPos = barY + barH + 6;
        // Legend (wraps across rows when needed)
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(8.5);
        let lx = margin;
        artKeys.forEach((key, i) => {
            const c = artPalette[i % artPalette.length];
            const text = `${key} (${artCounts[key]})`;
            const itemW = 4.5 + doc.getTextWidth(text) + 7;
            if (lx + itemW > margin + contentWidth) { lx = margin; yPos += 5.5; }
            doc.setFillColor(c[0], c[1], c[2]);
            doc.roundedRect(lx, yPos - 2.6, 3, 3, 0.6, 0.6, 'F');
            doc.setTextColor(55, 65, 81);
            doc.text(text, lx + 4.5, yPos);
            lx += itemW;
        });
        yPos += 8;
    }

    // Declarative summary sentence for the official record
    ensureSpace(10);
    doc.setFont('helvetica', 'italic');
    doc.setFontSize(10.5);
    doc.setTextColor(75, 85, 99);
    const summaryText = (month || year)
        ? `Im Zeitraum ${period} habe ich mich auf ${totalApplications} Stellen beworben.`
        : `Insgesamt habe ich mich auf ${totalApplications} Stellen beworben.`;
    doc.text(summaryText, pageWidth / 2, yPos, { align: 'center' });
    doc.setTextColor(0, 0, 0);
    yPos += 12;

    // ---- Compact application table (one row per application) ----
    // Details such as Notizen and the full Status-Verlauf are intentionally left
    // out; every row shows only the last status and the date of that status change.
    sectionHeading('Bewerbungen');

    const tableRows = applications
        .map((app) => ({ app, date: effDateOf(app), status: lastStatusOf(app) }))
        .sort((a, b) => a.date - b.date);

    if (tableRows.length === 0) {
        doc.setFont('helvetica', 'italic');
        doc.setFontSize(10.5);
        doc.setTextColor(107, 114, 128);
        doc.text('Keine Bewerbungen im gewählten Zeitraum.', margin, yPos + 2);
        doc.setTextColor(0, 0, 0);
        yPos += 10;
    } else {
        doc.autoTable({
            startY: yPos,
            margin: { left: margin, right: margin },
            head: [['Datum', 'Firma', 'Stelle', 'Art', 'Status']],
            body: tableRows.map(({ app, date, status }) => ([
                isNaN(date) ? '—' : date.toLocaleDateString('de-DE'),
                cell(app.firma),
                cell(app.stelle),
                cell(app.art),
                status
            ])),
            // Never split a row across a page boundary — a split row leaves the
            // single-line cells (Datum, Art, Status) blank on the continuation page.
            rowPageBreak: 'avoid',
            styles: {
                font: 'helvetica', fontSize: 9, cellPadding: 2.4,
                textColor: [31, 41, 55], lineColor: [226, 232, 240],
                lineWidth: 0.2, valign: 'middle', overflow: 'linebreak'
            },
            headStyles: {
                fillColor: [55, 65, 81], textColor: [255, 255, 255],
                fontStyle: 'bold', fontSize: 9.5, cellPadding: 2.6
            },
            alternateRowStyles: { fillColor: [248, 250, 252] },
            columnStyles: {
                0: { cellWidth: 23 },
                1: { cellWidth: 41, fontStyle: 'bold' },
                2: { cellWidth: 'auto' },
                3: { cellWidth: 25 },
                4: { cellWidth: 39, halign: 'center', fontStyle: 'bold' }
            },
            // Tint the Status cell in its status colour so the column reads like a badge
            didParseCell: (data) => {
                if (data.section === 'body' && data.column.index === 4) {
                    const c = colorFor(String(data.cell.raw));
                    data.cell.styles.textColor = c;
                    data.cell.styles.fillColor = [
                        Math.round(c[0] * 0.13 + 255 * 0.87),
                        Math.round(c[1] * 0.13 + 255 * 0.87),
                        Math.round(c[2] * 0.13 + 255 * 0.87)
                    ];
                }
            }
        });
        yPos = doc.lastAutoTable.finalY + 10;
    }

    // Footer with confirmation
    ensureSpace(20);
    yPos += 6;
    doc.setFont('helvetica', 'italic');
    doc.setFontSize(10);
    doc.setTextColor(0, 0, 0);
    doc.text('Ich versichere, dass die oben genannten Angaben der Wahrheit entsprechen.', pageWidth / 2, yPos, { align: 'center' });
    yPos += 7;
    doc.text(`Datum: ${dateStr}`, pageWidth / 2, yPos, { align: 'center' });
    
    // Save the PDF
    const fileName = `Bewerbungsaktivitaeten_${monthName}_${year || 'alle'}.pdf`;
    doc.save(fileName);
}

// Load PDF libraries dynamically
function loadPdfLibraries() {
    return new Promise((resolve) => {
        if (pdfLibrariesLoaded) {
            resolve();
            return;
        }
        
        // Check if already loading
        if (document.getElementById('jspdf-script')) {
            const checkLoaded = setInterval(() => {
                // Wait for the autotable plugin too, not just jsPDF: jsPDF loads
                // first (script1), the plugin second (script2). Resolving the
                // moment jsPDF exists leaves doc.autoTable undefined if script2
                // has not run yet.
                if (window.jspdf && window.jspdf.jsPDF
                    && typeof window.jspdf.jsPDF.API.autoTable === 'function') {
                    clearInterval(checkLoaded);
                    pdfLibrariesLoaded = true;
                    resolve();
                }
            }, 100);
            return;
        }
        
        // Load jsPDF from the app's own /vendor (self-hosted) so no external
        // script source has to be trusted in the Content-Security-Policy.
        const script1 = document.createElement('script');
        script1.id = 'jspdf-script';
        script1.src = '/vendor/jspdf.umd.min.js';
        script1.onload = () => {
            const script2 = document.createElement('script');
            script2.src = '/vendor/jspdf.plugin.autotable.min.js';
            script2.onload = () => {
                pdfLibrariesLoaded = true;
                resolve();
            };
            document.head.appendChild(script2);
        };
        document.head.appendChild(script1);
    });
}

// ============================================
// Event Listeners
// ============================================

// Application Modal
addApplicationBtn.addEventListener('click', openAddApplicationModal);
closeApplicationModal.addEventListener('click', () => {
    hideModal(applicationModal);
    resetApplicationForm();
});
cancelApplication.addEventListener('click', () => {
    hideModal(applicationModal);
    resetApplicationForm();
});
applicationForm.addEventListener('submit', saveApplication);

// Delete Modal
closeDeleteModal.addEventListener('click', () => hideModal(deleteModal));
cancelDelete.addEventListener('click', () => hideModal(deleteModal));
confirmDelete.addEventListener('click', deleteApplication);

// PDF Export Modal
exportPdfBtn.addEventListener('click', openPdfExportModal);
closePdfModal.addEventListener('click', () => hideModal(pdfExportModal));
cancelPdfExport.addEventListener('click', () => hideModal(pdfExportModal));
pdfExportForm.addEventListener('submit', generatePDF);

// Delete buttons (event delegation). Editing opens its own page (/bewerbung/:id).
document.addEventListener('click', (e) => {
    if (e.target.closest('.delete-btn')) {
        const id = e.target.closest('.delete-btn').dataset.id;
        openDeleteModal(id);
    }
});

// Close modals when clicking outside
document.addEventListener('click', (e) => {
    if (e.target === applicationModal) {
        hideModal(applicationModal);
        resetApplicationForm();
    }
    if (e.target === deleteModal) hideModal(deleteModal);
    if (e.target === pdfExportModal) hideModal(pdfExportModal);
});

// Close modals with Escape key
document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') {
        if (!applicationModal.classList.contains('hidden')) {
            hideModal(applicationModal);
            resetApplicationForm();
        }
        if (!deleteModal.classList.contains('hidden')) hideModal(deleteModal);
        if (!pdfExportModal.classList.contains('hidden')) hideModal(pdfExportModal);
    }
});

// Set current year in footer
document.getElementById('currentYear').textContent = new Date().getFullYear();

// ============================================
// Initialize
// ============================================

console.log('NextJobs initialized');
