
        const subscriptionCaseId = {{ case.id }};
        let currentSubscription = null;
        let subscriptionProducts = [];
        let lastCreatedSubscriptionProductId = null;

        function formatSubscriptionInterval(interval) {
            const map = {
                'daily': 'Daglig',
                'biweekly': '14-dage',
                'monthly': 'Maaned',
                'quarterly': 'Kvartal',
                'yearly': 'Aar'
            };
            return map[interval] || interval || '-';
        }

        function formatSubscriptionCurrency(amount) {
            return new Intl.NumberFormat('da-DK', {
                style: 'currency',
                currency: 'DKK',
                minimumFractionDigits: 0,
                maximumFractionDigits: 0
            }).format(amount || 0);
        }

        function formatSubscriptionDate(dateStr) {
            if (!dateStr) return '-';
            const date = new Date(dateStr);
            return date.toLocaleDateString('da-DK');
        }

        function setSubscriptionBadge(status) {
            const badge = document.getElementById('subscriptionStatusBadge');
            if (!badge) return;
            const classes = {
                'draft': 'bg-light text-dark',
                'active': 'bg-success',
                'paused': 'bg-warning',
                'cancelled': 'bg-secondary'
            };
            const label = {
                'draft': 'Kladde',
                'active': 'Aktiv',
                'paused': 'Pauset',
                'cancelled': 'Opsagt'
            };
            badge.className = `badge ${classes[status] || 'bg-light text-dark'}`;
            badge.textContent = label[status] || status || 'Ingen';
        }

        function showSubscriptionCreateForm() {
            const empty = document.getElementById('subscriptionEmpty');
            const form = document.getElementById('subscriptionCreateForm');
            const details = document.getElementById('subscriptionDetails');
            if (empty) empty.classList.remove('d-none');
            if (form) form.classList.remove('d-none');
            if (details) details.classList.add('d-none');
            setSubscriptionBadge(null);

            const startDateInput = document.getElementById('subscriptionStartDateInput');
            if (startDateInput && !startDateInput.value) {
                startDateInput.value = new Date().toISOString().split('T')[0];
            }

            const body = document.getElementById('subscriptionLineItemsBody');
            if (body) {
                body.innerHTML = `
                    <tr>
                        <td>
                            <select class="form-select form-select-sm subscriptionProductSelect" onchange="applySubscriptionProduct(this)">
                                <option value="">Vælg produkt</option>
                            </select>
                        </td>
                        <td><input type="text" class="form-control form-control-sm" placeholder="Managed Backup"></td>
                        <td><input type="number" class="form-control form-control-sm" min="0.01" step="0.01" value="1" oninput="updateSubscriptionLineTotals()"></td>
                        <td><input type="number" class="form-control form-control-sm" min="0" step="0.01" value="0" oninput="updateSubscriptionLineTotals()"></td>
                        <td class="text-end"><span class="subscriptionLineTotal">0,00 kr</span></td>
                        <td class="text-end">
                            <button type="button" class="btn btn-sm btn-outline-danger" onclick="removeSubscriptionLine(this)"><i class="bi bi-x"></i></button>
                        </td>
                    </tr>
                `;
            }
            populateSubscriptionProductSelects();
            updateSubscriptionLineTotals();
        }

        function populateSubscriptionProductSelects() {
            const selects = document.querySelectorAll('.subscriptionProductSelect');
            selects.forEach(select => {
                const currentValue = select.value;
                select.innerHTML = '<option value="">Vælg produkt</option>';
                subscriptionProducts.forEach(product => {
                    const option = document.createElement('option');
                    option.value = product.id;
                    option.textContent = product.name;
                    option.dataset.salesPrice = product.sales_price ?? '';
                    option.dataset.description = product.short_description ?? '';
                    select.appendChild(option);
                });
                if (currentValue) {
                    select.value = currentValue;
                } else if (lastCreatedSubscriptionProductId) {
                    select.value = String(lastCreatedSubscriptionProductId);
                }
            });
            lastCreatedSubscriptionProductId = null;
        }

        function applySubscriptionProduct(select) {
            const row = select.closest('tr');
            if (!row) return;
            const descriptionInput = row.querySelector('input[type="text"]');
            const unitPriceInput = row.querySelectorAll('input[type="number"]')[1];
            const selected = select.options[select.selectedIndex];
            if (!selected) return;

            const description = selected.dataset.description || selected.textContent || '';
            const salesPrice = selected.dataset.salesPrice;

            if (descriptionInput && !descriptionInput.value.trim()) {
                descriptionInput.value = description;
            }
            if (unitPriceInput && salesPrice !== '') {
                unitPriceInput.value = salesPrice;
            }
            updateSubscriptionLineTotals();
        }

        function addSubscriptionLine() {
            const body = document.getElementById('subscriptionLineItemsBody');
            if (!body) return;
            const row = document.createElement('tr');
            row.innerHTML = `
                <td>
                    <select class="form-select form-select-sm subscriptionProductSelect" onchange="applySubscriptionProduct(this)">
                        <option value="">Vælg produkt</option>
                    </select>
                </td>
                <td><input type="text" class="form-control form-control-sm" placeholder="Beskrivelse"></td>
                <td><input type="number" class="form-control form-control-sm" min="0.01" step="0.01" value="1" oninput="updateSubscriptionLineTotals()"></td>
                <td><input type="number" class="form-control form-control-sm" min="0" step="0.01" value="0" oninput="updateSubscriptionLineTotals()"></td>
                <td class="text-end"><span class="subscriptionLineTotal">0,00 kr</span></td>
                <td class="text-end">
                    <button type="button" class="btn btn-sm btn-outline-danger" onclick="removeSubscriptionLine(this)"><i class="bi bi-x"></i></button>
                </td>
            `;
            body.appendChild(row);
            populateSubscriptionProductSelects();
            updateSubscriptionLineTotals();
        }

        function removeSubscriptionLine(button) {
            const row = button.closest('tr');
            const body = document.getElementById('subscriptionLineItemsBody');
            if (!row || !body) return;
            if (body.children.length <= 1) {
                row.querySelectorAll('input').forEach(input => {
                    input.value = input.type === 'number' ? 0 : '';
                });
            } else {
                row.remove();
            }
            updateSubscriptionLineTotals();
        }

        function updateSubscriptionLineTotals() {
            const body = document.getElementById('subscriptionLineItemsBody');
            const totalEl = document.getElementById('subscriptionLinesTotal');
            if (!body || !totalEl) return;

            let total = 0;
            Array.from(body.querySelectorAll('tr')).forEach(row => {
                const inputs = row.querySelectorAll('input');
                const description = inputs[0]?.value || '';
                const qty = parseFloat(inputs[1]?.value || 0);
                const unit = parseFloat(inputs[2]?.value || 0);
                const lineTotal = (qty > 0 ? qty : 0) * (unit > 0 ? unit : 0);
                total += lineTotal;
                const lineTotalEl = row.querySelector('.subscriptionLineTotal');
                if (lineTotalEl) {
                    lineTotalEl.textContent = formatSubscriptionCurrency(lineTotal);
                }
                if (!description && qty === 0 && unit === 0) {
                    if (lineTotalEl) {
                        lineTotalEl.textContent = formatSubscriptionCurrency(0);
                    }
                }
            });

            totalEl.textContent = formatSubscriptionCurrency(total);
        }

        function collectSubscriptionLineItems() {
            const body = document.getElementById('subscriptionLineItemsBody');
            if (!body) return [];
            const items = [];
            Array.from(body.querySelectorAll('tr')).forEach(row => {
                const productSelect = row.querySelector('.subscriptionProductSelect');
                const inputs = row.querySelectorAll('input');
                const description = (inputs[0]?.value || '').trim();
                const quantity = parseFloat(inputs[1]?.value || 0);
                const unitPrice = parseFloat(inputs[2]?.value || 0);
                if (!description && quantity === 0 && unitPrice === 0) {
                    return;
                }
                items.push({
                    product_id: productSelect && productSelect.value ? parseInt(productSelect.value, 10) : null,
                    description,
                    quantity,
                    unit_price: unitPrice
                });
            });
            return items;
        }

        async function loadSubscriptionProducts() {
            try {
                const res = await fetch('/api/v1/products');
                if (!res.ok) {
                    throw new Error('Kunne ikke hente produkter');
                }
                subscriptionProducts = await res.json();
            } catch (e) {
                console.error('Error loading products:', e);
                subscriptionProducts = [];
            }
            populateSubscriptionProductSelects();
        }

        function openSubscriptionProductModal() {
            const form = document.getElementById('subscriptionProductForm');
            if (form) form.reset();
            new bootstrap.Modal(document.getElementById('subscriptionProductModal')).show();
        }

        async function createSubscriptionProduct() {
            const payload = {
                name: document.getElementById('subscriptionProductName').value.trim(),
                type: document.getElementById('subscriptionProductType').value.trim() || null,
                status: document.getElementById('subscriptionProductStatus').value,
                sales_price: document.getElementById('subscriptionProductSalesPrice').value || null,
                billing_period: document.getElementById('subscriptionProductBillingPeriod').value || null,
                short_description: document.getElementById('subscriptionProductDescription').value.trim() || null
            };

            if (!payload.name) {
                alert('Navn er paakraevet');
                return;
            }

            const res = await fetch('/api/v1/products', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });

            if (!res.ok) {
                const error = await res.json();
                alert(error.detail || 'Kunne ikke oprette produkt');
                return;
            }

            const product = await res.json();
            lastCreatedSubscriptionProductId = product.id;
            bootstrap.Modal.getInstance(document.getElementById('subscriptionProductModal')).hide();
            await loadSubscriptionProducts();
            updateSubscriptionLineTotals();
        }

        function renderSubscription(subscription) {
            currentSubscription = subscription;
            const empty = document.getElementById('subscriptionEmpty');
            const form = document.getElementById('subscriptionCreateForm');
            const details = document.getElementById('subscriptionDetails');
            if (empty) empty.classList.add('d-none');
            if (form) form.classList.add('d-none');
            if (details) details.classList.remove('d-none');

            document.getElementById('subscriptionNumber').textContent = subscription.subscription_number || `#${subscription.id}`;
            document.getElementById('subscriptionProduct').textContent = subscription.product_name || '-';
            document.getElementById('subscriptionInterval').textContent = formatSubscriptionInterval(subscription.billing_interval);
            document.getElementById('subscriptionPrice').textContent = formatSubscriptionCurrency(subscription.price);
            document.getElementById('subscriptionStartDate').textContent = formatSubscriptionDate(subscription.start_date);
            document.getElementById('subscriptionStatusText').textContent = subscription.status || '-';
            
            // New fields
            const periodStartEl = document.getElementById('subscriptionPeriodStart');
            const nextInvoiceEl = document.getElementById('subscriptionNextInvoice');
            if (periodStartEl) {
                periodStartEl.textContent = subscription.period_start ? formatSubscriptionDate(subscription.period_start) : '-';
            }
            if (nextInvoiceEl) {
                const nextDate = subscription.next_invoice_date ? formatSubscriptionDate(subscription.next_invoice_date) : '-';
                nextInvoiceEl.textContent = nextDate;
                // Highlight if invoice is due soon
                if (subscription.next_invoice_date) {
                    const daysUntil = Math.ceil((new Date(subscription.next_invoice_date) - new Date()) / (1000 * 60 * 60 * 24));
                    if (daysUntil <= 7 && daysUntil >= 0) {
                        nextInvoiceEl.innerHTML = `${nextDate} <span class="badge bg-warning text-dark">Om ${daysUntil} dage</span>`;
                    }
                }
            }

            setSubscriptionBadge(subscription.status);

            const itemsBody = document.getElementById('subscriptionItemsBody');
            const itemsTotal = document.getElementById('subscriptionItemsTotal');
            if (itemsBody) {
                const items = subscription.line_items || [];
                if (!items.length) {
                    itemsBody.innerHTML = '<tr><td colspan="5" class="text-center text-muted">Ingen linjer</td></tr>';
                } else {
                    itemsBody.innerHTML = items.map(item => `
                        <tr>
                            <td>${item.product_name || '-'}</td>
                            <td>${item.description}</td>
                            <td class="text-end">${parseFloat(item.quantity).toFixed(2)}</td>
                            <td class="text-end">${formatSubscriptionCurrency(item.unit_price)}</td>
                            <td class="text-end">${formatSubscriptionCurrency(item.line_total)}</td>
                        </tr>
                    `).join('');
                }
            }
            if (itemsTotal) {
                itemsTotal.textContent = formatSubscriptionCurrency(subscription.price || 0);
            }

            const actions = document.getElementById('subscriptionActions');
            if (!actions) return;

            const buttons = [];
            if (subscription.status === 'draft' || subscription.status === 'paused') {
                buttons.push(`<button class="btn btn-sm btn-success" onclick="updateSubscriptionStatus('active')"><i class="bi bi-play-circle me-1"></i>Aktiver</button>`);
            }
            if (subscription.status === 'active') {
                buttons.push(`<button class="btn btn-sm btn-warning" onclick="updateSubscriptionStatus('paused')"><i class="bi bi-pause-circle me-1"></i>Pause</button>`);
            }
            if (subscription.status !== 'cancelled') {
                buttons.push(`<button class="btn btn-sm btn-outline-danger" onclick="updateSubscriptionStatus('cancelled')"><i class="bi bi-x-circle me-1"></i>Opsig</button>`);
            }
            actions.innerHTML = buttons.join(' ');
        }

        async function loadSubscriptionForCase() {
            try {
                const res = await fetch(`/api/v1/sag-subscriptions/by-sag/${subscriptionCaseId}`);
                if (res.status === 404) {
                    showSubscriptionCreateForm();
                    setModuleContentState('subscription', false);
                    return;
                }
                if (!res.ok) {
                    throw new Error('Kunne ikke hente abonnement');
                }
                const subscription = await res.json();
                renderSubscription(subscription);
                setModuleContentState('subscription', true);
            } catch (e) {
                console.error('Error loading subscription:', e);
                showSubscriptionCreateForm();
                setModuleContentState('subscription', true);
            }
        }

        async function createSubscription() {
            const billingInterval = document.getElementById('subscriptionIntervalInput').value;
            const billingDay = parseInt(document.getElementById('subscriptionBillingDayInput').value, 10);
            const startDate = document.getElementById('subscriptionStartDateInput').value;
            const notes = document.getElementById('subscriptionNotesInput').value.trim();

            const lineItems = collectSubscriptionLineItems();

            if (!billingInterval || !billingDay || !startDate) {
                alert('Udfyld venligst alle paakraevet felter');
                return;
            }
            if (!lineItems.length) {
                alert('Du skal angive mindst en varelinje');
                return;
            }

            try {
                const res = await fetch('/api/v1/sag-subscriptions', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        sag_id: subscriptionCaseId,
                        billing_interval: billingInterval,
                        billing_day: billingDay,
                        start_date: startDate,
                        notes: notes || null,
                        line_items: lineItems
                    })
                });

                if (!res.ok) {
                    const error = await res.json();
                    throw new Error(error.detail || 'Fejl ved oprettelse');
                }

                const subscription = await res.json();
                renderSubscription(subscription);
            } catch (e) {
                alert(e.message || e);
            }
        }

        async function updateSubscriptionStatus(status) {
            if (!currentSubscription) return;
            if (status === 'cancelled' && !confirm('Er du sikker paa, at abonnementet skal opsiges?')) {
                return;
            }

            try {
                const res = await fetch(`/api/v1/sag-subscriptions/${currentSubscription.id}/status`, {
                    method: 'PATCH',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ status })
                });

                if (!res.ok) {
                    const error = await res.json();
                    throw new Error(error.detail || 'Kunne ikke opdatere status');
                }

                const updated = await res.json();
                renderSubscription(updated);
            } catch (e) {
                alert(e.message || e);
            }
        }

        document.addEventListener('DOMContentLoaded', () => {
            loadSubscriptionProducts();
            loadSubscriptionForCase();
        });

        // === Quick Time Entry Functions (for inline time tracking) ===
        function toggleQuickTimeForm() {
            const container = document.getElementById('quickTimeFormContainer');
            if (container) {
                container.classList.remove('d-none');
            }
        }
        
        // Make function globally available for onclick handler
        window.toggleQuickTimeForm = toggleQuickTimeForm;

        async function quickAddTime(event) {
            event.preventDefault();
            
            const form = document.getElementById('quickAddTimeForm');
            const formData = new FormData(form);
            
            // Parse hours and minutes
            const hours = parseInt(formData.get('hours')) || 0;
            const minutes = parseInt(formData.get('minutes')) || 0;
            const totalHours = hours + (minutes / 60);
            
            if (totalHours === 0) {
                alert('Angiv venligst timer eller minutter');
                return;
            }

            const billingSelect = document.getElementById('quickTimeBillingMethod');
            let billingMethod = billingSelect ? billingSelect.value : 'invoice';
            let prepaidCardId = null;
            let fixedPriceAgreementId = null;

            if (billingMethod.startsWith('card_')) {
                prepaidCardId = parseInt(billingMethod.split('_')[1]);
                billingMethod = 'prepaid';
            }

            if (billingMethod.startsWith('fpa_')) {
                fixedPriceAgreementId = parseInt(billingMethod.split('_')[1]);
                billingMethod = 'fixed_price';
            }

            const isInternal = billingMethod === 'internal';
            
            // Build payload
            const payload = {
                sag_id: {{ case.id }},
                worked_date: formData.get('date'),
                original_hours: totalHours,
                description: formData.get('description'),
                billing_method: billingMethod,
                is_internal: isInternal
            };

            if (prepaidCardId) {
                payload.prepaid_card_id = prepaidCardId;
            }

            if (fixedPriceAgreementId) {
                payload.fixed_price_agreement_id = fixedPriceAgreementId;
            }
            
            try {
                const response = await fetch('/api/v1/timetracking/entries/internal', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(payload)
                });
                
                if (!response.ok) {
                    const error = await response.json();
                    throw new Error(error.detail || 'Kunne ikke gemme tidsregistrering');
                }
                
                // Success - reload page to show new entry
                window.location.reload();
            } catch (error) {
                alert('Fejl: ' + error.message);
                console.error('Quick add time error:', error);
            }
        }
        
        // Set today's date as default for quick time form
        document.addEventListener('DOMContentLoaded', function() {
            const dateInput = document.getElementById('quickTimeDate');
            if (dateInput && !dateInput.value) {
                const today = new Date().toISOString().split('T')[0];
                dateInput.value = today;
            }
            // Activate tab from ?tab= URL parameter (used when navigating from relation tree QA menu)
            const tabParam = new URLSearchParams(window.location.search).get('tab');
            if (tabParam) {
                const tabBtn = document.getElementById(tabParam + '-tab')
                    || document.querySelector(`[data-module-tab="${tabParam}"]`);
                if (tabBtn) {
                    setTimeout(() => {
                        bootstrap.Tab.getOrCreateInstance(tabBtn).show();
                        forceCaseTabActivation(tabParam);
                    }, 300);
                }
            }
        });
    