// Implements: REQ-p00006-B
// Partial: _card-stack.js.j2 — Card rendering, open/close

// =====================================================================
// Card Stack — Unified for all node kinds
// =====================================================================

async function openCard(nodeId) {
    // If already open, just focus it
    if (editState.openCards.has(nodeId)) {
        focusCard(nodeId);
        return;
    }

    // Fetch node data via generic endpoint
    const data = await apiFetch('/api/node/' + encodeURIComponent(nodeId));
    if (!data) return;

    // Store in state with kind from response
    editState.openCards.set(nodeId, { data: data, collapsed: false, kind: data.kind });

    // Add to front of order
    editState.openCardOrder = editState.openCardOrder.filter(function(id) { return id !== nodeId; });
    editState.openCardOrder.unshift(nodeId);

    renderCardStack();
    // Prefetch coverage data so buttons are colored immediately
    if (data.kind === 'requirement') { prefetchCoverage(nodeId); }
    focusCard(nodeId);
    updateNavSelection();
    saveState();
}

function closeCard(nodeId) {
    editState.openCards.delete(nodeId);
    editState.openCardOrder = editState.openCardOrder.filter(function(id) { return id !== nodeId; });
    renderCardStack();
    updateNavSelection();
    saveState();
}

function focusCard(nodeId) {
    // Move to front of order
    editState.openCardOrder = editState.openCardOrder.filter(function(id) { return id !== nodeId; });
    editState.openCardOrder.unshift(nodeId);

    // Remove focused class from all, add to target
    document.querySelectorAll('.req-card').forEach(function(c) { c.classList.remove('focused'); });
    const card = document.getElementById('card-' + nodeId);
    if (card) {
        card.classList.add('focused');
        card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
    }

    renderCardStack();
    saveState();
}

function toggleCardCollapse(nodeId) {
    const info = editState.openCards.get(nodeId);
    if (!info) return;
    info.collapsed = !info.collapsed;
    const card = document.getElementById('card-' + nodeId);
    if (card) {
        card.classList.toggle('collapsed', info.collapsed);
    }
    saveState();
}

function closeAllCards() {
    editState.openCards.clear();
    editState.openCardOrder = [];
    renderCardStack();
    updateNavSelection();
    saveState();
}

function renderCardStack() {
    const body = document.getElementById('card-stack-body');
    const empty = document.getElementById('card-stack-empty');
    const countEl = document.getElementById('card-stack-count');

    if (editState.openCardOrder.length === 0) {
        body.innerHTML = '';
        body.appendChild(empty);
        empty.style.display = 'flex';
        countEl.textContent = 'No cards open';
        return;
    }

    empty.style.display = 'none';
    countEl.textContent = editState.openCardOrder.length + ' card' +
        (editState.openCardOrder.length !== 1 ? 's' : '') + ' open';

    let html = '';
    editState.openCardOrder.forEach(function(nodeId) {
        const info = editState.openCards.get(nodeId);
        if (!info) return;
        var kind = info.kind || 'requirement';
        if (kind === 'journey') {
            html += buildJourneyCardHtml(nodeId, info.data, info.collapsed);
        } else if (kind === 'requirement') {
            html += buildCardHtml(nodeId, info.data, info.collapsed);
        } else {
            html += buildGenericCardHtml(nodeId, info.data, info.collapsed);
        }
    });

    body.innerHTML = html;

    // Re-add empty element (hidden) for later
    body.appendChild(empty);

    // Re-apply cached coverage colors after DOM rebuild
    recolorCachedButtons();
}

