// auto-split module


    async function tryLoad(urls) {
        for (const u of urls) {
            try {
                await loadScript(u);
            } catch (_) {}
            if (window.jspdf && window.jspdf.jsPDF) return true;
        }
        return !!(window.jspdf && window.jspdf.jsPDF);
    }


      function go(){
        try{ window.focus(); }catch(e){}
        setTimeout(function(){ window.print(); }, 120);
      }



        function applyRun(run) {
            template = {
                name: run.name || '',
                steps: (run.steps || []).map(s => {
                    const k = s.kind || s.type || 'step';
                    if (k === 'group') return {
                        kind: 'group',
                        title: s.title || ''
                    };
                    return {
                        kind: 'step',
                        id: s.id,
                        title: s.title,
                        expected: s.expected,
                        required: !!s.required,
                        status: s.status || '',
                        comment: s.comment || '',
                        evidence: s.evidence || ''
                    };
                })
            };
            if (els.tplName) els.tplName.textContent = run.name || '—';
            if (els.module) els.module.value = run.module || '';
            if (els.moduleVersion) els.moduleVersion.value = run.module_version || '';
            if (els.pbxVersion) els.pbxVersion.value = run.pbx_version || '';
            if (els.tester) els.tester.value = run.tester || '';
            if (els.docbeeUrl) els.docbeeUrl.value = run.docbee_url || '';
            renderSteps(template.steps);
            recomputeGroupStyles();
            if (els.statusTag) els.statusTag.textContent = 'Lauf geladen';
            updateAutosave();
        }



        function applyTemplateOnly(tplObj) {
            template = {
                name: tplObj.name || '',
                steps: (tplObj.steps || []).map(s => {
                    const k = s.kind || s.type || 'step';
                    if (k === 'group') return {
                        kind: 'group',
                        title: s.title || ''
                    };
                    return {
                        kind: 'step',
                        id: s.id || '',
                        title: s.title || '',
                        expected: s.expected || '',
                        required: !!s.required,
                        status: '',
                        comment: '',
                        evidence: ''
                    };
                })
            };
            if (els.tplName) els.tplName.textContent = template.name || '—';
            if (els.module) els.module.value = tplObj.module || '';
            if (els.moduleVersion) els.moduleVersion.value = tplObj.module_version || '';
            if (els.pbxVersion) els.pbxVersion.value = tplObj.pbx_version || '';
            renderSteps(template.steps);
            recomputeGroupStyles();
            if (els.statusTag) els.statusTag.textContent = 'Template geladen';
            updateAutosave();
        }


function collectTemplateFromDOM() {
    if (!template) return {
        name: '',
        module: '',
        module_version: '',
        pbx_version: '',
        olm_nummer: '',
        steps: []
    };
    captureEditsIntoTemplate();
    renumberSteps();
    return {
        name: template?.name || els.tplName?.textContent || '',
        module: els.module.value,
        module_version: els.moduleVersion.value,
        pbx_version: els.pbxVersion.value,
        olm_nummer: els.olmNummer ? els.olmNummer.value : '',
        steps: template.steps.map(s => {
            if ((s.kind || 'step') === 'group') return {
                type: 'group',
                title: s.title
            };
            return {
                type: 'step',
                id: s.id,
                title: s.title,
                expected: s.expected,
                required: !!s.required
            };
        })
    };
}


function collectRun() {
    if (!template) return null;
    captureEditsIntoTemplate();
    return {
        name: template?.name || '',
        module: els.module.value,
        module_version: els.moduleVersion.value,
        pbx_version: els.pbxVersion.value,
        olm_nummer: els.olmNummer ? els.olmNummer.value : '',
        tester: els.tester.value,
        docbee_url: els.docbeeUrl.value,
        ts: new Date().toISOString(),
        steps: [...template.steps]
    };
}



function appendResultLink(createdJSON) {
    let link = null;
    try {
        const j = JSON.parse(createdJSON || "{}");
        link = j?.link || null;
    } catch {}

    // Ticket-ID aus dem Eingabefeld (falls vorhanden) extrahieren
    const ticketId = extractTicketId(els.docbeeUrl?.value || '');

    // Ziel-URL bestimmen:
    // 1) Falls API bereits einen Pfad liefert (z. B. "ticket/show/123"), normieren.
    // 2) Sonst UI-Link über bekannte Struktur /ticket/show/%ID% bauen.
    let url = null;
    if (link) {
        if (/^https?:\/\//i.test(link)) {
            url = link; // bereits absolute URL
        } else {
            url = DOCBEE_UI_BASE.replace(/\/+$/, '') + '/' + String(link).replace(/^\/+/, '');
        }
    } else if (ticketId) {
        url = `${DOCBEE_UI_BASE.replace(/\/+$/,'')}/ticket/show/${ticketId}`;
    }
    if (!url) return;

    const hint = document.createElement('div');
    hint.className = 'docbee-hint';
    hint.innerHTML = `✅ Angelegt: <a href="${url}" target="_blank" rel="noopener">${url}</a>`;
    document.querySelector('.actions')?.appendChild(hint);
}


