
    (function () {
        'use strict';

        let _openPopover = null;

        // ── helpers ───────────────────────────────────────────────────────
        function closeAllPopovers() {
            document.querySelectorAll('.rel-qa-menu').forEach(el => el.remove());
            _openPopover = null;
        }
        document.addEventListener('click', function(e) {
            if (!e.target.closest('.rel-qa-menu') && !e.target.closest('.btn-rel-action')) closeAllPopovers();
        });
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') closeAllPopovers();
        });

        function popoverPos(btn) {
            const r = btn.getBoundingClientRect();
            return { top: r.bottom + window.scrollY + 4, left: r.left + window.scrollX };
        }

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

        // ── load global entity tags into rel-tag-row divs (using global tag system) ──
        async function loadAllRelationTags() {
            const rows = Array.from(document.querySelectorAll('.rel-tag-row'));
            if (!rows.length) return;
            // Wait briefly for tag-picker.js to initialize
            const renderFn = () => window.renderEntityTags;
            await new Promise(res => { const t = setInterval(() => { if (renderFn()) { clearInterval(t); res(); } }, 50); setTimeout(() => { clearInterval(t); res(); }, 2000); });
            await Promise.all(rows.map(async el => {
                const caseId = parseInt(el.id.replace('rel-tags-', ''));
                if (isNaN(caseId) || !window.renderEntityTags) return;
                await window.renderEntityTags('case', caseId, el.id);
            }));
        }

        // ── tag button → opens global tag picker ──────────────────────────
        window.openRelTagPopover = function(caseId) {
            if (!window.showTagPicker) return;
            window.showTagPicker('case', caseId, () => {
                if (window.renderEntityTags) window.renderEntityTags('case', caseId, 'rel-tags-' + caseId);
            });
        };

        // ── quick action menu ─────────────────────────────────────────────
        const QA_ITEMS = [
            { icon: 'bi-person-check',    label: 'Tildel sag',       action: 'assign'       },
            { icon: 'bi-clock',           label: 'Tidregistrering',  action: 'time'         },
            { icon: 'bi-chat-left-text',  label: 'Kommentar',        action: 'note'         },
            { icon: 'bi-bell',            label: 'Påmindelse',       action: 'reminder'     },
            { icon: 'bi-graph-up-arrow',  label: 'Salgspipeline',    action: 'pipeline'     },
            { icon: 'bi-paperclip',       label: 'Filer',            action: 'files'        },
            { icon: 'bi-cpu',             label: 'Hardware',         action: 'hardware'     },
            { icon: 'bi-check2-square',   label: 'Opgave',           action: 'todo'         },
            { icon: 'bi-lightbulb',       label: 'Løsning',          action: 'solution'     },
            { icon: 'bi-bag',             label: 'Varekøb & salg',   action: 'sales'        },
            { icon: 'bi-arrow-repeat',    label: 'Abonnement',       action: 'subscription' },
            { icon: 'bi-envelope',        label: 'Send email',       action: 'email'        },
        ];

        // cache pipeline presence per caseId so we only fetch once per page load
        const _pipelineCache = {};

        window.openRelQaMenu = async function(caseId, caseTitle, btn) {
            closeAllPopovers();
            btn.classList.add('active');
            const pos = popoverPos(btn);
            const menu = document.createElement('div');
            menu.className = 'rel-qa-menu';
            menu.style.cssText = `position:absolute;top:${pos.top}px;left:${Math.max(0, pos.left - 120)}px;`;
            menu.innerHTML = `<div style="font-size:.72rem;font-weight:700;color:var(--accent);padding:4px 12px 4px;">SAG-${caseId}</div>`
                + `<div style="font-size:.72rem;color:var(--text-secondary,#aaa);padding:2px 12px 4px;"><span class="spinner-border spinner-border-sm" style="width:.6rem;height:.6rem;border-width:.1em;"></span></div>`;
            document.body.appendChild(menu);
            _openPopover = menu;

            // Fetch case data to check pipeline presence (cached)
            if (!(_pipelineCache[caseId] !== undefined)) {
                try {
                    const r = await fetch(`/api/v1/sag/${caseId}`, { credentials: 'include' });
                    if (r.ok) {
                        const d = await r.json();
                        _pipelineCache[caseId] = !!(d.pipeline_stage_id || d.pipeline_amount || d.pipeline_description);
                    } else {
                        _pipelineCache[caseId] = false;
                    }
                } catch { _pipelineCache[caseId] = false; }
            }

            const hasPipeline = _pipelineCache[caseId];

            // Filter: hide pipeline item if case already has one; show "Se pipeline" link instead
            const items = QA_ITEMS.filter(i => i.action !== 'pipeline' || !hasPipeline);
            const extra = hasPipeline
                ? `<div class="qa-item" style="opacity:.55;font-style:italic;" onclick="window.open('/sag/${caseId}','_blank')"><i class="bi bi-graph-up-arrow"></i>Pipeline (se sagen)</div>`
                : '';

            if (!_openPopover || _openPopover !== menu) return; // closed before fetch returned
            menu.innerHTML = `<div style="font-size:.72rem;font-weight:700;color:var(--accent);padding:4px 12px 4px;">SAG-${caseId}</div>`
                + items.map(item =>
                    `<div class="qa-item" onclick="relQaAction('${item.action}',${caseId},'${caseTitle.replace(/'/g,"\\'")}')"><i class="bi ${item.icon}"></i>${esc(item.label)}</div>`
                ).join('')
                + extra;
        };

        function getRelQaPrimaryButton() {
            const sidePanel = document.getElementById('caseAddSidePanel');
            if (sidePanel && sidePanel.classList.contains('open')) {
                return sidePanel.querySelector('#relQaModalFooter .btn-primary');
            }
            return document.querySelector('#relQaModalEl .btn-primary');
        }

        function closeRelQaSurfaceAfterSave() {
            const sidePanel = document.getElementById('caseAddSidePanel');
            const panelOpen = !!(sidePanel && sidePanel.classList.contains('open'));

            const relModalEl = document.getElementById('relQaModalEl');
            const relModalInstance = relModalEl ? bootstrap.Modal.getInstance(relModalEl) : null;
            if (relModalInstance) {
                relModalInstance.hide();
            }

            // In sidepanel mode, refresh to reflect new persisted data across modules.
            if (panelOpen) {
                setTimeout(() => window.location.reload(), 120);
            }
        }

        window.relQaAction = function(action, caseId, caseTitle) {
            closeAllPopovers();
            if      (action === 'time')         openRelTimeModal(caseId, caseTitle);
            else if (action === 'email')        openRelEmailModal(caseId, caseTitle);
            else if (action === 'note')         openRelNoteModal(caseId, caseTitle);
            else if (action === 'reminder')     openRelReminderModal(caseId, caseTitle);
            else if (action === 'todo')         openRelTodoModal(caseId, caseTitle);
            else if (action === 'assign')       openRelAssignModal(caseId, caseTitle);
            else if (action === 'pipeline')     openRelPipelineModal(caseId, caseTitle);
            else if (action === 'files')        openRelFilesModal(caseId, caseTitle);
            else if (action === 'hardware')     openRelHardwareModal(caseId, caseTitle);
            else if (action === 'solution')     openRelSolutionModal(caseId, caseTitle);
            else if (action === 'sales')        openRelSalesModal(caseId, caseTitle);
            else if (action === 'subscription') openRelSubscriptionModal(caseId, caseTitle);
            else                                window.open(`/sag/${caseId}`, '_blank');
        };

        // ── Quick Pipeline modal ──────────────────────────────────────────
        window.openRelPipelineModal = function(caseId, caseTitle) {
            _showRelModal(
                `<i class="bi bi-graph-up-arrow me-2"></i>Salgspipeline`,
                `<div class="mb-2"><label class="form-label small fw-semibold">SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Stage</label>
                   <select id="rqp_stage" class="form-select form-select-sm">
                     <option value="">-- Vælg stage --</option>
                     <option value="1">Ny</option>
                     <option value="2">Afklaring</option>
                     <option value="3">Tilbud</option>
                     <option value="4">Commit</option>
                     <option value="5">Vundet</option>
                     <option value="6">Tabt</option>
                     <option value="7">Opsalg</option>
                     <option value="8">Lead</option>
                     <option value="9">Kontakt</option>
                     <option value="10">Forhandling</option>
                   </select>
                 </div>
                 <div class="row g-2 mb-2">
                   <div class="col-7">
                     <label class="form-label small fw-semibold">Beløb (DKK)</label>
                     <input type="number" id="rqp_amount" class="form-control form-control-sm" min="0" step="0.01" placeholder="0">
                   </div>
                   <div class="col-5">
                     <label class="form-label small fw-semibold">Sandsynlighed %</label>
                     <input type="number" id="rqp_prob" class="form-control form-control-sm" min="0" max="100" placeholder="0">
                   </div>
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Note</label>
                   <textarea id="rqp_desc" class="form-control form-control-sm" rows="2" placeholder="Pipeline-note…"></textarea>
                 </div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelPipeline(${caseId})"><i class="bi bi-check2 me-1"></i>Gem</button>`
            );
        };

        window._submitRelPipeline = async function(caseId) {
            const stage = document.getElementById('rqp_stage').value;
            const amount = document.getElementById('rqp_amount').value;
            const prob = document.getElementById('rqp_prob').value;
            const desc = document.getElementById('rqp_desc').value;
            const payload = {};
            if (stage)  payload.stage_id     = parseInt(stage);
            if (amount) payload.amount        = parseFloat(amount);
            if (prob)   payload.probability   = parseInt(prob);
            if (desc)   payload.description   = desc;
            if (!Object.keys(payload).length) { if (typeof showNotification === 'function') showNotification('Udfyld mindst ét felt', 'warning'); return; }
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) { saveBtn.disabled = true; }
            try {
                const r = await fetch(`/api/v1/sag/${caseId}/pipeline`, { method: 'PATCH', credentials: 'include', headers: {'Content-Type':'application/json'}, body: JSON.stringify(payload) });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Pipeline opdateret ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl', 'error');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Files modal ─────────────────────────────────────────────
        window.openRelFilesModal = function(caseId, caseTitle) {
            _showRelModal(
                `<i class="bi bi-paperclip me-2"></i>Upload fil`,
                `<div class="mb-2"><label class="form-label small fw-semibold">SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Vælg fil</label>
                   <input type="file" id="rqf_file" class="form-control form-control-sm" multiple>
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Beskrivelse (valgfri)</label>
                   <input type="text" id="rqf_desc" class="form-control form-control-sm" placeholder="Fil-note…">
                 </div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelFiles(${caseId})"><i class="bi bi-upload me-1"></i>Upload</button>`
            );
        };

        window._submitRelFiles = async function(caseId) {
            const fileInput = document.getElementById('rqf_file');
            if (!fileInput.files.length) { if (typeof showNotification === 'function') showNotification('Vælg mindst én fil', 'warning'); return; }
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) { saveBtn.disabled = true; saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Uploader…'; }
            let success = 0; let failed = 0;
            for (const file of fileInput.files) {
                try {
                    const fd = new FormData();
                    fd.append('file', file);
                    const desc = document.getElementById('rqf_desc').value;
                    if (desc) fd.append('description', desc);
                    const r = await fetch(`/api/v1/sag/${caseId}/files`, { method: 'POST', credentials: 'include', body: fd });
                    if (r.ok) success++; else failed++;
                } catch { failed++; }
            }
            closeRelQaSurfaceAfterSave();
            if (typeof showNotification === 'function') {
                if (failed === 0) showNotification(`${success} fil(er) uploadet ✓`, 'success');
                else showNotification(`${success} ok, ${failed} fejlede`, 'warning');
            }
        };

        // ── Quick Hardware modal ──────────────────────────────────────────
        window.openRelHardwareModal = async function(caseId, caseTitle) {
            _showRelModal(
                `<i class="bi bi-cpu me-2"></i>Hardware`,
                `<div class="mb-2"><label class="form-label small fw-semibold">SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Søg hardware</label>
                   <input type="text" id="rqhw_search" class="form-control form-control-sm" placeholder="Serienummer, navn…" autocomplete="off">
                   <div id="rqhw_results" class="mt-1" style="max-height:180px;overflow-y:auto;border:1px solid var(--border,#dee2e6);border-radius:6px;display:none;"></div>
                 </div>
                 <div id="rqhw_selected" class="text-muted small"></div>
                 <div class="mb-2 mt-2">
                   <label class="form-label small fw-semibold">Note (valgfri)</label>
                   <input type="text" id="rqhw_note" class="form-control form-control-sm" placeholder="Note om hardware…">
                 </div>
                 <input type="hidden" id="rqhw_id" value="">`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelHardware(${caseId})"><i class="bi bi-check2 me-1"></i>Tilknyt</button>`
            );
            // Wire up search
            const inp = document.getElementById('rqhw_search');
            const res = document.getElementById('rqhw_results');
            let _hwTimer;
            inp.addEventListener('input', () => {
                clearTimeout(_hwTimer);
                _hwTimer = setTimeout(async () => {
                    const q = inp.value.trim();
                    if (q.length < 2) { res.style.display='none'; return; }
                    try {
                        const r = await fetch(`/api/v1/search/hardware?q=${encodeURIComponent(q)}`, { credentials: 'include' });
                        if (!r.ok) return;
                        const items = await r.json();
                        if (!items.length) { res.innerHTML = '<div class="p-2 text-muted small">Ingen resultater</div>'; res.style.display='block'; return; }
                        res.innerHTML = items.slice(0,10).map(h =>
                            `<div class="p-2 border-bottom hw-opt" style="cursor:pointer;font-size:.82rem;" data-id="${h.id}" data-label="${esc(h.name||h.serial_number||h.id)}">${esc(h.name||'')} <span class="text-muted">${esc(h.serial_number||'')}</span></div>`
                        ).join('');
                        res.style.display = 'block';
                        res.querySelectorAll('.hw-opt').forEach(el => el.addEventListener('click', () => {
                            document.getElementById('rqhw_id').value = el.dataset.id;
                            document.getElementById('rqhw_selected').textContent = '✓ Valgt: ' + el.dataset.label;
                            inp.value = el.dataset.label;
                            res.style.display = 'none';
                        }));
                    } catch {}
                }, 300);
            });
        };

        window._submitRelHardware = async function(caseId) {
            const hwId = document.getElementById('rqhw_id').value;
            if (!hwId) { if (typeof showNotification === 'function') showNotification('Vælg hardware fra listen', 'warning'); return; }
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) saveBtn.disabled = true;
            try {
                const r = await fetch(`/api/v1/sag/${caseId}/hardware`, {
                    method: 'POST', credentials: 'include', headers: {'Content-Type':'application/json'},
                    body: JSON.stringify({ hardware_id: parseInt(hwId), note: document.getElementById('rqhw_note').value })
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Hardware tilknyttet ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl', 'error');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Løsning modal ───────────────────────────────────────────
        window.openRelSolutionModal = function(caseId, caseTitle) {
            const today = new Date().toISOString().split('T')[0];
            _showRelModal(
                `<i class="bi bi-lightbulb me-2"></i>Løsning`,
                `<div class="mb-2"><label class="form-label small fw-semibold">SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Titel</label>
                   <input type="text" id="rqs_title" class="form-control form-control-sm" placeholder="Løsningstitel…">
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Type</label>
                   <select id="rqs_type" class="form-select form-select-sm">
                     <option value="standard">Standard</option>
                     <option value="workaround">Workaround</option>
                     <option value="permanent">Permanent</option>
                     <option value="external">Ekstern</option>
                   </select>
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Resultat</label>
                   <select id="rqs_result" class="form-select form-select-sm">
                     <option value="resolved">Løst</option>
                     <option value="partial">Delvist løst</option>
                     <option value="unresolved">Uløst</option>
                   </select>
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Beskrivelse</label>
                   <textarea id="rqs_desc" class="form-control form-control-sm" rows="3" placeholder="Beskriv løsningen…"></textarea>
                 </div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelSolution(${caseId})"><i class="bi bi-check2 me-1"></i>Gem</button>`
            );
        };

        window._submitRelSolution = async function(caseId) {
            const title = document.getElementById('rqs_title').value.trim();
            if (!title) { if (typeof showNotification === 'function') showNotification('Angiv en titel', 'warning'); return; }
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) saveBtn.disabled = true;
            try {
                const r = await fetch(`/api/v1/sag/${caseId}/solution`, {
                    method: 'POST', credentials: 'include', headers: {'Content-Type':'application/json'},
                    body: JSON.stringify({
                        sag_id: caseId,
                        title,
                        solution_type:  document.getElementById('rqs_type').value,
                        result:         document.getElementById('rqs_result').value,
                        description:    document.getElementById('rqs_desc').value,
                    })
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Løsning gemt ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl', 'error');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Varekøb & Salg modal ────────────────────────────────────
        window.openRelSalesModal = function(caseId, caseTitle) {
            const today = new Date().toISOString().split('T')[0];
            _showRelModal(
                `<i class="bi bi-bag me-2"></i>Varekøb &amp; salg`,
                `<div class="mb-2"><label class="form-label small fw-semibold">SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Type</label>
                   <select id="rqsl_type" class="form-select form-select-sm">
                     <option value="sale">Salg</option>
                     <option value="purchase">Indkøb</option>
                   </select>
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Beskrivelse</label>
                   <input type="text" id="rqsl_desc" class="form-control form-control-sm" placeholder="Varebeskrivelse…">
                 </div>
                 <div class="row g-2 mb-2">
                   <div class="col-4">
                     <label class="form-label small fw-semibold">Antal</label>
                     <input type="number" id="rqsl_qty" class="form-control form-control-sm" min="1" value="1" step="1">
                   </div>
                   <div class="col-4">
                     <label class="form-label small fw-semibold">Stykpris</label>
                     <input type="number" id="rqsl_uprice" class="form-control form-control-sm" min="0" step="0.01" placeholder="0.00">
                   </div>
                   <div class="col-4">
                     <label class="form-label small fw-semibold">Total (DKK)</label>
                     <input type="number" id="rqsl_total" class="form-control form-control-sm" min="0" step="0.01" placeholder="0.00">
                   </div>
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Dato</label>
                   <input type="date" id="rqsl_date" class="form-control form-control-sm" value="${today}">
                 </div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelSales(${caseId})"><i class="bi bi-check2 me-1"></i>Gem</button>`
            );
            // Auto-calculate total when qty/uprice changes
            setTimeout(() => {
                const qtyEl   = document.getElementById('rqsl_qty');
                const uprEl   = document.getElementById('rqsl_uprice');
                const totEl   = document.getElementById('rqsl_total');
                function calcTotal() {
                    const q = parseFloat(qtyEl.value) || 0;
                    const u = parseFloat(uprEl.value) || 0;
                    if (q && u) totEl.value = (q * u).toFixed(2);
                }
                qtyEl.addEventListener('input', calcTotal);
                uprEl.addEventListener('input', calcTotal);
            }, 50);
        };

        window._submitRelSales = async function(caseId) {
            const desc = document.getElementById('rqsl_desc').value.trim();
            const total = parseFloat(document.getElementById('rqsl_total').value);
            if (!desc) { if (typeof showNotification === 'function') showNotification('Angiv beskrivelse', 'warning'); return; }
            if (!total) { if (typeof showNotification === 'function') showNotification('Angiv beløb', 'warning'); return; }
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) saveBtn.disabled = true;
            try {
                const r = await fetch(`/api/v1/sag/${caseId}/sale-items`, {
                    method: 'POST', credentials: 'include', headers: {'Content-Type':'application/json'},
                    body: JSON.stringify({
                        type:        document.getElementById('rqsl_type').value,
                        description: desc,
                        quantity:    parseFloat(document.getElementById('rqsl_qty').value) || 1,
                        unit_price:  parseFloat(document.getElementById('rqsl_uprice').value) || null,
                        amount:      total,
                        line_date:   document.getElementById('rqsl_date').value || null,
                        status:      'draft',
                    })
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Varelinje oprettet ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl', 'error');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Abonnement modal ────────────────────────────────────────
        window.openRelSubscriptionModal = function(caseId, caseTitle) {
            const today = new Date().toISOString().split('T')[0];
            _showRelModal(
                `<i class="bi bi-arrow-repeat me-2"></i>Abonnement`,
                `<div class="mb-2"><label class="form-label small fw-semibold">SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="row g-2 mb-2">
                   <div class="col-6">
                     <label class="form-label small fw-semibold">Faktureringsinterval</label>
                     <select id="rqsub_interval" class="form-select form-select-sm">
                       <option value="monthly">Månedlig</option>
                       <option value="quarterly">Kvartalsvis</option>
                       <option value="yearly">Årlig</option>
                       <option value="weekly">Ugentlig</option>
                     </select>
                   </div>
                   <div class="col-3">
                     <label class="form-label small fw-semibold">Fakturering dag</label>
                     <input type="number" id="rqsub_day" class="form-control form-control-sm" min="1" max="28" value="1">
                   </div>
                   <div class="col-3">
                     <label class="form-label small fw-semibold">Startdato</label>
                     <input type="date" id="rqsub_start" class="form-control form-control-sm" value="${today}">
                   </div>
                 </div>
                 <div class="border rounded p-2 mb-2">
                   <div class="small fw-semibold mb-1">Varelinje</div>
                   <div class="row g-1">
                     <div class="col-6"><input type="text" id="rqsub_li_desc" class="form-control form-control-sm" placeholder="Beskrivelse"></div>
                     <div class="col-3"><input type="number" id="rqsub_li_qty" class="form-control form-control-sm" placeholder="Antal" min="1" value="1"></div>
                     <div class="col-3"><input type="number" id="rqsub_li_price" class="form-control form-control-sm" placeholder="Pris" min="0" step="0.01"></div>
                   </div>
                 </div>
                 <div class="mb-2">
                   <label class="form-label small fw-semibold">Note (valgfri)</label>
                   <input type="text" id="rqsub_notes" class="form-control form-control-sm" placeholder="Intern note…">
                 </div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelSubscription(${caseId})"><i class="bi bi-check2 me-1"></i>Opret</button>`
            );
        };

        window._submitRelSubscription = async function(caseId) {
            const interval  = document.getElementById('rqsub_interval').value;
            const day       = parseInt(document.getElementById('rqsub_day').value);
            const startDate = document.getElementById('rqsub_start').value;
            const liDesc    = document.getElementById('rqsub_li_desc').value.trim();
            const liQty     = parseFloat(document.getElementById('rqsub_li_qty').value) || 1;
            const liPrice   = parseFloat(document.getElementById('rqsub_li_price').value) || 0;
            if (!startDate) { if (typeof showNotification === 'function') showNotification('Angiv startdato', 'warning'); return; }
            if (!liDesc || !liPrice) { if (typeof showNotification === 'function') showNotification('Udfyld varelinje (beskrivelse + pris)', 'warning'); return; }
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) saveBtn.disabled = true;
            try {
                const r = await fetch('/api/v1/sag-subscriptions', {
                    method: 'POST', credentials: 'include', headers: {'Content-Type':'application/json'},
                    body: JSON.stringify({
                        sag_id:           caseId,
                        billing_interval: interval,
                        billing_day:      day,
                        start_date:       startDate,
                        notes:            document.getElementById('rqsub_notes').value || null,
                        line_items: [{ description: liDesc, quantity: liQty, unit_price: liPrice }]
                    })
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Abonnement oprettet ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl', 'error');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Time modal ──────────────────────────────────────────────
        window.openRelTimeModal = function(caseId, caseTitle) {
            const today = new Date().toISOString().split('T')[0];
            _showRelModal(
                `<i class="bi bi-clock me-2"></i>Tidregistrering`,
                `<div class="mb-2"><label class="form-label small fw-semibold">Sag</label>
                 <input class="form-control form-control-sm" readonly value="SAG-${caseId} – ${esc(caseTitle)}"></div>
                 <div class="row g-2 mb-2">
                   <div class="col-6"><label class="form-label small fw-semibold">Dato</label>
                     <input type="date" id="rqt_date" class="form-control form-control-sm" value="${today}"></div>
                   <div class="col-3"><label class="form-label small fw-semibold">Timer</label>
                     <input type="number" id="rqt_h" class="form-control form-control-sm" min="0" max="23" value="0"></div>
                   <div class="col-3"><label class="form-label small fw-semibold">Min</label>
                     <input type="number" id="rqt_m" class="form-control form-control-sm" min="0" max="59" step="15" value="30"></div>
                 </div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Fakturering</label>
                   <select id="rqt_billing" class="form-select form-select-sm">
                     <option value="invoice">Fakturerbar</option>
                     <option value="internal">Intern</option>
                     <option value="prepaid">Forudbetalt</option>
                   </select></div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Beskrivelse</label>
                   <textarea id="rqt_desc" class="form-control form-control-sm" rows="2"></textarea></div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelTime(${caseId})"><i class="bi bi-check2 me-1"></i>Gem</button>`
            );
        };

        window._submitRelTime = async function(caseId) {
            const h = parseInt(document.getElementById('rqt_h').value) || 0;
            const m = parseInt(document.getElementById('rqt_m').value) || 0;
            const totalHours = parseFloat((h + m / 60).toFixed(4));
            if (totalHours <= 0) {
                if (typeof showNotification === 'function') showNotification('Angiv tid (timer/minutter)', 'warning');
                return;
            }
            const billing = document.getElementById('rqt_billing')?.value || 'invoice';
            const payload = {
                sag_id: caseId,
                worked_date: document.getElementById('rqt_date').value,
                original_hours: totalHours,
                description: document.getElementById('rqt_desc').value,
                billing_method: billing,
                is_internal: billing === 'internal',
            };
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) { saveBtn.disabled = true; saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span>'; }
            try {
                const r = await fetch('/api/v1/timetracking/entries/internal', { method: 'POST', credentials: 'include', headers: {'Content-Type':'application/json'}, body: JSON.stringify(payload) });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Tid registreret ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl ved registrering', 'error');
                    if (saveBtn) { saveBtn.disabled = false; saveBtn.innerHTML = '<i class="bi bi-check2 me-1"></i>Gem'; }
                }
            } catch { if (saveBtn) { saveBtn.disabled = false; saveBtn.innerHTML = 'Gem'; } }
        };

        // ── Quick Email modal ─────────────────────────────────────────────
        window.openRelEmailModal = function(caseId, caseTitle) {
            const defaultRecipient = typeof getDefaultCaseRecipient === 'function' ? getDefaultCaseRecipient() : '';
            const defaultSubject = `Sag #${caseId}: `;
            const attachmentOptions = Array.isArray(sagFilesCache) && sagFilesCache.length
                ? sagFilesCache
                    .map((file) => {
                        const fileId = Number(file.id);
                        const filename = esc(file.filename || `Fil ${fileId}`);
                        return `<option value="${fileId}">${filename}</option>`;
                    })
                    .join('')
                : '<option disabled>Ingen sagsfiler</option>';

            _showRelModal(
                `<i class="bi bi-envelope me-2"></i>Email`,
                `<div class="mb-2"><label class="form-label small fw-semibold">Sag: SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="row g-2 mb-2">
                   <div class="col-12"><label class="form-label small fw-semibold">Til</label>
                     <input type="text" id="rqe_to" class="form-control form-control-sm" placeholder="modtager@eksempel.dk" value="${esc(defaultRecipient)}"></div>
                   <div class="col-6"><label class="form-label small fw-semibold">Cc</label>
                     <input type="text" id="rqe_cc" class="form-control form-control-sm" placeholder="cc@eksempel.dk"></div>
                   <div class="col-6"><label class="form-label small fw-semibold">Bcc</label>
                     <input type="text" id="rqe_bcc" class="form-control form-control-sm" placeholder="bcc@eksempel.dk"></div>
                 </div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Emne</label>
                   <input type="text" id="rqe_subject" class="form-control form-control-sm" value="${esc(defaultSubject)}"></div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Vedhaeftninger</label>
                   <select id="rqe_attachment_ids" class="form-select form-select-sm" multiple>${attachmentOptions}</select>
                 </div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Besked</label>
                   <textarea id="rqe_body" class="form-control form-control-sm" rows="6" placeholder="Skriv besked..."></textarea></div>
                 <div id="rqe_status" class="small text-muted"></div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelEmail(${caseId})"><i class="bi bi-send me-1"></i>Send email</button>`
            );
        };

        window._submitRelEmail = async function(caseId) {
            const toInput = document.getElementById('rqe_to');
            const ccInput = document.getElementById('rqe_cc');
            const bccInput = document.getElementById('rqe_bcc');
            const subjectInput = document.getElementById('rqe_subject');
            const bodyInput = document.getElementById('rqe_body');
            const attachmentSelect = document.getElementById('rqe_attachment_ids');
            const statusEl = document.getElementById('rqe_status');
            const saveBtn = getRelQaPrimaryButton();

            if (!toInput || !subjectInput || !bodyInput || !statusEl) return;

            const to = parseEmailField(toInput.value);
            const cc = parseEmailField(ccInput?.value || '');
            const bcc = parseEmailField(bccInput?.value || '');
            const subject = (subjectInput.value || '').trim();
            const bodyText = (bodyInput.value || '').trim();
            const attachmentFileIds = Array.from(attachmentSelect?.selectedOptions || [])
                .map((opt) => Number(opt.value))
                .filter((id) => Number.isInteger(id) && id > 0);

            if (!to.length) {
                if (typeof showNotification === 'function') showNotification('Udfyld mindst en modtager.', 'warning');
                return;
            }
            if (!subject) {
                if (typeof showNotification === 'function') showNotification('Udfyld emne.', 'warning');
                return;
            }
            if (!bodyText) {
                if (typeof showNotification === 'function') showNotification('Udfyld besked.', 'warning');
                return;
            }

            if (saveBtn) {
                saveBtn.disabled = true;
                saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Sender...';
            }
            statusEl.className = 'small text-muted';
            statusEl.textContent = 'Sender e-mail...';

            try {
                const res = await fetch(`/api/v1/sag/${caseId}/emails/send`, {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({
                        to,
                        cc,
                        bcc,
                        subject,
                        body_text: bodyText,
                        attachment_file_ids: attachmentFileIds,
                        thread_email_id: selectedLinkedEmailId || null,
                        thread_key: linkedEmailsCache.find((entry) => Number(entry.id) === Number(selectedLinkedEmailId))?.thread_key || null
                    })
                });

                if (!res.ok) {
                    let message = `HTTP ${res.status} ${res.statusText || 'Send failed'}`;
                    try {
                        const responseText = await res.text();
                        if (responseText) {
                            try {
                                const err = JSON.parse(responseText);
                                if (err?.detail) {
                                    message = err.detail;
                                } else if (err?.message) {
                                    message = err.message;
                                }
                            } catch (_) {
                                message = responseText.slice(0, 500);
                            }
                        }
                    } catch (_) {
                    }
                    throw new Error(message);
                }

                statusEl.className = 'small text-success';
                statusEl.textContent = 'E-mail sendt.';
                if (typeof loadLinkedEmails === 'function') {
                    loadLinkedEmails();
                }
                if (typeof showNotification === 'function') showNotification('E-mail sendt.', 'success');

                const relModalEl = document.getElementById('relQaModalEl');
                const relModal = relModalEl ? bootstrap.Modal.getInstance(relModalEl) : null;
                if (relModal) relModal.hide();
            } catch (error) {
                statusEl.className = 'small text-danger';
                statusEl.textContent = error?.message || 'Email send failed (ukendt fejl)';
                if (typeof showNotification === 'function') showNotification(statusEl.textContent, 'error');
                if (saveBtn) {
                    saveBtn.disabled = false;
                    saveBtn.innerHTML = '<i class="bi bi-send me-1"></i>Send email';
                }
                return;
            }

            if (saveBtn) {
                saveBtn.disabled = false;
                saveBtn.innerHTML = '<i class="bi bi-send me-1"></i>Send email';
            }
        };

        // ── Quick Kommentar modal ─────────────────────────────────────────
        window.openRelNoteModal = function(caseId, caseTitle) {
            _showRelModal(
                `<i class="bi bi-chat-left-text me-2"></i>Kommentar`,
                `<div class="mb-2"><label class="form-label small fw-semibold">Sag: SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <textarea id="rqn_text" class="form-control" rows="4" placeholder="Skriv kommentar..."></textarea>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelNote(${caseId})"><i class="bi bi-check2 me-1"></i>Gem</button>`
            );
        };

        window._submitRelNote = async function(caseId) {
            const text = document.getElementById('rqn_text').value.trim();
            if (!text) return;
            const saveBtn = document.querySelector('#relQaModalEl .btn-primary');
            if (saveBtn) { saveBtn.disabled = true; }
            try {
                const r = await fetch(`/api/v1/sag/${caseId}/kommentarer`, {
                    method: 'POST', credentials: 'include',
                    headers: {'Content-Type':'application/json'},
                    body: JSON.stringify({ forfatter: 'Hurtig kommentar', indhold: text })
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Kommentar tilføjet ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl ved gemning', 'error');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Opgave modal ────────────────────────────────────────────
        window.openRelTodoModal = function(caseId, caseTitle) {
            const today = new Date().toISOString().split('T')[0];
            _showRelModal(
                `<i class="bi bi-check2-square me-2"></i>Opgave`,
                `<div class="mb-2"><label class="form-label small fw-semibold">Sag: SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Opgavetitel</label>
                   <input type="text" id="rqtd_title" class="form-control form-control-sm" placeholder="Hvad skal gøres?"></div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Frist (valgfri)</label>
                   <input type="date" id="rqtd_due" class="form-control form-control-sm" value="${today}"></div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelTodo(${caseId})"><i class="bi bi-check2 me-1"></i>Opret</button>`
            );
        };

        window._submitRelTodo = async function(caseId) {
            const title = document.getElementById('rqtd_title').value.trim();
            if (!title) { if (typeof showNotification === 'function') showNotification('Angiv opgavetitel', 'warning'); return; }
            const due = document.getElementById('rqtd_due').value || null;
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) { saveBtn.disabled = true; }
            try {
                const r = await fetch(`/api/v1/sag/${caseId}/todos`, {
                    method: 'POST', credentials: 'include',
                    headers: {'Content-Type':'application/json'},
                    body: JSON.stringify({ titel: title, frist: due, sag_id: caseId })
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Opgave oprettet ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Opgave-endpoint ikke tilgængeligt endnu', 'warning');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Tildel sag modal ────────────────────────────────────────
        window.openRelAssignModal = async function(caseId, caseTitle) {
            _showRelModal(
                `<i class="bi bi-person-check me-2"></i>Tildel sag`,
                `<div class="mb-2"><label class="form-label small fw-semibold">SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <label class="form-label small fw-semibold">Ansvarlig bruger</label>
                 <select id="rqa_user" class="form-select form-select-sm"><option>Henter brugere…</option></select>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelAssign(${caseId})"><i class="bi bi-check2 me-1"></i>Tildel</button>`
            );
            try {
                const r = await fetch('/api/v1/users', { credentials: 'include' });
                if (r.ok) {
                    const users = await r.json();
                    const sel = document.getElementById('rqa_user');
                    if (sel) sel.innerHTML = '<option value="">Ingen (fjern tildeling)</option>'
                        + users.map(u => `<option value="${u.user_id}">${esc(u.display_name || u.username || '')}</option>`).join('');
                }
            } catch {}
        };

        window._submitRelAssign = async function(caseId) {
            const userId = document.getElementById('rqa_user')?.value;
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) { saveBtn.disabled = true; }
            try {
                const r = await fetch(`/api/v1/sag/${caseId}`, {
                    method: 'PATCH', credentials: 'include',
                    headers: {'Content-Type':'application/json'},
                    body: JSON.stringify({ ansvarlig_bruger_id: userId ? parseInt(userId) : null })
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Sag tildelt ✓', 'success');
                } else {
                    const d = await r.json().catch(()=>({}));
                    if (typeof showNotification === 'function') showNotification(d.detail || 'Fejl ved tildeling', 'error');
                    if (saveBtn) saveBtn.disabled = false;
                }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── Quick Reminder modal ──────────────────────────────────────────
        window.openRelReminderModal = function(caseId, caseTitle) {
            const tmr = new Date(); tmr.setDate(tmr.getDate()+1);
            const tmrStr = tmr.toISOString().slice(0,16);
            _showRelModal(
                `<i class="bi bi-bell me-2"></i>Påmindelse`,
                `<div class="mb-2"><label class="form-label small fw-semibold">Sag: SAG-${caseId} – ${esc(caseTitle)}</label></div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Tidspunkt</label>
                   <input type="datetime-local" id="rqr_at" class="form-control form-control-sm" value="${tmrStr}"></div>
                 <div class="mb-2"><label class="form-label small fw-semibold">Besked</label>
                   <input type="text" id="rqr_msg" class="form-control form-control-sm" placeholder="Husk at…"></div>`,
                `<button class="btn btn-sm btn-primary" onclick="_submitRelReminder(${caseId})"><i class="bi bi-check2 me-1"></i>Gem</button>`
            );
        };

        window._submitRelReminder = async function(caseId) {
            const payload = { sag_id: caseId, remind_at: document.getElementById('rqr_at').value, message: document.getElementById('rqr_msg').value };
            const saveBtn = getRelQaPrimaryButton();
            if (saveBtn) { saveBtn.disabled = true; }
            try {
                const r = await fetch('/api/v1/reminders', {
                    method: 'POST', credentials: 'include',
                    headers: {'Content-Type':'application/json'},
                    body: JSON.stringify(payload)
                });
                if (r.ok) {
                    closeRelQaSurfaceAfterSave();
                    if (typeof showNotification === 'function') showNotification('Påmindelse oprettet', 'success');
                } else { if (saveBtn) saveBtn.disabled = false; }
            } catch { if (saveBtn) saveBtn.disabled = false; }
        };

        // ── shared modal helper ───────────────────────────────────────────
        window._showRelModal = function(title, bodyHtml, footerBtns) {
            let el = document.getElementById('relQaModalEl');
            if (!el) {
                el = document.createElement('div');
                el.id = 'relQaModalEl';
                el.className = 'modal fade';
                el.tabIndex = -1;
                el.innerHTML = `<div class="modal-dialog modal-dialog-centered"><div class="modal-content">
                    <div class="modal-header py-2 px-3">
                        <h6 class="modal-title mb-0" id="relQaModalTitle"></h6>
                        <button type="button" class="btn-close btn-sm" data-bs-dismiss="modal"></button>
                    </div>
                    <div class="modal-body" id="relQaModalBody"></div>
                    <div class="modal-footer py-2 px-3" id="relQaModalFooter">
                        <button class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">Annuller</button>
                    </div>
                </div></div>`;
                document.body.appendChild(el);
            }
            document.getElementById('relQaModalTitle').innerHTML = title;
            document.getElementById('relQaModalBody').innerHTML = bodyHtml;
            const footer = document.getElementById('relQaModalFooter');
            // Remove old action buttons (keep Annuller)
            footer.querySelectorAll('.btn-primary').forEach(b => b.remove());
            if (footerBtns) footer.insertAdjacentHTML('afterbegin', footerBtns);
            new bootstrap.Modal(el).show();
        };

        // ── init on page load ─────────────────────────────────────────────
        document.addEventListener('DOMContentLoaded', loadAllRelationTags);

    })();
    