{{define "monitoring"}}
{{template "layout_start" .}}

<div class="page-header">
    <h2>Rendszermonitor</h2>
</div>

<!-- Section 0: Host (Proxmox box) health — slice 9, served by the host agent over the local API.
     The de-privileged controller can't read the host itself; this card shows the real box. -->
<div class="monitor-card" id="host-health-card">
    <div class="monitor-card-header">
        <h3>Szerver állapota (gazdagép)</h3>
        <span class="sysinfo-value" id="host-health-updated" style="font-size:.75rem;color:var(--text-3)"></span>
    </div>
    <div id="host-health-unavailable" class="monitoring-banner monitoring-banner-yellow" style="display:none">
        A gazdagép metrikái jelenleg nem elérhetők.
    </div>
    <div id="host-health-body" style="display:none">
        <div class="sysinfo-grid">
            <div class="sysinfo-row">
                <span class="sysinfo-label">CPU használat</span>
                <span class="sysinfo-value" id="host-cpu">–</span>
            </div>
            <div class="sysinfo-row">
                <span class="sysinfo-label">Terhelés (load)</span>
                <span class="sysinfo-value" id="host-load">–</span>
            </div>
            <div class="sysinfo-row">
                <span class="sysinfo-label">Memória</span>
                <span class="sysinfo-value" id="host-mem">–</span>
            </div>
            <div class="sysinfo-row">
                <span class="sysinfo-label">CPU hőmérséklet</span>
                <span class="sysinfo-value" id="host-temp">–</span>
            </div>
            <div class="sysinfo-row">
                <span class="sysinfo-label">Üzemidő</span>
                <span class="sysinfo-value" id="host-uptime">–</span>
            </div>
        </div>
        <h4 style="margin:1rem 0 .5rem">Tárolók kapacitása</h4>
        <div class="storage-bars" id="host-storage-bars"></div>
    </div>
</div>

<!-- Section 1: System Overview -->
<div class="monitor-card">
    <h3>Rendszer áttekintés</h3>
    <div class="sysinfo-grid">
        <div class="sysinfo-row">
            <span class="sysinfo-label">Gépnév</span>
            <span class="sysinfo-value" id="sysinfo-hostname">–</span>
        </div>
        <div class="sysinfo-row">
            <span class="sysinfo-label">Operációs rendszer</span>
            <span class="sysinfo-value" id="sysinfo-os">–</span>
        </div>
        <div class="sysinfo-row">
            <span class="sysinfo-label">Kernel</span>
            <span class="sysinfo-value" id="sysinfo-kernel">–</span>
        </div>
        <div class="sysinfo-row">
            <span class="sysinfo-label">Processzor</span>
            <span class="sysinfo-value" id="sysinfo-cpu">–</span>
        </div>
        <div class="sysinfo-row">
            <span class="sysinfo-label">Üzemidő</span>
            <span class="sysinfo-value" id="sysinfo-uptime">–</span>
        </div>
        <div class="sysinfo-row">
            <span class="sysinfo-label">Indítás</span>
            <span class="sysinfo-value" id="sysinfo-boot">–</span>
        </div>
    </div>
</div>

<!-- Section 1.5: Storage (moved here for visibility) -->
<div class="monitor-card">
    <h3>Tárhely</h3>
    <div class="storage-bars">
        {{with .SystemInfo}}
        <div class="storage-item meter {{usageColor .DiskPercent}}">
            <div class="storage-header">
                <span class="storage-label">Rendszer (/)</span>
                <span class="storage-value">{{fmtGB .DiskUsedGB}} / {{fmtGB .DiskTotalGB}} ({{printf "%.0f" .DiskPercent}}%)</span>
            </div>
            <div class="meter-track">
                <div class="meter-fill" style="width:{{printf "%.1f" .DiskPercent}}%"></div>
            </div>
        </div>
        {{range $.StorageBars}}
        {{if .Disconnected}}
        <div class="storage-item meter meter-empty storage-disconnected">
            <div class="storage-header">
                <span class="storage-label">{{.Label}}</span>
                <span class="storage-value">— <span class="state-text-neutral">Leválasztva</span></span>
            </div>
            <div class="meter-track"></div>
        </div>
        {{else}}
        <div class="storage-item meter {{usageColor .Percent}}">
            <div class="storage-header">
                <span class="storage-label">{{.Label}}</span>
                <span class="storage-value">{{fmtGB .UsedGB}} / {{fmtGB .TotalGB}} ({{printf "%.0f" .Percent}}%)</span>
            </div>
            <div class="meter-track">
                <div class="meter-fill" style="width:{{printf "%.1f" .Percent}}%"></div>
            </div>
            {{if .Purpose}}<div class="storage-purpose" style="font-size:.72rem;opacity:.65;margin-top:.2rem">{{.Purpose}}</div>{{end}}
        </div>
        {{end}}
        {{end}}
        {{end}}
    </div>
    {{if .DiskWarnings}}
    <div class="inline-warnings">
        {{range .DiskWarnings}}
        <div class="inline-warning inline-warning-{{.Level}}">
            <span class="inline-warning-dot">●</span>
            <span class="inline-warning-text">{{.Message}}</span>
            {{if .Link}}<a href="{{.Link}}" class="inline-warning-link">{{.LinkText}} →</a>{{end}}
        </div>
        {{end}}
    </div>
    {{end}}
