// ===================== QA App – komplette app.js =====================

// === DocBee: Token HIER eintragen ===
const DOCBEE_TOKEN = window.DOCBEE_TOKEN || ""; // DocBee Token eintragen"
const ENABLE_FALLBACK_NOTE = false; // auf true setzen, falls bei Fehler automatisch Notiz angelegt werden soll

window.addEventListener('error', e => {
    try {
        console.error(e.error || e.message || e);
    } catch (_) {}
    alert('JS-Fehler: ' + (e.message || e));
});

let template = null; // {name,module,module_version,pbx_version,steps:[...]}




// === DOM-Refs ===
const els = {
    yamlFile: document.getElementById('yamlFile'),
    stepsTableBody: document.querySelector('#stepsTable tbody'),
    tplName: document.getElementById('tplName'),
    statusTag: document.getElementById('statusTag'),
    module: document.getElementById('module'),
    moduleVersion: document.getElementById('moduleVersion'),
    pbxVersion: document.getElementById('pbxVersion'),
    tester: document.getElementById('tester'),
    olmNummer: document.getElementById('olmNummer'),
    docbeeUrl: document.getElementById('docbeeUrl'),
    btnAddStep: document.getElementById('btnAddStep'),
    btnSaveJSON: document.getElementById('btnSaveJSON'),
    loadJSON: document.getElementById('loadJSON'),
    btnAddGroup: document.getElementById('btnAddGroup'),
    btnExportTemplateYAML: document.getElementById('btnExportTemplateYAML'),
    btnExportAll: document.getElementById('btnExportAll'),
    gitlabTplSelect: document.getElementById('gitlabTplSelect'),
    gitlabTplStatus: document.getElementById('gitlabTplStatus'),
    docbeeTokenStatus: document.getElementById('docbeeTokenStatus'),
    btnGitlabReload: document.getElementById('btnGitlabReload'),
};
// === Drag Guard + Observer: Nur Drag über expliziten Griff zulassen ===
function enforceDragHandleOnly() {
    if (!els.stepsTableBody) return;
    els.stepsTableBody.querySelectorAll('tr[draggable="true"]').forEach(tr => tr.setAttribute('draggable', 'false'));
    els.stepsTableBody.querySelectorAll('.drag-handle').forEach(h => h.setAttribute('draggable', 'true'));
}
document.addEventListener('DOMContentLoaded', () => {
    if (els.stepsTableBody) {
        const mo = new MutationObserver(() => enforceDragHandleOnly());
        mo.observe(els.stepsTableBody, {
            childList: true,
            subtree: true
        });
        enforceDragHandleOnly();
    }
});
document.addEventListener('dragstart', (e) => {
    if (!e.target.closest('.drag-handle')) {
        e.preventDefault();
    }
}, {
    capture: true
});


// === GitLab Events ===
if (els.gitlabTplSelect) els.gitlabTplSelect.addEventListener('change', async (e) => {
    const p = e.target.value;
    if (!p) return;
    try {
        els.gitlabTplStatus && (els.gitlabTplStatus.textContent = "GitLab: lade Datei…");
        const y = await fetchGitlabFileRaw(p);
        loadYAMLText(y);
        els.gitlabTplStatus && (els.gitlabTplStatus.textContent = `GitLab: geladen – ${p.split('/').pop()}`);
    } catch (err) {
        els.gitlabTplStatus && (els.gitlabTplStatus.textContent = "GitLab: Fehler");
        console.error("[GitLab] raw failed:", err);
        alert("Vorlage aus GitLab konnte nicht geladen werden: " + err.message);
    }
});

if (els.btnGitlabReload) els.btnGitlabReload.addEventListener('click', (e) => {
    e.preventDefault();
    populateGitlabDropdown();
});

