{% extends "base.html" %}
{% block title %}Debug — Drakkar{% endblock %}

{% block content %}
<!-- ==================== CONFIG SUMMARY ==================== -->
{% if config_summary %}
<div class="mb-6 px-4 py-3 rounded-lg border border-cream-200 font-mono text-xs text-ink-700 break-all select-all" style="background:#f5f3ee;">
    {{ config_summary }}
</div>
{% endif %}

<!-- ==================== METRICS ==================== -->
<div class="mb-8">
    <div class="flex items-center justify-between mb-3">
        <h2 class="text-xl font-bold text-ink-900">Metrics</h2>
        <div class="flex items-center gap-3">
            <label class="text-xs text-gray-500 flex items-center gap-1">
                <input id="metrics-show-user" type="checkbox" checked class="rounded"> User
            </label>
            <label class="text-xs text-gray-500 flex items-center gap-1">
                <input id="metrics-show-framework" type="checkbox" checked class="rounded"> Framework
            </label>
            <button id="metrics-refresh" class="px-3 py-1.5 text-sm rounded border border-cream-300 text-ink-700 hover:bg-cream-100">Refresh</button>
        </div>
    </div>
    <div id="metrics-list">
        <div class="text-gray-500 text-sm">Loading...</div>
    </div>
</div>

<hr class="border-cream-200 mb-6">

<!-- ==================== TRACE ==================== -->
<div class="mb-8">
    <h2 class="text-xl font-bold text-ink-900 mb-3">Message Trace</h2>
    <p class="text-xs text-gray-400 mb-3">Trace a Kafka message by partition:offset through the full pipeline. Falls back to other workers in the same cluster.</p>
    <div class="flex items-center gap-3 mb-4">
        <label class="text-sm text-gray-500">Partition:Offset</label>
        <input id="trace-input" type="text" placeholder="e.g. 5:42" class="bg-white border border-cream-300 rounded px-3 py-1.5 text-sm font-mono text-ink-700 w-40 focus:border-teal-400 focus:outline-none">
        <button id="trace-btn" class="bg-teal-600 hover:bg-teal-500 text-white px-3 py-1.5 rounded text-sm">Trace</button>
        <span id="trace-status" class="text-sm text-gray-400"></span>
    </div>
    <div id="trace-result"></div>
</div>

<hr class="border-cream-200 mb-6">

<!-- ==================== DATABASES ==================== -->
<div class="flex items-center justify-between mb-6">
    <h2 class="text-xl font-bold text-ink-900">Databases</h2>
    <div class="flex items-center gap-3">
        <button id="btn-merge" disabled
                class="px-4 py-2 text-sm font-medium rounded disabled:opacity-40"
                style="background:#2a2a2a;color:white;">
            Merge Selected
        </button>
        <button id="btn-refresh" class="px-3 py-2 text-sm rounded border border-cream-300 text-ink-700 hover:bg-cream-100">
            Refresh
        </button>
    </div>
</div>

<div id="db-list" class="space-y-6">
    <div class="text-gray-500">Loading...</div>
</div>

<!-- merge result banner -->
<div id="merge-result" class="hidden mt-4 p-4 rounded border border-green-300 bg-green-50">
    <div class="flex items-center justify-between">
        <div>
            <span class="font-semibold text-green-800" id="merge-msg"></span>
        </div>
        <a id="merge-download" href="#" class="px-3 py-1 text-sm rounded font-medium"
           style="background:#2a2a2a;color:white;">
            Download
        </a>
    </div>
</div>