</div>

<!-- Section 2: Hub Connection Status -->
<div class="monitor-card">
    <h3>Hub kapcsolat</h3>
    {{if .HubEnabled}}
        {{if .HubConnected}}
        <div class="monitoring-banner monitoring-banner-green">
            Kapcsolódva — a központi rendszer aktívan figyeli a szervert.
        </div>
        {{else}}
        <div class="monitoring-banner monitoring-banner-red">
            Nem elérhető — a központi rendszer nem kapott friss jelentést.
        </div>
        {{end}}
    <div class="sysinfo-grid" style="margin-top: 0.75rem">
        <div class="sysinfo-row">
            <span class="sysinfo-label">Hub URL</span>
            <span class="sysinfo-value"><code>{{.HubURL}}</code></span>
        </div>
        <div class="sysinfo-row">
            <span class="sysinfo-label">Ügyfél azonosító</span>
            <span class="sysinfo-value"><code>{{.CustomerID}}</code></span>
        </div>
        {{if not .HubLastSuccess.IsZero}}
        <div class="sysinfo-row">
            <span class="sysinfo-label">Utolsó sikeres jelentés</span>
            <span class="sysinfo-value">{{.HubLastSuccess | timeAgo}}</span>
        </div>
        {{end}}
        {{if .HubLastError}}
        <div class="sysinfo-row">
            <span class="sysinfo-label">Utolsó hiba</span>
            <span class="sysinfo-value"><span class="text-error">{{.HubLastError}}</span></span>
        </div>
        {{end}}
    </div>
    {{else}}
    <div class="monitoring-banner monitoring-banner-yellow">
        A Hub kapcsolat nincs bekapcsolva — a központi monitoring nem aktív.
    </div>
    {{end}}
</div>

<!-- Section 3: System Metrics Charts -->
<div class="monitor-card">
    <div class="monitor-card-header">
        <h3>Rendszer metrikák</h3>
        <div class="time-range-bar" id="system-range-bar">
            <button class="filter-btn active" data-range="1h">1 óra</button>
            <button class="filter-btn" data-range="6h">6 óra</button>
            <button class="filter-btn" data-range="24h">24 óra</button>
            <button class="filter-btn" data-range="7d">7 nap</button>
            <button class="filter-btn" data-range="30d">30 nap</button>
        </div>
    </div>
    <div class="charts-grid" id="system-charts">
        <div class="chart-box">
            <div class="chart-title">CPU használat (%)</div>
            <div class="chart-wrap"><canvas id="chart-cpu"></canvas></div>
        </div>
        <div class="chart-box">
            <div class="chart-title">Memória használat (GB)</div>
            <div class="chart-wrap"><canvas id="chart-memory"></canvas></div>
        </div>
        <div class="chart-box">
            <div class="chart-title">Hőmérséklet (°C)</div>
            <div class="chart-wrap"><canvas id="chart-temp"></canvas></div>
        </div>
        <div class="chart-box">
            <div class="chart-title">Terhelés (Load Average)</div>
            <div class="chart-wrap"><canvas id="chart-load"></canvas></div>
        </div>
    </div>
    <div class="chart-empty" id="system-charts-empty" style="display:none">
        Még nincsenek adatok. A metrikák gyűjtése elindult, az első adatok néhány perc múlva megjelennek.
    </div>
</div>