// === Drag & Drop (Rows verschieben, inkl. Gruppen) ===
let dragIndex = -1;
// ===== Funktion: rowIndexOf =====
// Zweck: siehe Inline-Kommentare im Funktionskörper.
function rowIndexOf(target) {
    const tr = target.closest('tr');
    if (!tr) return -1;
    return [...els.stepsTableBody.children].indexOf(tr);
}
els.stepsTableBody && els.stepsTableBody.addEventListener('dragstart', (e) => {
    if (!e.target.closest('.drag-handle')) {
        e.preventDefault();
        return;
    }
    const i = rowIndexOf(e.target);
    if (i < 0) return;
    dragIndex = i;
    e.dataTransfer?.setData('text/plain', String(i));
    if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';
    const row = e.target.closest('tr') || e.target;
    e.dataTransfer?.setDragImage?.(row, 16, 16);
    row.classList.add('dragging');
});
els.stepsTableBody && els.stepsTableBody.addEventListener('dragend', (e) => {
    const tr = e.target.closest('tr');
    if (tr) tr.classList.remove('dragging');
    [...els.stepsTableBody.children].forEach(r => {
        r.classList.remove('drag-over');
        r.removeAttribute('data-pos');
    });
    dragIndex = -1;
});
els.stepsTableBody && els.stepsTableBody.addEventListener('dragover', (e) => {
    e.preventDefault();
    const tr = e.target.closest('tr');
    if (!tr) return;
    [...els.stepsTableBody.children].forEach(r => {
        r.classList.remove('drag-over');
        r.removeAttribute('data-pos');
    });
    tr.classList.add('drag-over');
    const rect = tr.getBoundingClientRect();
    const pos = (e.clientY - rect.top) < rect.height / 2 ? 'before' : 'after';
    tr.setAttribute('data-pos', pos);
});
els.stepsTableBody && els.stepsTableBody.addEventListener('drop', (e) => {
    e.preventDefault();
    captureEditsIntoTemplate();
    const from = dragIndex >= 0 ? dragIndex : parseInt(e.dataTransfer?.getData('text/plain') || '-1', 10);
    const tr = e.target.closest('tr');
    if (from < 0 || !tr) return;
    const toBase = rowIndexOf(tr);
    const pos = tr.getAttribute('data-pos') || 'after';
    let to = toBase + (pos === 'after' ? 1 : 0);
    if (to === from || to - 1 === from) {
        renderSteps(template.steps);
        recomputeGroupStyles();
        return;
    }
    // Element verschieben
    const item = template.steps.splice(from, 1)[0];
    if (to > from) to--; // nach dem Entfernen verschiebt sich Index
    template.steps.splice(to, 0, item);
    ensureRenumberAndRender();
});

document.getElementById('stepsTable')?.addEventListener('change', (e) => {
    if (e.target && e.target.matches('select.status')) {
        updateStatusClass(e.target);
        recomputeGroupStyles();
    }
});

els.btnExportMD && els.btnExportMD.addEventListener('click', exportMD);
els.btnExportCSV && els.btnExportCSV.addEventListener('click', exportCSV);
els.btnPrintPDF && els.btnPrintPDF.addEventListener('click', printPDF);
els.btnExportTemplateYAML && els.btnExportTemplateYAML.addEventListener('click', exportTemplateYAML);

els.btnSaveJSON && els.btnSaveJSON.addEventListener('click', () => {
    const run = collectRun();
    if (!run) return;
    if (!checkRequired(run)) return;
    const base = `qa-run-${safeName(run.module)}-${safeName(run.module_version)}-${safeName(run.pbx_version)}`;
    download(JSON.stringify(run, null, 2), `${base}.json`, 'application/json');
});
els.loadJSON && els.loadJSON.addEventListener('change', async (e) => {
    const f = e.target.files?.[0];
    if (!f) return;
    const txt = await f.text();
    try {
        const run = JSON.parse(txt);
        template = {
            name: run.name || '',
            steps: (run.steps || []).map(s => ({
                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 || '—';
        els.module.value = run.module || '';
        els.moduleVersion.value = run.module_version || '';
        els.pbxVersion.value = run.pbx_version || '';
        els.tester.value = run.tester || '';
        els.docbeeUrl.value = run.docbee_url || '';
        renderSteps(template.steps);
        recomputeGroupStyles();
        if (els.statusTag) els.statusTag.textContent = 'Lauf geladen';
        updateAutosave();
    } catch (err) {
        alert('Ungültiges JSON: ' + err.message);
    }
});

// === Bindings absichern + Busy-Fix + Mini-CSS ===
(function ensureBindings() {
    // ===== Funktion: bind =====
    // Zweck: siehe Inline-Kommentare im Funktionskörper.
    function bind() {
        const b = document.getElementById('btnPushDocBee');
        if (b) {
            b.removeAttribute('disabled');
            b.classList.remove('is-busy');
            b.style.pointerEvents = 'auto';
            b.addEventListener('click', postToDocBee, {
                once: false
            });
        }
        const p = document.getElementById('btnPrintPDF');
        const btn = document.getElementById('btnExportAll');
        if (btn) {
            btn.addEventListener('click', e => {
                e.preventDefault();
                exportAll().catch(err => alert('Export error: ' + err.message));
            });
            console.log('Export-Button gebunden');
        } else {
            alert('Export-Button nicht gefunden (id=btnExportAll).');
        }
    }
    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bind);
    else bind();
    window.addEventListener('pageshow', () => {
        const b = document.getElementById('btnPushDocBee');
        if (b) {
            b.removeAttribute('disabled');
            b.classList.remove('is-busy');
            b.style.pointerEvents = 'auto';
        }
    });
})();
(function injectAuxCss() {
    const s = document.createElement('style');
    s.textContent = `
    .is-busy{opacity:.6;pointer-events:none}
    .docbee-hint{margin-top:8px;font-size:14px}
    .docbee-hint a{text-decoration:underline}
  `;
    document.head.appendChild(s);
})();

// ===================== Ende app.js =====================