<script>
(function() {
    // === Trace ===
    var traceInput = document.getElementById('trace-input');
    var traceBtn = document.getElementById('trace-btn');
    var traceStatus = document.getElementById('trace-status');
    var traceResult = document.getElementById('trace-result');

    var evtColors = {consumed:'#2563eb', arranged:'#0d9488', task_started:'#d97706', task_completed:'#059669', task_failed:'#dc2626', collect_completed:'#7c3aed', produced:'#9333ea', committed:'#6b7280'};

    function fmtTimeMs(ts) { return ts ? new Date(ts * 1000).toISOString().substring(11, 23) : ''; }
    function durColor(d) { return d > 1 ? '#dc2626' : d > 0.1 ? '#d97706' : '#059669'; }

    function loadTrace() {
        var input = traceInput.value.trim();
        var m = input.match(/^(\d+)[:\s/](\d+)$/);
        if (!m) {
            traceStatus.textContent = 'format: partition:offset';
            return;
        }
        var p = m[1], o = m[2];
        history.replaceState(null, '', '#trace/' + p + '/' + o);
        traceStatus.textContent = 'loading...';
        traceResult.textContent = '';

        fetch('/api/debug/trace?partition=' + p + '&offset=' + o)
            .then(function(r) { return r.json(); })
            .then(function(events) {
                traceResult.textContent = '';
                if (!events.length) {
                    var msg = document.createElement('p');
                    msg.className = 'text-gray-400 py-4 text-center';
                    msg.textContent = 'No events found for ' + p + ':' + o + ' in any cluster worker';
                    traceResult.appendChild(msg);
                    traceStatus.textContent = '';
                    return;
                }

                var workerName = events[0].worker_name || '?';
                traceStatus.textContent = events.length + ' events from ' + workerName;

                var table = document.createElement('table');
                table.className = 'w-full text-sm';
                var thead = document.createElement('thead');
                var headTr = document.createElement('tr');
                headTr.className = 'text-left text-gray-400 border-b border-cream-200';
                var cols = ['Time', 'Worker', 'Event', 'Task ID', 'Duration', 'Details'];
                for (var ci = 0; ci < cols.length; ci++) {
                    var th = document.createElement('th');
                    th.className = 'py-2 px-3';
                    th.textContent = cols[ci];
                    headTr.appendChild(th);
                }
                thead.appendChild(headTr);
                table.appendChild(thead);

                var tbody = document.createElement('tbody');
                for (var ei = 0; ei < events.length; ei++) {
                    var ev = events[ei];
                    var tr = document.createElement('tr');
                    tr.className = 'border-b border-cream-100 trace-row';
                    if (ev.task_id) tr.setAttribute('data-task-id', ev.task_id);
                    tr.addEventListener('mouseenter', function() {
                        var tid = this.getAttribute('data-task-id');
                        if (!tid) return;
                        document.querySelectorAll('.trace-row').forEach(function(row) {
                            if (row.getAttribute('data-task-id') === tid) row.style.background = '#e0f2fe';
                            else row.style.background = '';
                        });
                    });
                    tr.addEventListener('mouseleave', function() {
                        document.querySelectorAll('.trace-row').forEach(function(row) { row.style.background = ''; });
                    });

                    // time
                    var td1 = document.createElement('td');
                    td1.className = 'py-2 px-3 text-xs font-mono';
                    td1.textContent = fmtTimeMs(ev.ts);
                    // worker
                    var td2 = document.createElement('td');
                    td2.className = 'py-2 px-3 text-xs font-mono text-gray-500';
                    td2.textContent = ev.worker_name || '?';
                    // event
                    var td3 = document.createElement('td');
                    td3.className = 'py-2 px-3 font-mono text-xs font-semibold';
                    td3.style.color = evtColors[ev.event] || '#6b7280';
                    td3.textContent = ev.event;
                    // task id
                    var td4 = document.createElement('td');
                    td4.className = 'py-2 px-3 font-mono text-xs';
                    if (ev.task_id) {
                        var ta = document.createElement('a');
                        ta.href = '/task/' + encodeURIComponent(ev.task_id.split(':r')[0]);
                        ta.className = 'text-teal-600 hover:underline';
                        ta.textContent = ev.task_id;
                        td4.appendChild(ta);
                    }
                    // duration
                    var td5 = document.createElement('td');
                    td5.className = 'py-2 px-3 font-mono text-xs';
                    if (ev.duration) {
                        td5.style.color = durColor(ev.duration);
                        td5.textContent = ev.duration.toFixed(3) + 's';
                    }
                    // details
                    var td6 = document.createElement('td');
                    td6.className = 'py-2 px-3 text-xs text-gray-500 max-w-lg truncate expandable cursor-pointer';
                    td6.title = 'Click to expand';
                    var details = [];
                    if (ev.args) details.push('args: ' + ev.args);
                    if (ev.exit_code !== null && ev.exit_code !== undefined) details.push('exit: ' + ev.exit_code);
                    if (ev.pid) details.push('pid: ' + ev.pid);
                    if (ev.stdout_size) details.push('stdout: ' + ev.stdout_size + 'b');
                    if (ev.metadata) details.push(ev.metadata);
                    td6.setAttribute('data-full', details.join('\n'));
                    td6.textContent = details.join(' | ');

                    tr.append(td1, td2, td3, td4, td5, td6);
                    tbody.appendChild(tr);
                }
                table.appendChild(tbody);
                traceResult.appendChild(table);
            })
            .catch(function(err) {
                traceStatus.textContent = 'error: ' + err.message;
            });
    }

    traceBtn.onclick = loadTrace;
    traceInput.addEventListener('keydown', function(ev) {
        if (ev.key === 'Enter') loadTrace();
    });

    // === Databases ===
    var listEl = document.getElementById('db-list');
    var mergeBtn = document.getElementById('btn-merge');
    var refreshBtn = document.getElementById('btn-refresh');
    var mergeResult = document.getElementById('merge-result');
    var mergeMsg = document.getElementById('merge-msg');
    var mergeDownload = document.getElementById('merge-download');
    var selected = new Set();

    function updateMergeBtn() {
        mergeBtn.disabled = selected.size < 2;
    }

    function formatSize(bytes) {
        if (bytes < 1024) return bytes + ' B';
        if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
        return (bytes / 1048576).toFixed(1) + ' MB';
    }

    function formatTs(ts) {
        if (!ts) return '-';
        var d = new Date(ts * 1000);
        return d.toISOString().replace('T', ' ').slice(0, 19);
    }

    function makeHeaderRow() {
        var tr = document.createElement('tr');
        tr.className = 'text-left text-gray-500 text-xs border-b border-cream-100';
        var cols = [
            ['', 'px-4 py-2 w-8'],
            ['File', 'px-2 py-2'],
            ['Worker', 'px-2 py-2'],
            ['Events', 'px-2 py-2 text-right'],
            ['First', 'px-2 py-2'],
            ['Last', 'px-2 py-2'],
            ['Size', 'px-2 py-2 text-right'],
            ['', 'px-2 py-2 w-8']
        ];
        cols.forEach(function(c) {
            var th = document.createElement('th');
            th.className = c[1];
            th.textContent = c[0];
            tr.appendChild(th);
        });
        return tr;
    }

    function render(databases) {
        listEl.textContent = '';
        if (!databases.length) {
            var empty = document.createElement('div');
            empty.className = 'text-gray-500 py-8 text-center';
            empty.textContent = 'No database files found';
            listEl.appendChild(empty);
            return;
        }

        // group by cluster
        var groups = {};
        var order = [];
        databases.forEach(function(db) {
            var cluster = db.cluster_name || '';
            if (!(cluster in groups)) {
                groups[cluster] = [];
                order.push(cluster);
            }
            groups[cluster].push(db);
        });
        // sort: named clusters first (alpha), unclustered at end
        order.sort(function(a, b) {
            if (a && !b) return -1;
            if (!a && b) return 1;
            return a.localeCompare(b);
        });

        order.forEach(function(cluster) {
            var panel = document.createElement('div');
            panel.className = 'rounded-lg border border-cream-200 overflow-hidden';
            panel.style.background = '#fff';

            var header = document.createElement('div');
            header.className = 'px-4 py-3 border-b border-cream-200 flex items-center justify-between';
            header.style.background = '#f5f3ee';
            var title = document.createElement('span');
            title.className = 'font-semibold text-ink-800';
            title.textContent = cluster || 'Unclustered';
            header.appendChild(title);

            var selectAll = document.createElement('label');
            selectAll.className = 'text-xs text-gray-500 flex items-center gap-1 cursor-pointer';
            var saCheckbox = document.createElement('input');
            saCheckbox.type = 'checkbox';
            saCheckbox.className = 'rounded';
            saCheckbox.dataset.cluster = cluster;
            saCheckbox.onchange = function() {
                groups[cluster].forEach(function(db) {
                    if (saCheckbox.checked) selected.add(db.filename);
                    else selected.delete(db.filename);
                });
                panel.querySelectorAll('input[data-file]').forEach(function(cb) {
                    cb.checked = saCheckbox.checked;
                });
                updateMergeBtn();
            };
            selectAll.appendChild(saCheckbox);
            selectAll.appendChild(document.createTextNode(' select all'));
            header.appendChild(selectAll);
            panel.appendChild(header);

            var table = document.createElement('table');
            table.className = 'w-full text-sm';
            var thead = document.createElement('thead');
            thead.appendChild(makeHeaderRow());
            table.appendChild(thead);

            var tbody = document.createElement('tbody');
            groups[cluster].forEach(function(db) {
                var tr = document.createElement('tr');
                tr.className = 'border-b border-cream-50 hover:bg-cream-50';

                // checkbox
                var tdCb = document.createElement('td');
                tdCb.className = 'px-4 py-2';
                var cb = document.createElement('input');
                cb.type = 'checkbox';
                cb.className = 'rounded';
                cb.dataset.file = db.filename;
                cb.checked = selected.has(db.filename);
                cb.onchange = function() {
                    if (cb.checked) selected.add(db.filename);
                    else selected.delete(db.filename);
                    updateMergeBtn();
                };
                tdCb.appendChild(cb);
                tr.appendChild(tdCb);

                // filename
                var tdFile = document.createElement('td');
                tdFile.className = 'px-2 py-2 font-mono text-xs';
                tdFile.textContent = db.filename;
                tr.appendChild(tdFile);

                // worker
                var tdWorker = document.createElement('td');
                tdWorker.className = 'px-2 py-2 font-mono text-xs';
                tdWorker.textContent = db.worker_name || '-';
                tr.appendChild(tdWorker);

                // event count (with type breakdown on hover)
                var tdCount = document.createElement('td');
                tdCount.className = 'px-2 py-2 text-right font-mono cursor-default';
                tdCount.textContent = db.event_count.toLocaleString();
                if (db.event_counts && Object.keys(db.event_counts).length) {
                    var parts = [];
                    Object.keys(db.event_counts).sort().forEach(function(k) {
                        parts.push(k + ': ' + db.event_counts[k]);
                    });
                    tdCount.title = parts.join('\n');
                }
                tr.appendChild(tdCount);

                // first/last ts
                var tdFirst = document.createElement('td');
                tdFirst.className = 'px-2 py-2 text-xs text-gray-500';
                tdFirst.textContent = formatTs(db.first_event_ts);
                tr.appendChild(tdFirst);

                var tdLast = document.createElement('td');
                tdLast.className = 'px-2 py-2 text-xs text-gray-500';
                tdLast.textContent = formatTs(db.last_event_ts);
                tr.appendChild(tdLast);

                // size
                var tdSize = document.createElement('td');
                tdSize.className = 'px-2 py-2 text-right text-xs text-gray-500';
                tdSize.textContent = formatSize(db.size_bytes);
                tr.appendChild(tdSize);

                // download icon
                var tdDl = document.createElement('td');
                tdDl.className = 'px-2 py-2';
                var dlLink = document.createElement('a');
                dlLink.href = '/debug/download/' + encodeURIComponent(db.filename);
                dlLink.className = 'text-gray-400 hover:text-ink-700';
                dlLink.title = 'Download';
                dlLink.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>';
                tdDl.appendChild(dlLink);
                tr.appendChild(tdDl);

                tbody.appendChild(tr);
            });
            table.appendChild(tbody);
            panel.appendChild(table);
            listEl.appendChild(panel);
        });
    }

    function loadDatabases() {
        listEl.textContent = '';
        var loading = document.createElement('div');
        loading.className = 'text-gray-500';
        loading.textContent = 'Loading...';
        listEl.appendChild(loading);
        fetch('/api/debug/databases').then(function(r) { return r.json(); }).then(render)
        .catch(function() {
            listEl.textContent = '';
            var err = document.createElement('div');
            err.className = 'text-red-500';
            err.textContent = 'Failed to load databases';
            listEl.appendChild(err);
        });
    }

    refreshBtn.onclick = loadDatabases;

    mergeBtn.onclick = function() {
        if (selected.size < 2) return;
        mergeBtn.disabled = true;
        mergeBtn.textContent = 'Merging...';
        mergeResult.classList.add('hidden');
        fetch('/api/debug/merge', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({filenames: Array.from(selected)})
        }).then(function(r) { return r.json(); }).then(function(data) {
            mergeBtn.textContent = 'Merge Selected';
            updateMergeBtn();
            if (data.error) {
                alert('Merge failed: ' + data.error);
                return;
            }
            mergeMsg.textContent = 'Merged ' + data.event_count + ' events from '
                + data.worker_count + ' workers'
                + (data.cluster_name ? ' (' + data.cluster_name + ')' : '');
            mergeDownload.href = '/debug/download/' + encodeURIComponent(data.filename);
            mergeResult.classList.remove('hidden');
            loadDatabases();
        }).catch(function(err) {
            mergeBtn.textContent = 'Merge Selected';
            updateMergeBtn();
            alert('Merge failed: ' + err);
        });
    };

    // === Metrics ===
    var metricsListEl = document.getElementById('metrics-list');
    var metricsShowUser = document.getElementById('metrics-show-user');
    var metricsShowFramework = document.getElementById('metrics-show-framework');
    var metricsRefreshBtn = document.getElementById('metrics-refresh');
    var metricsData = [];

    var typeColors = {counter:'#2563eb', gauge:'#059669', histogram:'#d97706', info:'#7c3aed', summary:'#9333ea'};
    var sourceColors = {framework:'#6b7280', user:'#0d9488'};

    function fmtVal(v) {
        if (v === 0) return '0';
        if (v >= 1e6) return (v / 1e6).toFixed(1) + 'M';
        if (v >= 1e3) return (v / 1e3).toFixed(1) + 'K';
        if (Number.isInteger(v)) return v.toString();
        return v < 0.01 ? v.toExponential(2) : v.toFixed(3);
    }

    function renderMetrics() {
        metricsListEl.textContent = '';
        var showUser = metricsShowUser.checked;
        var showFw = metricsShowFramework.checked;
        var filtered = metricsData.filter(function(m) {
            if (m.source === 'user' && !showUser) return false;
            if (m.source === 'framework' && !showFw) return false;
            return true;
        });

        if (!filtered.length) {
            var empty = document.createElement('div');
            empty.className = 'text-gray-500 text-sm py-4 text-center';
            empty.textContent = metricsData.length ? 'All metrics hidden by filters' : 'No metrics registered';
            metricsListEl.appendChild(empty);
            return;
        }

        // group by source
        var groups = {user: [], framework: []};
        filtered.forEach(function(m) { groups[m.source].push(m); });

        ['user', 'framework'].forEach(function(source) {
            var items = groups[source];
            if (!items.length) return;

            var section = document.createElement('div');
            section.className = 'mb-4';

            var hdr = document.createElement('div');
            hdr.className = 'text-xs font-semibold uppercase tracking-wide mb-2';
            hdr.style.color = sourceColors[source];
            hdr.textContent = source + ' metrics (' + items.length + ')';
            section.appendChild(hdr);

            var table = document.createElement('table');
            table.className = 'w-full text-sm';
            var thead = document.createElement('thead');
            var headTr = document.createElement('tr');
            headTr.className = 'text-left text-gray-400 text-xs border-b border-cream-200';
            ['Name', 'Type', 'Description', 'Values'].forEach(function(col) {
                var th = document.createElement('th');
                th.className = 'py-2 px-3';
                th.textContent = col;
                headTr.appendChild(th);
            });
            thead.appendChild(headTr);
            table.appendChild(thead);

            var tbody = document.createElement('tbody');
            items.forEach(function(m) {
                var tr = document.createElement('tr');
                tr.className = 'border-b border-cream-50 hover:bg-cream-50';

                var tdName = document.createElement('td');
                tdName.className = 'py-2 px-3 font-mono text-xs';
                tdName.textContent = m.name;

                var tdType = document.createElement('td');
                tdType.className = 'py-2 px-3 text-xs font-semibold';
                tdType.style.color = typeColors[m.type] || '#6b7280';
                tdType.textContent = m.type;

                var tdHelp = document.createElement('td');
                tdHelp.className = 'py-2 px-3 text-xs text-gray-500 max-w-xs truncate';
                tdHelp.title = m.help;
                tdHelp.textContent = m.help;

                var tdVals = document.createElement('td');
                tdVals.className = 'py-2 px-3 font-mono text-xs';
                if (!m.samples.length) {
                    tdVals.textContent = '-';
                } else if (m.samples.length === 1 && !Object.keys(m.samples[0].labels).length) {
                    tdVals.textContent = fmtVal(m.samples[0].value);
                } else {
                    m.samples.forEach(function(s) {
                        var line = document.createElement('div');
                        var lblStr = Object.keys(s.labels).map(function(k) { return k + '=' + s.labels[k]; }).join(',');
                        var suffix = s.name.replace(m.name, '').replace(/^_/, '');
                        var prefix = '';
                        if (suffix) prefix = suffix + ' ';
                        if (lblStr) prefix += '{' + lblStr + '} ';
                        line.textContent = prefix + fmtVal(s.value);
                        tdVals.appendChild(line);
                    });
                }

                tr.append(tdName, tdType, tdHelp, tdVals);
                tbody.appendChild(tr);
            });
            table.appendChild(tbody);
            section.appendChild(table);
            metricsListEl.appendChild(section);
        });
    }

    function loadMetrics() {
        fetch('/api/debug/metrics').then(function(r) { return r.json(); }).then(function(data) {
            metricsData = data;
            renderMetrics();
        }).catch(function() {
            metricsListEl.textContent = '';
            var err = document.createElement('div');
            err.className = 'text-red-500 text-sm';
            err.textContent = 'Failed to load metrics';
            metricsListEl.appendChild(err);
        });
    }

    metricsRefreshBtn.onclick = loadMetrics;
    metricsShowUser.onchange = renderMetrics;
    metricsShowFramework.onchange = renderMetrics;

    // === Boot ===
    loadMetrics();
    loadDatabases();

    // Handle #trace/P/O deep links
    function initFromHash() {
        var hash = location.hash.slice(1);
        if (hash.startsWith('trace/')) {
            var parts = hash.split('/');
            if (parts.length >= 3) {
                traceInput.value = parts[1] + ':' + parts[2];
                loadTrace();
            }
        }
    }
    initFromHash();
    window.addEventListener('hashchange', initFromHash);
})();
</script>
{% endblock %}