<!-- Section 3.5: Memory Distribution Bar -->
<div class="monitor-card" id="memory-distribution-card" style="display:none">
    <h3>Memória eloszlás</h3>
    <div id="mem-dist-header" class="memory-dist-header"></div>
    <div class="memory-dist-bar" id="mem-dist-bar"></div>
    <div class="memory-bar-legend" id="mem-dist-legend"></div>
</div>

<!-- Section 4: Container Resources -->
<div class="monitor-card">
    <h3>Alkalmazás erőforrások</h3>
    <div class="container-charts-row" id="container-charts">
        <div class="chart-box chart-box-half">
            <div class="chart-title">CPU használat (%)</div>
            <div class="chart-wrap chart-wrap-bar"><canvas id="chart-container-cpu"></canvas></div>
        </div>
        <div class="chart-box chart-box-half">
            <div class="chart-title">Memória használat (MB)</div>
            <div class="chart-wrap chart-wrap-bar"><canvas id="chart-container-mem"></canvas></div>
        </div>
    </div>
    <div class="chart-empty" id="container-charts-empty" style="display:none">
        Még nincsenek konténer adatok.
    </div>
</div>

<!-- Section 5: Per-container detail (expandable) -->
<div class="monitor-card" id="container-detail-panel" style="display:none">
    <div class="monitor-card-header">
        <h3 id="container-detail-title">–</h3>
        <div class="time-range-bar" id="container-range-bar">
            <button class="filter-btn active" data-range="1h">1 óra</button>
            <button class="filter-btn" data-range="6h">6 óra</button>
            <button class="filter-btn" data-range="24h">24 óra</button>
            <button class="filter-btn" data-range="7d">7 nap</button>
        </div>
        <button class="btn btn-outline btn-sm" onclick="closeContainerDetail()">Bezárás</button>
    </div>
    <div class="charts-grid charts-grid-2">
        <div class="chart-box">
            <div class="chart-title">CPU %</div>
            <div class="chart-wrap"><canvas id="chart-detail-cpu"></canvas></div>
        </div>
        <div class="chart-box">
            <div class="chart-title">Memória (MB)</div>
            <div class="chart-wrap"><canvas id="chart-detail-mem"></canvas></div>
        </div>
    </div>
</div>

