// Partial: _file-viewer.js.j2 — Merged file viewer with markdown rendering toggle

{% if mode == 'edit' %}
// =====================================================================
// File Viewer
// =====================================================================

async function showSource(filePath, lineNumber) {
    const panel = document.getElementById('file-viewer-panel');
    const divider = document.getElementById('divider-right');
    const pathEl = document.getElementById('fv-path');
    const statusEl = document.getElementById('fv-status');
    const body = document.getElementById('fv-body');

    pathEl.textContent = filePath;
    pathEl.title = filePath;
    statusEl.textContent = '';
    statusEl.className = 'fv-status';

    // Show panel and divider
    panel.classList.add('open');
    divider.style.display = '';

    // Show loading state
    body.innerHTML = '<div style="padding:24px;color:#adb5bd;text-align:center;">Loading...</div>';

    try {
        const resp = await fetch('/api/file-content?path=' + encodeURIComponent(filePath));
        if (!resp.ok) {
            const err = await resp.json().catch(function() { return {}; });
            body.innerHTML = '<div style="padding:24px;color:#dc3545;text-align:center;">' +
                escapeHtml(err.error || 'Failed to load file') + '</div>';
            return;
        }
        const data = await resp.json();

        // Update status badge
        if (data.has_pending_mutations) {
            statusEl.textContent = data.pending_mutation_count + ' pending edit' +
                (data.pending_mutation_count !== 1 ? 's' : '');
            statusEl.className = 'fv-status has-mutations';
            statusEl.title = 'Unsaved mutations would modify this file: ' +
                (data.affected_nodes || []).join(', ');
        } else {
            statusEl.textContent = 'on disk';
            statusEl.className = 'fv-status on-disk';
            statusEl.title = 'Showing current file contents from disk';
        }

        // Render lines with line numbers
        var html = '<div class="source-table" role="presentation">';
        var lines = data.lines || [];
        for (var i = 0; i < lines.length; i++) {
            var num = i + 1;
            var cls = 'source-line';
            if (num === lineNumber) cls += ' highlighted';
            html += '<div class="' + cls + '" id="fv-line-' + num + '">' +
                '<span class="line-num">' + num + '</span>' +
                '<span class="line-content">' + escapeHtml(lines[i]) + '</span>' +
                '</div>';
        }
        html += '</div>';
        body.innerHTML = html;

        // Scroll to the target line
        if (lineNumber > 0) {
            var target = document.getElementById('fv-line-' + lineNumber);
            if (target) {
                setTimeout(function() {
                    target.scrollIntoView({ block: 'center', behavior: 'smooth' });
                }, 100);
            }
        }

    } catch (e) {
        body.innerHTML = '<div style="padding:24px;color:#dc3545;text-align:center;">' +
            'Error loading file: ' + escapeHtml(String(e)) + '</div>';
    }
}

function closeFileViewer() {
    document.getElementById('file-viewer-panel').classList.remove('open');
    document.getElementById('divider-right').style.display = 'none';
}

{% else %}
// ─────────────────────────────────────────────────────────────────────────────
// File Viewer Panel
// ─────────────────────────────────────────────────────────────────────────────

function showFile(filePath, lineNumber) {
    const fileData = state.sourceFiles[filePath];
    if (!fileData) {
        // No embedded content for this file
        const panel = document.getElementById('file-viewer-panel');
        const body = document.getElementById('file-viewer-body');
        document.getElementById('file-viewer-path').textContent = filePath.split('/').pop();
        document.getElementById('file-viewer-path').title = filePath;
        document.getElementById('file-viewer-lang').textContent = '';
        document.getElementById('file-viewer-mode-toggle').style.display = 'none';
        body.innerHTML = '<div style="padding:24px;color:#6c757d;text-align:center;">' +
            'File content not available.<br>Regenerate with <code>--embed-content</code> to enable inline viewing.</div>';
        openFileViewer();
        return;
    }

    state.currentFile = filePath;
    const fileName = filePath.split('/').pop();
    const isMarkdown = fileName.endsWith('.md');

    // Update header
    document.getElementById('file-viewer-path').textContent = fileName;
    document.getElementById('file-viewer-path').title = filePath;
    document.getElementById('file-viewer-lang').textContent = fileData.language || '';
    document.getElementById('file-viewer-vscode').href =
        'vscode://file/' + filePath + ':' + (lineNumber || 1) + ':1';

    // Show mode toggle for markdown files
    const modeToggle = document.getElementById('file-viewer-mode-toggle');
    if (isMarkdown) {
        modeToggle.style.display = 'flex';
        state.fileViewMode = 'rendered';
        modeToggle.querySelectorAll('.file-viewer-mode-btn').forEach(btn => {
            btn.classList.toggle('active', btn.dataset.mode === 'rendered');
        });
    } else {
        modeToggle.style.display = 'none';
        state.fileViewMode = 'source';
    }

    // Render file content
    renderFileContent(fileData, lineNumber);
    openFileViewer();
}