function buildCardHtml(nodeId, data, collapsed) {
    const collapsedClass = collapsed ? ' collapsed' : '';
    const focusedClass = editState.openCardOrder[0] === nodeId ? ' focused' : '';
    const shortId = nodeId.replace('REQ-', '');
    const title = escapeHtml(data.title || '');
    var props = data.properties || {};
    const level = (props.level || '').toUpperCase();
    const status = (props.status || '').toLowerCase();
    const statusDisplay = status.charAt(0).toUpperCase() + status.slice(1);
    const hash = props.hash || '';
    const sourcePath = (data.source && data.source.path) || '';
    const sourceLine = (data.source && data.source.line) || 0;

    let html = '<div class="req-card' + collapsedClass + focusedClass + '" id="card-' + nodeId + '">';

    // Header
    html += '<div class="req-card-header" onclick="toggleCardCollapse(\'' + nodeId + '\')">';
    html += '<span class="req-card-expand">&#9660;</span>';
    html += '<span class="req-card-id">' + shortId + '</span>';
    html += '<span class="req-card-title-display">' + title + '</span>';
    html += '<button class="req-card-close" onclick="event.stopPropagation(); closeCard(\'' + nodeId + '\')" title="Close card">&times;</button>';
    html += '</div>';

    // Body
    html += '<div class="req-card-body">';

    // Metadata section
    html += '<div class="card-section"><div class="card-section-label">Metadata</div>';
    html += '<div class="card-meta">';

    // Level
    html += '<div class="card-meta-item">';
    html += '<span class="card-meta-key">Level:</span>';
    html += '<span class="card-meta-value">' + level + '</span>';
    html += '</div>';

    // Status (badge or select)
    html += '<div class="card-meta-item">';
    html += '<span class="card-meta-key">Status:</span>';
    html += '<span class="status-badge-wrapper"><span class="status-badge ' + status + '">' + statusDisplay + '</span></span>';
    html += '<span class="status-select-wrapper edit-only">';
    html += '<select class="status-select" data-node-id="' + nodeId + '" data-original="' + status + '" onchange="onStatusChange(this)">';
    ['Active', 'Draft', 'Deprecated', 'Proposed'].forEach(function(s) {
        const sel = s.toLowerCase() === status ? ' selected' : '';
        html += '<option value="' + s + '"' + sel + '>' + s + '</option>';
    });
    html += '</select></span>';
    html += '</div>';

    // Hash
    html += '<div class="card-meta-item">';
    html += '<span class="card-meta-key">Hash:</span>';
    html += '<span class="card-meta-value" style="font-family:monospace;font-size:0.75rem;">' + hash + '</span>';
    html += '</div>';

    // Source
    if (sourcePath) {
        html += '<div class="card-meta-item">';
        html += '<span class="card-meta-key">Source:</span>';
        html += '<a class="card-meta-value" href="#" onclick="event.preventDefault(); showSource(\'' +
            escapeHtml(sourcePath) + '\', ' + sourceLine + ')" ' +
            'style="color:#0d6efd;cursor:pointer;font-size:0.75rem;text-decoration:none;">' +
            escapeHtml(sourcePath.split('/').pop()) + ':' + sourceLine + '</a>';
        html += '</div>';
    }

    html += '</div></div>';

    // Editable Title (edit mode only, replaces header title on blur)
    html += '<div class="card-section edit-only" style="display:none;"><div class="card-section-label">Title</div>';
    html += '<div class="editable-field" contenteditable="true" data-node-id="' + nodeId + '" ' +
        'data-field="title" data-original="' + escapeAttr(data.title || '') + '" ' +
        'onblur="onTitleBlur(this)" onkeydown="onEditableKeydown(event)">' +
        escapeHtml(data.title || '') + '</div>';
    html += '</div>';

    // Parents section
    if (data.parents && data.parents.length > 0) {
        html += '<div class="card-section"><div class="card-section-label">Implements / Refines</div>';
        html += '<div class="card-parents">';
        data.parents.forEach(function(p) {
            const edgeKind = (p.edge_kind || 'implements').toUpperCase();
            html += '<a class="card-parent-link" href="#" onclick="event.preventDefault(); openCard(\'' + p.id + '\')">';
            html += '<span class="card-parent-kind">' + edgeKind + '</span> ';
            html += p.id.replace('REQ-', '') + ' - ' + escapeHtml(p.title || '');
            html += '</a>';
        });
        html += '</div></div>';
    }

    // Assertions section
    const assertions = (data.children || []).filter(function(c) { return c.kind === 'assertion'; });
    if (assertions.length > 0) {
        html += '<div class="card-section"><div class="card-section-label">Assertions (' + assertions.length + ')</div>';
        html += '<div class="card-assertions">';
        assertions.forEach(function(a) {
            const assertionId = a.id || '';
            const label = a.label || '';
            const text = a.text || '';
            html += '<div class="card-assertion-wrapper" data-assertion-id="' + assertionId + '">';
            html += '<div class="card-assertion">';
            html += '<span class="card-assertion-label">' + label + '</span>';
            html += '<span class="card-assertion-text editable-field" ' +
                'contenteditable="false" data-assertion-id="' + assertionId + '" ' +
                'data-field="assertion" data-original="' + escapeAttr(text) + '" ' +
                'onblur="onAssertionBlur(this)" onkeydown="onEditableKeydown(event)">' +
                escapeHtml(text) + '</span>';
            html += '<button class="assertion-implemented-btn" ' +
                'data-req-id="' + nodeId + '" data-label="' + escapeAttr(label) + '" ' +
                'onclick="event.stopPropagation(); toggleAssertionCode(this, \'' + nodeId + '\', \'' + escapeAttr(label) + '\')">' +
                'Implemented</button>';
            html += '<button class="assertion-validation-btn" ' +
                'data-req-id="' + nodeId + '" data-label="' + escapeAttr(label) + '" ' +
                'onclick="event.stopPropagation(); toggleAssertionTests(this, \'' + nodeId + '\', \'' + escapeAttr(label) + '\')">' +
                'Validation</button>';
            html += '</div>';
            html += '<div class="assertion-code-panel" id="assertion-code-' + nodeId + '-' + label + '" style="display:none;"></div>';
            html += '<div class="assertion-tests-panel" id="assertion-tests-' + nodeId + '-' + label + '" style="display:none;"></div>';
            html += '</div>';
        });
        html += '</div>';

        // Add assertion button (edit mode only)
        html += '<button class="card-add-assertion-btn edit-only" onclick="onAddAssertion(\'' + nodeId + '\')" style="display:none;">+ Add Assertion</button>';
        html += '</div>';
    } else {
        html += '<div class="card-section"><div class="card-section-label">Assertions</div>';
        html += '<div style="font-size:0.8rem;color:#adb5bd;">No assertions defined</div>';
        html += '<button class="card-add-assertion-btn edit-only" onclick="onAddAssertion(\'' + nodeId + '\')" style="display:none;">+ Add Assertion</button>';
        html += '</div>';
    }

    // Children (requirements only)
    const childReqs = (data.children || []).filter(function(c) {
        return c.kind === 'requirement';
    });
    if (childReqs.length > 0) {
        html += '<div class="card-section"><div class="card-section-label">Children (' + childReqs.length + ')</div>';
        html += '<div class="card-children">';
        childReqs.forEach(function(c) {
            html += '<a class="card-child-link" href="#" onclick="event.preventDefault(); openCard(\'' + c.id + '\')">';
            html += c.id.replace('REQ-', '');
            if (c.title) html += ' - ' + escapeHtml(c.title);
            html += '</a>';
        });
        html += '</div></div>';
    }

    html += '</div>'; // end req-card-body
    html += '</div>'; // end req-card

    return html;
}