function formatDocBeeMessage(run) {
    const pad = (s, n) => (s || '').length > n ? (s || '').slice(0, n - 1) + '…' : (s || '').padEnd(n, ' ');
    const fmtDate = new Date(run.ts).toLocaleString('de-DE');

    // Kurz-Summary (nur echte Steps zählen)
    const counts = {
        pass: 0,
        fail: 0,
        skip: 0,
        blocked: 0
    };
    (run.steps || []).forEach(s => {
        const k = s.kind || s.type || 'step';
        if (k !== 'step') return;
        if (counts[s.status] !== undefined) counts[s.status]++;
    });
    const summary = `✅ ${counts.pass} | ❌ ${counts.fail} | ⏭️ ${counts.skip} | ⛔ ${counts.blocked}`;

    // Kopf + Metadaten (out VOR jeglicher Nutzung initialisieren)
    let out = '';
    out += `QA REPORT\n`;
    out += `===========\n`;
    out += `Modul:        ${run.module || ''}\n`;
    out += `Modul-Version:${run.module_version || ''}\n`;
    out += `PBX-Version:  ${run.pbx_version || ''}\n`;
    out += `Tester:       ${run.tester || ''}\n`;
    if (run.docbee_url) out += `Ticket:       ${run.docbee_url}\n`;
    out += `Datum:        ${fmtDate}\n\n`;
    out += `Übersicht:    ${summary}\n\n`;

    // Tabelle (monospace-geeignet)
    const SEP = '────────────────────────────────────────────────────────────────────────';
    out += `${SEP}\n`;
    out += `${pad('Schritt', 12)} ${pad('Status', 7)} ${pad('Titel', 52)}\n`;
    out += `${SEP}\n`;

    (run.steps || []).forEach(s => {
        const k = s.kind || s.type || 'step';
        if (k === 'group') {
            out += `\n## ${s.title || ''}\n\n`;
            return;
        }
        const st = (s.status || '').toUpperCase(); // PASS/FAIL/SKIP/BLOCKED/…
        const stShort = st === 'BLOCKED' ? 'BLOCK' : st;
        const SMAP = {
            pass: '✅',
            fail: '❌',
            skip: '⏭️',
            blocked: '⛔'
        };
        const stLabel = (SMAP[(s.status || '').toLowerCase()] ?
            SMAP[(s.status || '').toLowerCase()] + ' ' :
            '') + stShort;
        const req = s.required ? '📌 ' : '';
        out += `${pad(s.id || '', 12)} ${pad(stLabel, 9)} ${pad(req + (s.title || ''), 50)}\n`;
        if (s.comment) out += `  • Kommentar: ${s.comment}\n`;
        if (s.evidence) out += `  • Evidenz: ${s.evidence}\n`;
    });
    out += `${SEP}\n`;
    out += `Legende: PASS=✅, FAIL=❌, SKIP=⏭️, BLOCK=⛔\n`;
    return out;
}




async function postToDocBee() {
    const run = collectRun();
    if (!run) return;
    if (!checkRequired(run)) return;

    const ticketId = extractTicketId(els.docbeeUrl?.value || '');
    if (!ticketId) {
        alert("Keine Ticket-ID in der DocBee-URL gefunden.");
        return;
    }
    if (!hasToken()) {
        alert("Kein API-Token konfiguriert.");
        return;
    }

    // Kommentarinhalt (Markdown)
    const content = formatDocBeeMessage(run);

    // alten Vorgangs-Status holen (Vorgangs-Status = ticketStatus)
    const tGet = await getJSON(`${DOCBEE_BASEURL}/restApi/v1/ticket/${ticketId}?fields=ticketStatus`);
    const prevStatusId = tGet?.json?.ticketStatus ?? null;

    // Busy-State
    els.btnPushDocBee?.setAttribute('disabled', '');
    els.btnPushDocBee?.classList.add('is-busy');

    try {

        // *** Message posten (muss Message sein) ***
        const url = `${DOCBEE_BASEURL}/restApi/v1/ticket/${ticketId}/message`;
        const rMsg = await postJSON(url, {
            content: content,
            subject: `QA Report ${ticketId}`,
            internal: true,
            hidden: false
        });

        if (rMsg.ok) {
            // kurze Wartezeit, dann Status ggf. zurücksetzen (gegen Auto-"Antwort erhalten")
            await sleep(800);
            if (prevStatusId != null) {
                await restoreTicketStatus(ticketId, prevStatusId);
            }
            appendResultLink(rMsg.text);
            alert("Nachricht im Ticket angelegt (Status beibehalten).");
            return;
        }


        if (ENABLE_FALLBACK_NOTE) {
            const rNote = await postJSON(`${DOCBEE_BASEURL}/restApi/v1/note`, {
                note: {
                    ticket: {
                        id: Number(ticketId)
                    },
                    subject: `QA Report ${ticketId}`,
                    text: content,
                    internal: false
                }
            });
            if (rNote.ok) {
                appendResultLink(rNote.text);
                alert("Notiz angelegt (Fallback).");
                return;
            }
            alert(`Fehler: MSG ${rMsg.status}, NOTE ${rNote.status}`);
        } else {
            alert(`Nachricht fehlgeschlagen (Status ${rMsg.status}). Details siehe Konsole.`);
        }
    } catch (e) {
        alert("DocBee-Request fehlgeschlagen: " + String(e));
    } finally {
        els.btnPushDocBee?.removeAttribute('disabled');
        els.btnPushDocBee?.classList.remove('is-busy');
    }
}