function renderFileContent(fileData, lineNumber) {
    const body = document.getElementById('file-viewer-body');

    if (state.fileViewMode === 'rendered' && state.currentFile && state.currentFile.endsWith('.md')) {
        // Rendered markdown view with line numbers
        const rawLines = fileData.raw.split('\n');
        let html = '<div class="source-lines">';
        for (let i = 0; i < rawLines.length; i++) {
            const num = i + 1;
            const renderedLine = renderMarkdown(rawLines[i]);
            html += '<div class="source-line" data-line="' + num + '">' +
                '<span class="line-num">' + num + '</span>' +
                '<div class="line-content rendered-line">' + renderedLine + '</div>' +
                '</div>';
        }
        html += '</div>';
        body.innerHTML = html;
        scrollAndFlashLine(body, lineNumber);
        return;
    }

    // Source view with line numbers and syntax highlighting
    const lines = fileData.lines;
    let html = '<div class="source-lines">';

    for (let i = 0; i < lines.length; i++) {
        const num = i + 1;
        html += '<div class="source-line" data-line="' + num + '">' +
            '<span class="line-num">' + num + '</span>' +
            '<code class="line-content highlight">' + (lines[i] || '') + '</code>' +
            '</div>';
    }
    html += '</div>';
    body.innerHTML = html;
    scrollAndFlashLine(body, lineNumber);
}

function scrollAndFlashLine(container, lineNumber) {
    if (!lineNumber) return;
    setTimeout(function() {
        // Clear any previous highlight
        var prev = container.querySelector('.source-line.highlighted');
        if (prev) {
            prev.classList.remove('highlighted');
            prev.style.backgroundColor = '';
            prev.style.transition = '';
            var prevCells = prev.querySelectorAll('.line-num, .line-content');
            for (var i = 0; i < prevCells.length; i++) {
                prevCells[i].style.backgroundColor = '';
                prevCells[i].style.transition = '';
            }
        }

        var target = container.querySelector('.source-line[data-line="' + lineNumber + '"]');
        if (!target) return;

        target.scrollIntoView({ behavior: 'smooth', block: 'center' });
        target.classList.add('highlighted');

        // Flash after scroll completes — use scrollend event with timeout fallback
        var fired = false;
        function flash() {
            if (fired) return;
            fired = true;
            // Flash child cells directly — table row bg is hidden behind cell bg
            var cells = target.querySelectorAll('.line-num, .line-content');
            for (var i = 0; i < cells.length; i++) {
                cells[i].style.transition = 'none';
                cells[i].style.backgroundColor = '#ffc107';
            }
            setTimeout(function() {
                for (var i = 0; i < cells.length; i++) {
                    cells[i].style.transition = 'background-color 1s ease-out';
                    cells[i].style.backgroundColor = '';
                }
            }, 400);
        }

        // scrollend fires when smooth scroll completes
        container.addEventListener('scrollend', function onScrollEnd() {
            container.removeEventListener('scrollend', onScrollEnd);
            flash();
        });
        // Fallback: if no scroll needed or scrollend unsupported, flash after 800ms
        setTimeout(flash, 800);
    }, 50);
}

function openFileViewer() {
    const panel = document.getElementById('file-viewer-panel');
    const divider = document.getElementById('split-divider');
    panel.classList.add('open');
    divider.style.display = 'block';
    state.fileViewerOpen = true;
    // Apply saved split ratio
    panel.style.width = state.splitRatio + '%';
    saveStateToCookie();
}

function closeFileViewer() {
    const panel = document.getElementById('file-viewer-panel');
    const divider = document.getElementById('split-divider');
    panel.classList.remove('open');
    divider.style.display = 'none';
    state.fileViewerOpen = false;
    state.currentFile = null;
    saveStateToCookie();
}

function setFileViewMode(mode) {
    state.fileViewMode = mode;
    document.querySelectorAll('#file-viewer-mode-toggle .file-viewer-mode-btn').forEach(btn => {
        btn.classList.toggle('active', btn.dataset.mode === mode);
    });

    // Re-render with current file
    if (state.currentFile) {
        const fileData = state.sourceFiles[state.currentFile];
        if (fileData) {
            renderFileContent(fileData, null);
        }
    }
}

function renderMarkdown(text) {
    // Simple markdown to HTML renderer for inline display
    let html = text
        // Escape HTML first
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        // Headers
        .replace(/^### (.+)$/gm, '<h3>$1</h3>')
        .replace(/^## (.+)$/gm, '<h2>$1</h2>')
        .replace(/^# (.+)$/gm, '<h1>$1</h1>')
        // Bold and italic
        .replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>')
        .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
        .replace(/\*(.+?)\*/g, '<em>$1</em>')
        // Inline code
        .replace(/`([^`]+)`/g, '<code>$1</code>')
        // Horizontal rules
        .replace(/^---+$/gm, '<hr>')
        // List items
        .replace(/^- (.+)$/gm, '<li>$1</li>')
        .replace(/^(\d+)\. (.+)$/gm, '<li>$2</li>')
        // Paragraphs (double newline)
        .replace(/\n\n/g, '</p><p>')
        // Single newlines to <br>
        .replace(/\n/g, '<br>');

    return '<p>' + html + '</p>';
}

// ─────────────────────────────────────────────────────────────────────────────
// Intercept File Links
// ─────────────────────────────────────────────────────────────────────────────

function interceptFileLinks() {
    // Only intercept if we have source files embedded
    if (!state.sourceFiles || Object.keys(state.sourceFiles).length === 0) return;

    document.addEventListener('click', function(e) {
        const link = e.target.closest('a[href^="vscode://file/"]');
        if (!link) return;

        e.preventDefault();
        const href = link.getAttribute('href');
        // Parse vscode://file/PATH:LINE:COL
        const match = href.match(/^vscode:\/\/file\/(.+?)(?::(\d+))?(?::(\d+))?$/);
        if (match) {
            const filePath = match[1];
            const lineNum = match[2] ? parseInt(match[2], 10) : 1;
            showFile(filePath, lineNum);
        }
    });
}

{% endif %}