function updateNavSelection() {
    document.querySelectorAll('.nav-tree-row').forEach(function(row) {
        row.classList.toggle('selected', editState.openCards.has(row.dataset.id));
    });
}

// =====================================================================
// Journey Cards — reads from generic /api/node/ response
// =====================================================================

function buildJourneyCardHtml(nodeId, data, collapsed) {
    var collapsedClass = collapsed ? ' collapsed' : '';
    var focusedClass = editState.openCardOrder[0] === nodeId ? ' focused' : '';
    var title = escapeHtml(data.title || '');
    var shortId = escapeHtml(data.id || nodeId);
    var props = data.properties || {};
    var sourcePath = (data.source && data.source.path) || '';
    var sourceLine = (data.source && data.source.line) || 1;

    var html = '<div class="req-card journey-card' + collapsedClass + focusedClass + '" id="card-' + nodeId + '">';

    // Header
    html += '<div class="req-card-header" onclick="toggleCardCollapse(\'' + nodeId + '\')">';
    html += '<span class="req-card-expand">&#9660;</span>';
    html += '<span class="journey-card-kind">JNY</span>';
    html += '<span class="req-card-title-display">' + title + '</span>';
    html += '<button class="req-card-close" onclick="event.stopPropagation(); closeCard(\'' + nodeId + '\')" title="Close card">&times;</button>';
    html += '</div>';

    // Body
    html += '<div class="req-card-body">';

    // Metadata section
    html += '<div class="card-section"><div class="card-section-label">Journey Metadata</div>';
    html += '<div class="card-meta">';

    if (props.actor) {
        html += '<div class="card-meta-item">';
        html += '<span class="card-meta-key">Actor:</span>';
        html += '<span class="card-meta-value">' + escapeHtml(props.actor) + '</span>';
        html += '</div>';
    }

    if (props.goal) {
        html += '<div class="card-meta-item">';
        html += '<span class="card-meta-key">Goal:</span>';
        html += '<span class="card-meta-value">' + escapeHtml(props.goal) + '</span>';
        html += '</div>';
    }

    if (props.descriptor) {
        html += '<div class="card-meta-item">';
        html += '<span class="card-meta-key">Topic:</span>';
        html += '<span class="card-meta-value">' + escapeHtml(props.descriptor) + '</span>';
        html += '</div>';
    }

    if (sourcePath) {
        html += '<div class="card-meta-item">';
        html += '<span class="card-meta-key">Source:</span>';
        html += '<a class="card-meta-value" href="#" onclick="event.preventDefault(); showSource(\'' +
            escapeHtml(sourcePath) + '\', ' + sourceLine + ')" ' +
            'style="color:#0d6efd;cursor:pointer;font-size:0.75rem;text-decoration:none;">' +
            escapeHtml(sourcePath.split('/').pop()) + '</a>';
        html += '</div>';
    }

    html += '</div></div>';

    // Referenced Requirements (from links array — ADDRESSES edges)
    var refs = (data.links || []).filter(function(l) { return l.edge_kind === 'addresses'; });
    if (refs.length > 0) {
        html += '<div class="card-section"><div class="card-section-label">Addresses (' + refs.length + ')</div>';
        html += '<div class="card-parents">';
        refs.forEach(function(link) {
            html += '<a class="card-parent-link" href="#" onclick="event.preventDefault(); openCard(\'' + link.id + '\')">';
            html += link.id.replace('REQ-', '');
            if (link.title) html += ' - ' + escapeHtml(link.title);
            html += '</a>';
        });
        html += '</div></div>';
    }

    // Journey body (full text with steps)
    if (props.description) {
        html += '<div class="card-section"><div class="card-section-label">Journey Body</div>';
        html += '<div class="journey-card-description">' + simpleMarkdown(props.description) + '</div>';
        html += '</div>';
    }

    html += '</div>'; // end req-card-body
    html += '</div>'; // end req-card

    return html;
}