<script src="/static/chart.min.js"></script>
<script>
(function() {
    'use strict';

    // --- Chart.js dark theme defaults ---
    var colors = {
        cpu: {border: '#2EA8F5', bg: 'rgba(46,168,245,0.1)'},
        memory: {border: '#8E7CE8', bg: 'rgba(142,124,232,0.1)'},
        temp: {border: '#E0A93E', bg: 'rgba(224,169,62,0.1)'},
        load: {border: '#5EC4B6', bg: 'rgba(94,196,182,0.1)'}
    };

    // --- Range helper: returns milliseconds for a range string ---
    function parseRangeMs(range) {
        switch (range) {
            case '1h':  return 3600000;
            case '6h':  return 21600000;
            case '24h': return 86400000;
            case '7d':  return 604800000;
            case '30d': return 2592000000;
            default:    return 3600000;
        }
    }

    // --- X-axis tick label format: short time for <=24h, date for longer ---
    function tickFormatForRange(range) {
        if (range === '7d' || range === '30d') return 'date';
        return 'time';
    }

    // --- Chart options for line charts with LINEAR x-axis ---
    function chartOpts(yLabel, beginAtZero) {
        var now = Date.now();
        var defaultRangeMs = parseRangeMs('1h');
        return {
            responsive: true,
            maintainAspectRatio: false,
            animation: {duration: 300},
            plugins: {
                legend: {display: false},
                tooltip: {
                    backgroundColor: '#0F1B2E',
                    titleColor: '#EDF2F9',
                    bodyColor: '#94A6BF',
                    borderColor: '#22344F',
                    borderWidth: 1,
                    callbacks: {
                        title: function(items) {
                            if (!items.length) return '';
                            var raw = items[0].raw;
                            if (raw && typeof raw === 'object' && raw.x) {
                                return formatTimestamp(raw.x);
                            }
                            if (items[0].parsed && items[0].parsed.x) {
                                return formatTimestamp(items[0].parsed.x);
                            }
                            return '';
                        }
                    }
                }
            },
            scales: {
                x: {
                    type: 'linear',
                    min: now - defaultRangeMs,
                    max: now,
                    grid: {color: 'rgba(34,52,79,0.5)'},
                    ticks: {
                        color: '#94A6BF',
                        maxTicksLimit: 8,
                        callback: function(v) {
                            return formatTimeLabel(v);
                        }
                    }
                },
                y: {
                    grid: {color: 'rgba(34,52,79,0.5)'},
                    ticks: {color: '#94A6BF'},
                    beginAtZero: beginAtZero !== false,
                    title: {display: !!yLabel, text: yLabel || '', color: '#5E7392', font: {size: 11}}
                }
            }
        };
    }

    var lineDataset = function(color) {
        return {
            borderColor: color.border,
            backgroundColor: color.bg,
            borderWidth: 2,
            pointRadius: 0,
            pointHitRadius: 10,
            tension: 0.3,
            fill: true,
            spanGaps: true
        };
    };

    // --- Timezone formatting ---
    var budaTZ = 'Europe/Budapest';

    // Current range for choosing date vs time format in tick labels
    var currentTickFormat = 'time';

    function formatTimestamp(ts) {
        if (ts === null || ts === undefined || ts === '') return '';
        if (typeof ts === 'string') ts = Number(ts);
        if (isNaN(ts)) return '';
        // ts should already be in ms (linear axis stores ms values)
        var d = new Date(ts);
        return d.toLocaleString('hu-HU', {timeZone: budaTZ, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit'});
    }

    function formatTimeLabel(ts) {
        if (ts === null || ts === undefined || ts === '') return '';
        if (typeof ts === 'string') ts = Number(ts);
        if (isNaN(ts)) return '';
        var d = new Date(ts);
        if (currentTickFormat === 'date') {
            return d.toLocaleDateString('hu-HU', {timeZone: budaTZ, month: '2-digit', day: '2-digit'});
        }
        return d.toLocaleTimeString('hu-HU', {timeZone: budaTZ, hour: '2-digit', minute: '2-digit'});
    }

    // --- Shared: build {x, y} point array from timestamps + values ---
    function buildXYData(timestamps, values) {
        var points = [];
        for (var i = 0; i < timestamps.length; i++) {
            points.push({x: timestamps[i], y: values[i]});
        }
        return points;
    }

    // --- Shared: set x-axis min/max on a chart based on range ---
    function setChartXBounds(chart, range) {
        var now = Date.now();
        var rangeMs = parseRangeMs(range);
        chart.options.scales.x.min = now - rangeMs;
        chart.options.scales.x.max = now;
    }

    // --- Shared: update a line chart with {x, y} data ---
    function updateLineChart(chart, timestamps, values) {
        chart.data.datasets[0].data = buildXYData(timestamps, values);
        chart.update('none');
    }

    // =============================================
    //  SYSTEM CHARTS
    // =============================================
    var systemRange = '1h';
    var chartCPU, chartMem, chartTemp, chartLoad;

    function initSystemCharts() {
        var mkChart = function(id, color, yLabel, beginAtZero) {
            return new Chart(document.getElementById(id), {
                type: 'line',
                data: {datasets: [{data: [], ...lineDataset(color)}]},
                options: chartOpts(yLabel, beginAtZero)
            });
        };
        chartCPU  = mkChart('chart-cpu',    colors.cpu,    '%',  true);
        chartMem  = mkChart('chart-memory', colors.memory, 'GB', true);
        chartTemp = mkChart('chart-temp',   colors.temp,   '°C', false);
        chartLoad = mkChart('chart-load',   colors.load,   '',   true);
    }

    async function loadSystemMetrics() {
        try {
            var resp = await fetch('/api/metrics/system?range=' + systemRange + '&resolution=200');
            var json = await resp.json();
            if (!json.ok || !json.data) return;
            var d = json.data;

            if (!d.labels || d.labels.length === 0) {
                document.getElementById('system-charts').style.display = 'none';
                document.getElementById('system-charts-empty').style.display = 'block';
                return;
            }
            document.getElementById('system-charts').style.display = '';
            document.getElementById('system-charts-empty').style.display = 'none';

            // Convert Unix seconds to milliseconds
            var timestamps = d.labels.map(function(ts) { return ts * 1000; });

            // Update tick label format based on range
            currentTickFormat = tickFormatForRange(systemRange);

            // Set x-axis bounds to the full requested range
            var allCharts = [chartCPU, chartMem, chartTemp, chartLoad];
            allCharts.forEach(function(c) { setChartXBounds(c, systemRange); });

            // Update each chart with {x, y} data
            updateLineChart(chartCPU,  timestamps, d.cpu);
            updateLineChart(chartMem,  timestamps, d.memory);
            updateLineChart(chartTemp, timestamps, d.temp);
            updateLineChart(chartLoad, timestamps, d.load1);
        } catch(e) {
            console.error('Failed to load system metrics:', e);
        }
    }

    // Range bar clicks
    document.getElementById('system-range-bar').addEventListener('click', function(e) {
        var btn = e.target.closest('.filter-btn');
        if (!btn) return;
        this.querySelectorAll('.filter-btn').forEach(function(b) { b.classList.remove('active'); });
        btn.classList.add('active');
        systemRange = btn.dataset.range;
        loadSystemMetrics();
    });

    // =============================================
    //  CONTAINER BAR CHARTS
    // =============================================
    var chartContainerCPU, chartContainerMem;
    var containerNames = [];

    function initContainerCharts() {
        var barOpts = function(xLabel) {
            return {
                indexAxis: 'y',
                responsive: true,
                maintainAspectRatio: false,
                animation: {duration: 300},
                plugins: {
                    legend: {display: false},
                    tooltip: {
                        backgroundColor: '#0F1B2E',
                        titleColor: '#EDF2F9',
                        bodyColor: '#94A6BF',
                        borderColor: '#22344F',
                        borderWidth: 1
                    }
                },
                scales: {
                    x: {
                        grid: {color: 'rgba(34,52,79,0.5)'},
                        ticks: {color: '#94A6BF'},
                        beginAtZero: true,
                        title: {display: true, text: xLabel, color: '#5E7392', font: {size: 11}}
                    },
                    y: {
                        grid: {display: false},
                        ticks: {color: '#94A6BF', font: {size: 12}}
                    }
                },
                onClick: function(evt, elements) {
                    if (elements.length > 0) {
                        var idx = elements[0].index;
                        if (containerNames[idx]) {
                            showContainerDetail(containerNames[idx]);
                        }
                    }
                }
            };
        };

        chartContainerCPU = new Chart(document.getElementById('chart-container-cpu'), {
            type: 'bar',
            data: {labels: [], datasets: [{data: [], backgroundColor: '#2EA8F5', borderRadius: 2}]},
            options: barOpts('%')
        });
        chartContainerMem = new Chart(document.getElementById('chart-container-mem'), {
            type: 'bar',
            data: {labels: [], datasets: [{data: [], backgroundColor: '#8E7CE8', borderRadius: 2}]},
            options: barOpts('MB')
        });
    }

    async function loadContainerSummary() {
        try {
            var resp = await fetch('/api/metrics/containers/summary');
            var json = await resp.json();
            if (!json.ok || !json.data) return;

            var data = json.data;
            if (!data.length) {
                document.getElementById('container-charts').style.display = 'none';
                document.getElementById('container-charts-empty').style.display = 'block';
                return;
            }
            document.getElementById('container-charts').style.display = '';
            document.getElementById('container-charts-empty').style.display = 'none';

            containerNames = data.map(function(c) { return c.name; });
            var cpuData = data.map(function(c) { return Math.round(c.cpu_percent * 100) / 100; });
            var memData = data.map(function(c) { return Math.round(c.mem_usage_mb); });

            // Adjust bar chart height based on container count
            var h = Math.max(200, data.length * 35 + 60);
            document.querySelectorAll('.chart-wrap-bar').forEach(function(el) { el.style.height = h + 'px'; });

            chartContainerCPU.data.labels = containerNames;
            chartContainerCPU.data.datasets[0].data = cpuData;
            chartContainerCPU.update('none');

            chartContainerMem.data.labels = containerNames;
            chartContainerMem.data.datasets[0].data = memData;
            chartContainerMem.update('none');

            buildMemoryDistributionBar(data);
        } catch(e) {
            console.error('Failed to load container summary:', e);
        }
    }

    var memDistPalette = ['#2EA8F5','#8E7CE8','#5EC4B6','#E0A93E','#D67BB5','#7FA6E8','#59B88C','#E8935E','#6FCADF','#B3A1F0'];

    async function buildMemoryDistributionBar(containers) {
        var totalMB = {{.SystemInfo.TotalMemMB}};
        if (!totalMB) return;

        // Get real-time used memory from API
        var usedMB = 0;
        try {
            var resp = await fetch('/api/system/info');
            var json = await resp.json();
            if (json.ok && json.data && json.data.system) usedMB = json.data.system.used_mem_mb || 0;
        } catch(e) {}
        if (!usedMB) return;

        var card = document.getElementById('memory-distribution-card');
        var bar = document.getElementById('mem-dist-bar');
        var legend = document.getElementById('mem-dist-legend');
        var header = document.getElementById('mem-dist-header');

        // Sum container memory
        var appTotal = 0;
        containers.forEach(function(c) { appTotal += c.mem_usage_mb || 0; });
        var osMB = Math.max(0, usedMB - appTotal);
        var freeMB = Math.max(0, totalMB - usedMB);

        function fmtMB(mb) { return mb >= 1024 ? (mb/1024).toFixed(1) + ' GB' : Math.round(mb) + ' MB'; }

        header.textContent = 'Használt: ' + fmtMB(usedMB) + ' / ' + fmtMB(totalMB) + ' (' + Math.round(usedMB/totalMB*100) + '%)';

        // Sort containers by memory usage descending
        containers.sort(function(a, b) { return (b.mem_usage_mb || 0) - (a.mem_usage_mb || 0); });

        // Build bar segments
        var html = '';
        var legendHtml = '';
        containers.forEach(function(c, i) {
            var mb = c.mem_usage_mb || 0;
            if (mb < 1) return;
            var pct = (mb / totalMB * 100).toFixed(2);
            var color = memDistPalette[i % memDistPalette.length];
            html += '<div class="memory-bar-segment" style="width:' + pct + '%;background:' + color + '" title="' + c.name + ': ' + fmtMB(mb) + '"></div>';
            legendHtml += '<div class="memory-legend-item"><span class="memory-legend-dot" style="background:' + color + '"></span>' + c.name + ' (' + fmtMB(mb) + ')</div>';
        });

        // OS / system overhead
        if (osMB > 10) {
            var osPct = (osMB / totalMB * 100).toFixed(2);
            html += '<div class="memory-bar-segment" style="width:' + osPct + '%;background:var(--text-3);opacity:0.5" title="Rendszer: ' + fmtMB(osMB) + '"></div>';
            legendHtml += '<div class="memory-legend-item"><span class="memory-legend-dot" style="background:var(--text-3);opacity:0.5"></span>Rendszer (' + fmtMB(osMB) + ')</div>';
        }

        // Free space legend only
        legendHtml += '<div class="memory-legend-item"><span class="memory-legend-dot" style="background:var(--bg-2);border:1px solid var(--line)"></span>Szabad (' + fmtMB(freeMB) + ')</div>';

        bar.innerHTML = html;
        legend.innerHTML = legendHtml;
        card.style.display = '';
    }

    // =============================================
    //  CONTAINER DETAIL (per-container history)
    // =============================================
    var detailChartCPU, detailChartMem;
    var detailContainer = '';
    var detailRange = '1h';

    function initDetailCharts() {
        var mkChart = function(id, color, yLabel) {
            return new Chart(document.getElementById(id), {
                type: 'line',
                data: {datasets: [{data: [], ...lineDataset(color)}]},
                options: chartOpts(yLabel, true)
            });
        };
        detailChartCPU = mkChart('chart-detail-cpu', colors.cpu, '%');
        detailChartMem = mkChart('chart-detail-mem', colors.memory, 'MB');
    }

    window.showContainerDetail = async function(name) {
        detailContainer = name;
        document.getElementById('container-detail-title').textContent = name + ' — Erőforrás előzmények';
        document.getElementById('container-detail-panel').style.display = '';
        document.getElementById('container-detail-panel').scrollIntoView({behavior: 'smooth'});
        await loadContainerDetail();
    };

    window.closeContainerDetail = function() {
        document.getElementById('container-detail-panel').style.display = 'none';
        detailContainer = '';
    };

    async function loadContainerDetail() {
        if (!detailContainer) return;
        try {
            var resp = await fetch('/api/metrics/containers/' + encodeURIComponent(detailContainer) + '?range=' + detailRange + '&resolution=150');
            var json = await resp.json();
            if (!json.ok || !json.data) return;
            var d = json.data;

            // Convert Unix seconds to milliseconds
            var timestamps = (d.labels || []).map(function(ts) { return ts * 1000; });

            // Set x-axis bounds
            setChartXBounds(detailChartCPU, detailRange);
            setChartXBounds(detailChartMem, detailRange);

            // Update with {x, y} data
            updateLineChart(detailChartCPU, timestamps, d.cpu || []);
            updateLineChart(detailChartMem, timestamps, d.memory || []);
        } catch(e) {
            console.error('Failed to load container detail:', e);
        }
    }

    document.getElementById('container-range-bar').addEventListener('click', function(e) {
        var btn = e.target.closest('.filter-btn');
        if (!btn) return;
        this.querySelectorAll('.filter-btn').forEach(function(b) { b.classList.remove('active'); });
        btn.classList.add('active');
        detailRange = btn.dataset.range;
        loadContainerDetail();
    });

    // =============================================
    //  HOST (PROXMOX BOX) HEALTH — slice 9, proxied from the host agent
    // =============================================
    function usageColorClass(pct) {
        if (pct >= 85) return 'crit';
        if (pct >= 70) return 'warn';
        return 'nominal';
    }

    function fmtBytesGB(bytes) {
        if (!bytes || bytes <= 0) return '0 GB';
        var gb = bytes / 1073741824;
        if (gb >= 1024) return (gb / 1024).toFixed(2) + ' TB';
        if (gb >= 100) return Math.round(gb) + ' GB';
        return gb.toFixed(1) + ' GB';
    }

    function escapeHtml(s) {
        return String(s).replace(/[&<>"']/g, function(c) {
            return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c];
        });
    }

    function showHostUnavailable() {
        document.getElementById('host-health-unavailable').style.display = '';
        document.getElementById('host-health-body').style.display = 'none';
        document.getElementById('host-health-updated').textContent = '';
    }

    function renderHostHealth(d) {
        var h = d.host || {};
        document.getElementById('host-health-unavailable').style.display = 'none';
        document.getElementById('host-health-body').style.display = '';

        // CPU % + load average
        document.getElementById('host-cpu').textContent =
            (h.cpu_percent != null ? h.cpu_percent.toFixed(1) : '–') + '%';
        var load = Array.isArray(h.loadavg) ? h.loadavg.join('  ') : '–';
        document.getElementById('host-load').textContent = load || '–';

        // Memory used/total
        if (h.memory_total_bytes > 0) {
            document.getElementById('host-mem').textContent =
                fmtBytesGB(h.memory_used_bytes) + ' / ' + fmtBytesGB(h.memory_total_bytes) +
                ' (' + Math.round(h.memory_percent || 0) + '%)';
        } else {
            document.getElementById('host-mem').textContent = '–';
        }

        // CPU temp — null renders as "n/a" cleanly (graceful-null from the agent)
        document.getElementById('host-temp').textContent =
            (h.cpu_temp_c == null) ? 'n/a' : (h.cpu_temp_c + ' °C');

        // Uptime (reuse the existing formatter)
        document.getElementById('host-uptime').textContent =
            (h.uptime_seconds > 0) ? formatUptime(h.uptime_seconds) : '–';

        // Per-storage capacity bars
        var bars = document.getElementById('host-storage-bars');
        var targets = Array.isArray(d.storage_targets) ? d.storage_targets : [];
        if (!targets.length) {
            bars.innerHTML = '<div class="sysinfo-value" style="color:var(--text-3)">Nincs tároló adat.</div>';
        } else {
            var html = '';
            targets.forEach(function(t) {
                // Friendly label (server-supplied) with the raw PVE storage id shown muted for clarity.
                var friendly = escapeHtml(t.label || t.name || '');
                var rawId = escapeHtml(t.name || '');
                var idHtml = rawId ? ' <span style="color:var(--text-3);font-size:.72rem">(' + rawId + ')</span>' : '';
                var label = friendly + idHtml;
                var purposeHtml = t.purpose ? '<div class="storage-purpose" style="font-size:.72rem;opacity:.65;margin-top:.2rem">' + escapeHtml(t.purpose) + '</div>' : '';
                if (t.state && t.state !== 'attached') {
                    html += '<div class="storage-item meter meter-empty storage-disconnected">' +
                        '<div class="storage-header"><span class="storage-label">' + label + '</span>' +
                        '<span class="storage-value">— <span class="state-text-neutral">Nem elérhető</span></span></div>' +
                        '<div class="meter-track"></div>' + purposeHtml + '</div>';
                    return;
                }
                var pct = (t.used_fraction != null ? t.used_fraction * 100 : 0);
                // Extra detail: thin-pool fill (corrupts every guest if full) + disk temp/wear.
                var extra = [];
                if (t.thin_pool && t.thin_pool.data_used_fraction != null) {
                    extra.push('thin-pool: ' + Math.round(t.thin_pool.data_used_fraction * 100) + '%');
                }
                if (t.smart) {
                    if (t.smart.temperature_c != null) extra.push(t.smart.temperature_c + ' °C');
                    if (t.smart.percentage_used != null) extra.push('kopás: ' + t.smart.percentage_used + '%');
                }
                var extraHtml = extra.length ? ' <span style="color:var(--text-3);font-size:.75rem">· ' + escapeHtml(extra.join(' · ')) + '</span>' : '';
                html += '<div class="storage-item meter ' + usageColorClass(pct) + '">' +
                    '<div class="storage-header">' +
                    '<span class="storage-label">' + label + extraHtml + '</span>' +
                    '<span class="storage-value">' + fmtBytesGB(t.used_bytes) + ' / ' + fmtBytesGB(t.total_bytes) +
                    ' (' + Math.round(pct) + '%)</span></div>' +
                    '<div class="meter-track"><div class="meter-fill' +
                    '" style="width:' + Math.min(100, pct).toFixed(1) + '%"></div></div>' + purposeHtml + '</div>';
            });
            bars.innerHTML = html;
        }

        var now = new Date();
        document.getElementById('host-health-updated').textContent =
            'Frissítve: ' + now.toLocaleTimeString('hu-HU', {timeZone: budaTZ, hour: '2-digit', minute: '2-digit', second: '2-digit'});
    }

    async function loadHostMetrics() {
        try {
            var resp = await fetch('/api/host-metrics');
            var json = await resp.json();
            if (!json.ok || !json.data) { showHostUnavailable(); return; }
            renderHostHealth(json.data);
        } catch(e) {
            console.error('Failed to load host metrics:', e);
            showHostUnavailable();
        }
    }

    // =============================================
    //  STATIC SYSTEM INFO
    // =============================================
    async function loadSysInfo() {
        try {
            var resp = await fetch('/api/metrics/sysinfo');
            var json = await resp.json();
            if (!json.ok || !json.data) return;
            var d = json.data;

            document.getElementById('sysinfo-hostname').textContent = d.hostname || '–';
            document.getElementById('sysinfo-os').textContent = d.os || '–';
            document.getElementById('sysinfo-kernel').textContent = d.kernel || '–';

            var cpuText = d.cpu_model || '–';
            if (d.cpu_cores > 0) cpuText += ' (' + d.cpu_cores + ' mag)';
            document.getElementById('sysinfo-cpu').textContent = cpuText;

            if (d.uptime_seconds > 0) {
                document.getElementById('sysinfo-uptime').textContent = formatUptime(d.uptime_seconds);
            }
            if (d.boot_time) {
                var bt = new Date(d.boot_time);
                document.getElementById('sysinfo-boot').textContent = bt.toLocaleString('hu-HU', {timeZone: budaTZ, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit'});
            }
        } catch(e) {
            console.error('Failed to load sysinfo:', e);
        }
    }

    function formatUptime(seconds) {
        var days = Math.floor(seconds / 86400);
        var hours = Math.floor((seconds % 86400) / 3600);
        var minutes = Math.floor((seconds % 3600) / 60);
        if (days > 0) return days + ' nap, ' + hours + ' óra';
        if (hours > 0) return hours + ' óra, ' + minutes + ' perc';
        return minutes + ' perc';
    }

    // =============================================
    //  INIT
    // =============================================
    initSystemCharts();
    initContainerCharts();
    initDetailCharts();
    loadSysInfo();
    loadSystemMetrics();
    loadContainerSummary();
    loadHostMetrics();

    // Auto-refresh every 60 seconds
    setInterval(function() {
        loadSystemMetrics();
        loadContainerSummary();
        if (detailContainer) loadContainerDetail();
    }, 60000);

    // Host (Proxmox box) health is a live snapshot — poll it more often while the page is open.
    setInterval(loadHostMetrics, 8000);

})();
</script>

{{template "layout_end" .}}
{{end}}