// =====================================================================
// Generic Card — fallback for TEST, CODE, TEST_RESULT, etc.
// =====================================================================

function buildGenericCardHtml(nodeId, data, collapsed) {
    var collapsedClass = collapsed ? ' collapsed' : '';
    var focusedClass = editState.openCardOrder[0] === nodeId ? ' focused' : '';
    var title = escapeHtml(data.title || nodeId);
    var kind = data.kind || 'unknown';
    var kindLabel = kind.charAt(0).toUpperCase() + kind.slice(1);
    var props = data.properties || {};
    var sourcePath = (data.source && data.source.path) || '';
    var sourceLine = (data.source && data.source.line) || 0;

    var html = '<div class="req-card' + collapsedClass + focusedClass + '" id="card-' + nodeId + '">';

    // Header
    html += '<div class="req-card-header" onclick="toggleCardCollapse(\'' + nodeId + '\')">';
    html += '<span class="req-card-expand">&#9660;</span>';
    html += '<span class="journey-card-kind">' + escapeHtml(kindLabel) + '</span>';
    html += '<span class="req-card-title-display">' + title + '</span>';
    html += '<button class="req-card-close" onclick="event.stopPropagation(); closeCard(\'' + nodeId + '\')" title="Close card">&times;</button>';
    html += '</div>';

    // Body
    html += '<div class="req-card-body">';

    // Source
    if (sourcePath) {
        html += '<div class="card-section"><div class="card-section-label">Source</div>';
        html += '<div class="card-meta"><div class="card-meta-item">';
        html += '<a class="card-meta-value" href="#" onclick="event.preventDefault(); showSource(\'' +
            escapeHtml(sourcePath) + '\', ' + sourceLine + ')" ' +
            'style="color:#0d6efd;cursor:pointer;font-size:0.75rem;text-decoration:none;">' +
            escapeHtml(sourcePath.split('/').pop()) + ':' + sourceLine + '</a>';
        html += '</div></div></div>';
    }

    // Properties as key-value pairs
    var propKeys = Object.keys(props);
    if (propKeys.length > 0) {
        html += '<div class="card-section"><div class="card-section-label">Properties</div>';
        html += '<div class="card-meta">';
        propKeys.forEach(function(key) {
            var val = props[key];
            if (val === null || val === undefined || val === '') return;
            html += '<div class="card-meta-item">';
            html += '<span class="card-meta-key">' + escapeHtml(key) + ':</span>';
            html += '<span class="card-meta-value">' + escapeHtml(String(val)) + '</span>';
            html += '</div>';
        });
        html += '</div></div>';
    }

    // Links
    var links = data.links || [];
    if (links.length > 0) {
        html += '<div class="card-section"><div class="card-section-label">Links (' + links.length + ')</div>';
        html += '<div class="card-parents">';
        links.forEach(function(link) {
            html += '<a class="card-parent-link" href="#" onclick="event.preventDefault(); openCard(\'' + link.id + '\')">';
            html += '<span class="card-parent-kind">' + escapeHtml(link.edge_kind || '') + '</span> ';
            html += escapeHtml(link.id);
            if (link.title) html += ' - ' + escapeHtml(link.title);
            html += '</a>';
        });
        html += '</div></div>';
    }

    html += '</div>'; // end req-card-body
    html += '</div>'; // end req-card

    return html;
}

// =====================================================================
// Simple Markdown Renderer (for journey body text)
// =====================================================================

function simpleMarkdown(text) {
    // Escape HTML first, then add minimal formatting
    var lines = text.split('\n');
    var result = [];
    for (var i = 0; i < lines.length; i++) {
        var line = escapeHtml(lines[i]);
        // Bold: **text**
        line = line.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
        // Headers: ## text -> bold
        line = line.replace(/^(#{1,3})\s+(.+)$/, '<strong>$2</strong>');
        // Numbered steps: 1. text
        line = line.replace(/^(\d+)\.\s+/, '<strong>$1.</strong> ');
        // Bullet items: - text
        line = line.replace(/^(\s*)-\s+/, '$1&bull; ');
        result.push(line);
    }
    return result.join('\n');
}

// =====================================================================
// Coverage Prefetch — color buttons on card open
// =====================================================================

async function prefetchCoverage(nodeId) {
    var testData = assertionTestsCache[nodeId]
        ? Promise.resolve(assertionTestsCache[nodeId])
        : apiFetch('/api/test-coverage/' + encodeURIComponent(nodeId));
    var codeData = assertionCodeCache[nodeId]
        ? Promise.resolve(assertionCodeCache[nodeId])
        : apiFetch('/api/code-coverage/' + encodeURIComponent(nodeId));

    var results = await Promise.all([testData, codeData]);

    if (results[0] && results[0].success) {
        assertionTestsCache[nodeId] = results[0];
    }
    if (results[1] && results[1].success) {
        assertionCodeCache[nodeId] = results[1];
    }
    // Re-apply all cached colors (covers this card + any others in the DOM)
    recolorCachedButtons();
}

function recolorCachedButtons() {
    for (var reqId in assertionTestsCache) {
        updateAllValidationButtons(reqId, assertionTestsCache[reqId]);
    }
    for (var reqId in assertionCodeCache) {
        updateAllImplementedButtons(reqId, assertionCodeCache[reqId]);
    }
}

// =====================================================================
// Assertion Validation — Test Coverage Buttons
// =====================================================================

var assertionTestsCache = {};

async function toggleAssertionTests(btn, reqId, label) {
    var panelId = 'assertion-tests-' + reqId + '-' + label;
    var panel = document.getElementById(panelId);
    if (!panel) return;

    // Toggle visibility
    if (panel.style.display !== 'none') {
        panel.style.display = 'none';
        btn.classList.remove('active');
        return;
    }

    panel.style.display = 'block';
    btn.classList.add('active');

    // Fetch data if not cached
    if (!assertionTestsCache[reqId]) {
        panel.innerHTML = '<div class="assertion-tests-loading">Loading...</div>';
        var data = await apiFetch('/api/test-coverage/' + encodeURIComponent(reqId));
        if (!data || !data.success) {
            panel.innerHTML = '<div class="assertion-tests-loading">Failed to load coverage data</div>';
            return;
        }
        assertionTestsCache[reqId] = data;
        // Update ALL validation buttons for this requirement
        updateAllValidationButtons(reqId, data);
    }

    renderAssertionTests(panel, reqId, label, assertionTestsCache[reqId]);
}

function renderAssertionTests(panel, reqId, label, data) {
    var assertionData = data.assertion_tests[label];
    if (!assertionData) {
        panel.innerHTML = '<div class="assertion-tests-empty">No data for this assertion</div>';
        return;
    }

    var tests = assertionData.tests;
    if (tests.length === 0) {
        panel.innerHTML = '<div class="assertion-tests-empty">No tests cover this assertion</div>';
        return;
    }

    var html = '';
    for (var i = 0; i < tests.length; i++) {
        var t = tests[i];
        var statusIcon = '';
        var statusClass = '';
        // Determine overall status from results
        var hasResults = t.results && t.results.length > 0;
        if (hasResults) {
            var allPassed = t.results.every(function(r) { return r.status === 'passed'; });
            var anyFailed = t.results.some(function(r) { return r.status === 'failed' || r.status === 'failure' || r.status === 'error'; });
            if (allPassed) { statusIcon = '&#x2705;'; statusClass = 'test-passed'; }
            else if (anyFailed) { statusIcon = '&#x274C;'; statusClass = 'test-failed'; }
            else { statusIcon = '&#x2753;'; statusClass = ''; }
        } else {
            statusIcon = '&#x2796;'; statusClass = 'test-no-result';
        }

        var testLabel = escapeHtml(t.label || t.id);

        html += '<div class="assertion-test-item ' + statusClass + '">';
        html += '<span class="assertion-test-icon">' + statusIcon + '</span>';
        if (t.file) {
            html += '<a class="assertion-test-link" href="#" onclick="event.preventDefault(); showSource(\'' +
                escapeHtml(t.file) + '\', ' + (t.line || 0) + ')">' + testLabel + '</a>';
        } else {
            html += '<span class="assertion-test-link">' + testLabel + '</span>';
        }
        // Result file link (e.g., test-results.xml)
        if (hasResults && t.results[0].file) {
            html += ' <a class="assertion-result-file-link" href="#" onclick="event.preventDefault(); showSource(\'' +
                escapeHtml(t.results[0].file) + '\', ' + (t.results[0].line || 0) +
                ')" title="View result in ' + escapeHtml(t.results[0].file) + '">[result]</a>';
        }
        html += '</div>';
    }
    panel.innerHTML = html;
}

function updateAllValidationButtons(reqId, data) {
    var buttons = document.querySelectorAll('.assertion-validation-btn[data-req-id="' + reqId + '"]');
    for (var i = 0; i < buttons.length; i++) {
        var btn = buttons[i];
        var label = btn.dataset.label;
        var assertionData = data.assertion_tests[label];
        if (!assertionData) continue;

        // Remove previous state classes
        btn.classList.remove('validation-pass', 'validation-partial', 'validation-fail', 'validation-unknown');

        var tests = assertionData.tests;
        if (tests.length === 0) {
            btn.classList.add('validation-fail');
            continue;
        }

        // Collect all results across all tests for this assertion
        var allResults = [];
        for (var j = 0; j < tests.length; j++) {
            if (tests[j].results) {
                for (var k = 0; k < tests[j].results.length; k++) {
                    allResults.push(tests[j].results[k].status);
                }
            }
        }

        if (allResults.length === 0) {
            // Tests exist but no results loaded — tests ARE coverage
            btn.classList.add('validation-pass');
        } else {
            var allPassed = allResults.every(function(s) { return s === 'passed'; });
            var anyFailed = allResults.some(function(s) { return s === 'failed' || s === 'failure' || s === 'error'; });
            if (allPassed) {
                btn.classList.add('validation-pass');
            } else if (anyFailed) {
                btn.classList.add('validation-partial');
            } else {
                // Unknown statuses (skipped, etc.) — still covered
                btn.classList.add('validation-pass');
            }
        }
    }
}

// =====================================================================
// Assertion Implementation — Code Coverage Buttons
// =====================================================================

var assertionCodeCache = {};

async function toggleAssertionCode(btn, reqId, label) {
    var panelId = 'assertion-code-' + reqId + '-' + label;
    var panel = document.getElementById(panelId);
    if (!panel) return;

    // Toggle visibility
    if (panel.style.display !== 'none') {
        panel.style.display = 'none';
        btn.classList.remove('active');
        return;
    }

    panel.style.display = 'block';
    btn.classList.add('active');

    // Fetch data if not cached
    if (!assertionCodeCache[reqId]) {
        panel.innerHTML = '<div class="assertion-tests-loading">Loading...</div>';
        var data = await apiFetch('/api/code-coverage/' + encodeURIComponent(reqId));
        if (!data || !data.success) {
            panel.innerHTML = '<div class="assertion-tests-loading">Failed to load implementation data</div>';
            return;
        }
        assertionCodeCache[reqId] = data;
        // Update ALL implemented buttons for this requirement
        updateAllImplementedButtons(reqId, data);
    }

    renderAssertionCode(panel, reqId, label, assertionCodeCache[reqId]);
}

function renderAssertionCode(panel, reqId, label, data) {
    var assertionData = data.assertion_code[label];
    if (!assertionData) {
        panel.innerHTML = '<div class="assertion-tests-empty">No data for this assertion</div>';
        return;
    }

    var codeRefs = assertionData.code_refs;
    if (codeRefs.length === 0) {
        panel.innerHTML = '<div class="assertion-tests-empty">No code implements this assertion</div>';
        return;
    }

    var html = '';
    for (var i = 0; i < codeRefs.length; i++) {
        var c = codeRefs[i];
        // Extract short filename from full path
        var fileName = c.file ? c.file.split('/').pop() : c.id;

        html += '<div class="assertion-test-item">';
        html += '<span class="assertion-test-icon">&#x1F4C4;</span>';
        if (c.file) {
            html += '<a class="assertion-test-link" href="#" onclick="event.preventDefault(); showSource(\'' +
                escapeHtml(c.file) + '\', ' + (c.line || 0) + ')">' +
                escapeHtml(fileName) + ':' + (c.line || 1) + '</a>';
        } else {
            html += '<span class="assertion-test-link">' + escapeHtml(c.label || c.id) + '</span>';
        }
        html += '</div>';
    }
    panel.innerHTML = html;
}

function updateAllImplementedButtons(reqId, data) {
    var buttons = document.querySelectorAll('.assertion-implemented-btn[data-req-id="' + reqId + '"]');
    for (var i = 0; i < buttons.length; i++) {
        var btn = buttons[i];
        var label = btn.dataset.label;
        var assertionData = data.assertion_code[label];
        if (!assertionData) continue;

        // Remove previous state classes
        btn.classList.remove('implemented-yes', 'implemented-no');

        var codeRefs = assertionData.code_refs;
        if (codeRefs.length > 0) {
            btn.classList.add('implemented-yes');
        } else {
            btn.classList.add('implemented-no');
        }
    }
}
