<?php
/**
 * 右侧栏：实时时钟 + 服务器状态
 * 设置在外观 → 自定义 → 右侧栏
 */
$clock_enable  = get_theme_mod( 'zyc_clock_enable', true );
$clock_title   = get_theme_mod( 'zyc_clock_title', '🕒 时间' );
$status_enable = get_theme_mod( 'zyc_status_enable', true );
$status_title  = get_theme_mod( 'zyc_status_title', '📊 服务器状态' );
?>
<aside class="sidebar-right" aria-label="右侧栏">

    <?php
    // 优先用主题自定义内容，不受小工具干扰
    $zyc_use_widgets_r = get_theme_mod( 'zyc_rightbar_widgets', false );
    if ( $zyc_use_widgets_r && is_active_sidebar( 'sidebar-right' ) ) : ?>
        <?php dynamic_sidebar( 'sidebar-right' ); ?>
    <?php else : ?>

        <?php if ( $clock_enable ) : ?>
        <div class="widget widget-clock">
            <h3 class="widget-title"><?php echo esc_html( $clock_title ); ?></h3>
            <div class="widget-content">
                <div class="clock-box">
                    <div class="clock-date" id="zyc-clock-date">----</div>
                    <div class="clock-time" id="zyc-clock-time">--:--:--</div>
                    <div class="clock-ms" id="zyc-clock-ms">.---</div>
                </div>
            </div>
        </div>
        <?php endif; ?>

        <?php if ( $status_enable ) : ?>
        <div class="widget widget-status">
            <h3 class="widget-title"><?php echo esc_html( $status_title ); ?></h3>
            <div class="widget-content">
                <ul class="status-list" id="zyc-status">
                    <li class="status-cpu">
                        <span class="st-label"><i class="st-dot st-dot-cpu"></i>CPU</span>
                        <span class="st-value" id="zyc-cpu">--%</span>
                        <span class="st-bar"><span class="st-bar-fill" id="zyc-cpu-bar" style="width:0%"></span></span>
                    </li>
                    <li class="status-load">
                        <span class="st-label">负载</span>
                        <span class="st-value" id="zyc-load">--</span>
                    </li>
                    <li class="status-mem">
                        <span class="st-label"><i class="st-dot st-dot-mem"></i>内存</span>
                        <span class="st-value" id="zyc-mem">-- / -- MB</span>
                        <span class="st-bar"><span class="st-bar-fill st-bar-mem" id="zyc-mem-bar" style="width:0%"></span></span>
                    </li>
                    <li class="status-net">
                        <span class="st-label">网络 ↓ / ↑</span>
                        <span class="st-value" id="zyc-net">-- / --</span>
                    </li>
                    <li class="status-host">
                        <span class="st-label">主机</span>
                        <span class="st-value" id="zyc-host">--</span>
                    </li>
                    <li class="status-uptime">
                        <span class="st-label">运行</span>
                        <span class="st-value" id="zyc-uptime">--</span>
                    </li>
                </ul>
                <p class="status-updated" id="zyc-updated">等待数据…</p>
            </div>
        </div>
        <?php endif; ?>

        <?php if ( $stats_enable ) : ?>
        <div class="widget widget-stats">
            <h3 class="widget-title"><?php echo esc_html( get_theme_mod( 'zyc_stats_title', '📈 流量计量' ) ); ?></h3>
            <div class="widget-content">
                <div class="stats-period-switch">
                    <button class="zyc-stats-tab active" data-period="4">4 小时</button>
                    <button class="zyc-stats-tab" data-period="24">24 小时</button>
                </div>

                <div class="stats-section">
                    <div class="stats-section-title">
                        <span>CPU 负载</span>
                        <span class="stats-hint">/ <?php echo esc_html( (int) shell_exec( 'nproc 2>/dev/null' ) ?: 1 ); ?> 核</span>
                    </div>
                    <svg class="stats-chart" id="zyc-cpu-chart" viewBox="0 0 280 60" preserveAspectRatio="none"></svg>
                    <div class="stats-chart-legend">
                        <span><i class="dot" style="background:#2f81f7"></i>1m</span>
                        <span><i class="dot" style="background:#f0c674"></i>5m</span>
                        <span><i class="dot" style="background:#f85149"></i>15m</span>
                    </div>
                    <div class="stats-chart-hint" id="zyc-cpu-hint">等待数据…</div>
                </div>

                <div class="stats-section">
                    <div class="stats-section-title">
                        <span>流量速率</span>
                        <span class="stats-hint">下行（下载）/ 上行（上传）</span>
                    </div>
                    <svg class="stats-chart" id="zyc-net-chart" viewBox="0 0 280 50" preserveAspectRatio="none"></svg>
                    <div class="stats-chart-legend">
                        <span><i class="dot" style="background:#22c55e"></i>下行</span>
                        <span><i class="dot" style="background:#a855f7"></i>上行</span>
                    </div>
                    <div class="stats-chart-hint" id="zyc-net-hint">等待数据…</div>
                </div>

                <div class="stats-section">
                    <div class="stats-section-title">
                        <span>流量用量</span>
                        <div class="stats-unit-switch">
                            <button class="zyc-unit-tab active" data-unit="mb">MB</button>
                            <button class="zyc-unit-tab" data-unit="gb">GB</button>
                            <button class="zyc-unit-tab" data-unit="tb">TB</button>
                        </div>
                    </div>
                    <div class="stats-net-row">
                        <div class="stats-net-item">
                            <span class="stats-net-label">上行</span>
                            <span class="stats-net-value" id="zyc-stats-tx">--</span>
                        </div>
                        <div class="stats-net-item">
                            <span class="stats-net-label">下行</span>
                            <span class="stats-net-value" id="zyc-stats-rx">--</span>
                        </div>
                    </div>
                    <div class="stats-net-hint" id="zyc-stats-hint">等待数据…</div>
                </div>
            </div>
        </div>
        <?php endif; ?>

    <?php endif; ?>

</aside>

<script>
(function () {
    'use strict';

    <?php if ( ! $clock_enable && ! $status_enable ) : ?>
    return; // 都关了，不加载脚本
    <?php endif; ?>

    /* ============ 时钟 ============ */
    <?php if ( $clock_enable ) : ?>
    var WEEK = ['日', '一', '二', '三', '四', '五', '六'];
    function pad(n, w) {
        w = w || 2;
        n = String(n);
        while (n.length < w) { n = '0' + n; }
        return n;
    }
    function tickClock() {
        var now = new Date();
        var dateEl = document.getElementById('zyc-clock-date');
        var timeEl = document.getElementById('zyc-clock-time');
        var msEl = document.getElementById('zyc-clock-ms');
        if (dateEl) {
            dateEl.textContent = now.getFullYear() + '年' + pad(now.getMonth() + 1) + '月' + pad(now.getDate()) + '日 星期' + WEEK[now.getDay()];
        }
        if (timeEl) {
            timeEl.textContent = pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds());
        }
        if (msEl) {
            msEl.textContent = '.' + pad(now.getMilliseconds(), 3);
        }
    }
    tickClock();
    setInterval(tickClock, 50);
    <?php endif; ?>

    /* ============ 服务器状态 ============ */
    <?php if ( $status_enable ) : ?>
    var API_URL = <?php
        echo wp_json_encode( trailingslashit( get_template_directory_uri() ) . 'server-status.php' );
    ?>;

    var prev = null;
    var prevTime = 0;

    function fmtBytes(b) {
        if (b < 1024) return b + ' B';
        if (b < 1048576) return (b / 1024).toFixed(1) + ' KB';
        if (b < 1073741824) return (b / 1048576).toFixed(2) + ' MB';
        return (b / 1073741824).toFixed(2) + ' GB';
    }
    function fmtRate(bps) {
        if (bps < 0) return '--';
        return fmtBytes(bps) + '/s';
    }
    function fmtUptime(s) {
        var d = Math.floor(s / 86400);
        var h = Math.floor((s % 86400) / 3600);
        var m = Math.floor((s % 3600) / 60);
        if (d > 0) return d + '天' + h + '时';
        if (h > 0) return h + '时' + m + '分';
        return m + '分' + Math.floor(s % 60) + '秒';
    }
    function setText(id, v) {
        var el = document.getElementById(id);
        if (el) el.textContent = v;
    }

    function refresh() {
        fetch(API_URL, { cache: 'no-store' })
            .then(function (r) { return r.json(); })
            .then(function (d) {
                setText('zyc-cpu', d.cpu + '%');
                var cpuBar = document.getElementById('zyc-cpu-bar');
                if (cpuBar) cpuBar.style.width = Math.min(100, d.cpu) + '%';

                setText('zyc-load', d.load[0] + ' / ' + d.load[1] + ' / ' + d.load[2] + '（' + d.cores + '核）');
                setText('zyc-mem', d.mem.used_mb + ' / ' + d.mem.total_mb + ' MB');
                var memBar = document.getElementById('zyc-mem-bar');
                if (memBar) memBar.style.width = Math.min(100, d.mem.pct) + '%';

                var now = Date.now() / 1000;
                if (prev !== null && prevTime > 0) {
                    var dt = now - prevTime;
                    // 服务器TX（出口）= 用户下行（下载），服务器RX（入口）= 用户上行（上传）
                    var downRate = dt > 0 ? (d.net.tx_bytes - prev.tx_bytes) / dt : -1;
                    var upRate   = dt > 0 ? (d.net.rx_bytes - prev.rx_bytes) / dt : -1;
                    setText('zyc-net', '↓' + fmtRate(downRate) + ' ↑' + fmtRate(upRate));
                } else {
                    setText('zyc-net', '↓' + fmtBytes(d.net.tx_bytes) + ' ↑' + fmtBytes(d.net.rx_bytes));
                }
                prev = d.net;
                prevTime = now;

                setText('zyc-host', d.hostname);
                setText('zyc-uptime', fmtUptime(d.uptime));
                setText('zyc-updated', '更新于 ' + new Date().toLocaleTimeString('zh-CN', { hour12: false }));
            })
            .catch(function () {
                setText('zyc-updated', '状态接口暂不可用');
            });
    }
    refresh();
    setInterval(refresh, 3000);
    <?php endif; ?>

    /* ============ 流量计量表（4h/24h + MB/GB/TB） ============ */
    <?php if ( $stats_enable ) : ?>
    var STATS_URL = <?php echo wp_json_encode( trailingslashit( get_template_directory_uri() ) . 'server-stats.php' ); ?>;
    var zycStats = { period: 4, unit: 'mb', data: null, refreshTimer: null };
    var STATS_COLORS = { c1: '#2f81f7', c5: '#f0c674', c15: '#f85149' };
    var STATS_UNIT_MULT = { mb: 1048576, gb: 1073741824, tb: 1099511627776 };

    function zycStatsFmt(bytes, unit) {
        var m = STATS_UNIT_MULT[unit] || 1;
        var v = bytes / m;
        if (v >= 100) return Math.round(v) + ' ' + unit.toUpperCase();
        if (v >= 10)  return v.toFixed(1) + ' ' + unit.toUpperCase();
        return v.toFixed(3) + ' ' + unit.toUpperCase();
    }

    /* ============ 图表 hover 交互 ============ */
    var zycChartReg = {};
    var zycTip = document.createElement('div');
    zycTip.id = 'zyc-chart-tooltip';
    zycTip.className = 'zyc-chart-tooltip';
    document.body.appendChild(zycTip);

    function zycChartRegister(svgId, info) {
        zycChartReg[svgId] = info;
        var svg = document.getElementById(svgId);
        if (svg && !svg.getAttribute('data-zyc-bound')) {
            svg.setAttribute('data-zyc-bound', '1');
            svg.addEventListener('mousemove', zycChartOnMove);
            svg.addEventListener('mouseleave', zycChartOnLeave);
        }
    }

    function zycChartOnMove(e) {
        var svgId = this.id;
        var reg = zycChartReg[svgId];
        if (!reg || !reg.points.length) return;

        var rect = this.getBoundingClientRect();
        var scaleX = reg.W / rect.width;
        var mouseX = (e.clientX - rect.left) * scaleX;

        var n = reg.points.length;
        var idx = Math.round((mouseX - reg.padL) / reg.usableW * (n - 1));
        idx = Math.max(0, Math.min(n - 1, idx));

        var p = reg.points[idx];
        var x = reg.padL + (reg.usableW * idx / Math.max(1, n - 1));

        var old = this.querySelectorAll('.zyc-crosshair, .zyc-hover-dot');
        for (var oi = 0; oi < old.length; oi++) old[oi].remove();

        var ns = 'http://www.w3.org/2000/svg';
        var line = document.createElementNS(ns, 'line');
        line.setAttribute('class', 'zyc-crosshair');
        line.setAttribute('x1', x); line.setAttribute('x2', x);
        line.setAttribute('y1', reg.padT); line.setAttribute('y2', reg.H - reg.padB);
        this.appendChild(line);

        for (var di = 0; di < reg.dots.length; di++) {
            var dotKey = reg.dots[di];
            var dy = reg.yFor(p[dotKey]);
            var dot = document.createElementNS(ns, 'circle');
            dot.setAttribute('class', 'zyc-hover-dot');
            dot.setAttribute('cx', x); dot.setAttribute('cy', dy); dot.setAttribute('r', 2.5);
            this.appendChild(dot);
        }

        zycTip.innerHTML = reg.fmtTip(p);
        zycTip.style.display = 'block';
        var tipX = e.clientX + 12;
        var tipY = e.clientY - 36;
        if (tipX + 160 > window.innerWidth) tipX = e.clientX - 172;
        if (tipY < 4) tipY = e.clientY + 12;
        zycTip.style.left = tipX + 'px';
        zycTip.style.top = tipY + 'px';
    }

    function zycChartOnLeave() {
        var old = this.querySelectorAll('.zyc-crosshair, .zyc-hover-dot');
        for (var oi = 0; oi < old.length; oi++) old[oi].remove();
        zycTip.style.display = 'none';
    }

    function zycStatsDrawChart(svgEl, points, cores) {
        if (!svgEl || !points.length) return;
        var W = 280, H = 60, padL = 24, padR = 4, padT = 4, padB = 16;
        var usableW = W - padL - padR, usableH = H - padT - padB;
        var maxLoad = Math.max(cores, 1) * 2;

        // Y 轴刻度
        var yTicks = [];
        for (var v = 0; v <= maxLoad; v += Math.max(0.5, Math.floor(maxLoad / 6) || 0.5)) {
            yTicks.push(Math.min(maxLoad, +v.toFixed(1)));
        }
        if (yTicks[yTicks.length - 1] !== maxLoad) yTicks.push(maxLoad);

        var parts = ['<g class="axis-y">'];
        yTicks.forEach(function (t) {
            var y = padT + usableH - (t / maxLoad) * usableH;
            parts.push('<line x1="' + padL + '" y1="' + y + '" x2="' + (W - padR) + '" y2="' + y + '" class="grid"/>');
            parts.push('<text x="' + (padL - 3) + '" y="' + (y + 3) + '" text-anchor="end" class="tick-label">' + t.toFixed(1) + '</text>');
        });
        parts.push('</g>');

        // 数据线
        function lineFor(key) {
            var pts = [];
            points.forEach(function (p, i) {
                var x = padL + (usableW * i / Math.max(1, points.length - 1));
                var y = padT + usableH - (Math.min(maxLoad, p[key]) / maxLoad) * usableH;
                pts.push(x.toFixed(1) + ',' + y.toFixed(1));
            });
            return '<polyline points="' + pts.join(' ') + '" class="cpu-line cpu-' + key + '"/>';
        }

        // 高负载区域阴影（超过 cores）
        var warnY = padT + usableH - (cores / maxLoad) * usableH;
        parts.push('<rect x="' + padL + '" y="' + warnY + '" width="' + usableW + '" height="' + (usableH - (warnY - padT)) + '" class="cpu-warn-zone"/>');
        parts.push('<line x1="' + padL + '" y1="' + warnY + '" x2="' + (W - padR) + '" y2="' + warnY + '" class="cpu-warn-line"/>');

        parts.push(lineFor('load1'));
        parts.push(lineFor('load5'));
        parts.push(lineFor('load15'));

        // X 轴时间标签
        var xl1 = padL + (usableW * 0 / Math.max(1, points.length - 1));
        var xl2 = padL + (usableW * 0.5 / Math.max(1, points.length - 1));
        var xl3 = padL + usableW;
        function tsLabel(ts) {
            var d = new Date(ts * 1000);
            return d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0');
        }
        parts.push('<text x="' + xl1 + '" y="' + (H - 2) + '" text-anchor="start" class="tick-label">' + (points[0] ? tsLabel(points[0].ts) : '') + '</text>');
        parts.push('<text x="' + xl2 + '" y="' + (H - 2) + '" text-anchor="middle" class="tick-label">' + (points[Math.floor(points.length/2)] ? tsLabel(points[Math.floor(points.length/2)].ts) : '') + '</text>');
        parts.push('<text x="' + xl3 + '" y="' + (H - 2) + '" text-anchor="end" class="tick-label">' + (points[points.length - 1] ? tsLabel(points[points.length - 1].ts) : '') + '</text>');

        svgEl.innerHTML = parts.join('');

        // 注册 hover 交互
        function yForCpu(v) {
            return padT + usableH - (Math.min(maxLoad, v) / maxLoad) * usableH;
        }
        function fmtTipCpu(p) {
            var d = new Date(p.ts * 1000);
            var t = d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0') + ':' + d.getSeconds().toString().padStart(2, '0');
            return '<div class="zyc-tip-time">' + t + '</div>' +
                   '<div><i class="zyc-tip-dot" style="background:#2f81f7"></i>1m: <b>' + p.load1 + '</b></div>' +
                   '<div><i class="zyc-tip-dot" style="background:#f0c674"></i>5m: <b>' + p.load5 + '</b></div>' +
                   '<div><i class="zyc-tip-dot" style="background:#f85149"></i>15m: <b>' + p.load15 + '</b></div>';
        }
        zycChartRegister('zyc-cpu-chart', {
            W: W, H: H, padL: padL, padR: padR, padT: padT, padB: padB,
            usableW: usableW, points: points, dots: ['load1', 'load5', 'load15'],
            yFor: yForCpu, fmtTip: fmtTipCpu
        });
    }

    function zycStatsFmtRate(bps) {
        if (bps < 1024) return bps.toFixed(0) + ' B';
        if (bps < 1048576) return (bps / 1024).toFixed(1) + ' KB';
        return (bps / 1048576).toFixed(2) + ' MB';
    }

    function zycStatsDrawNetChart(svgEl, points) {
        if (!svgEl || !points.length) return;
        var W = 280, H = 50, padL = 24, padR = 4, padT = 4, padB = 14;
        var usableW = W - padL - padR, usableH = H - padT - padB;

        var maxRate = 1;
        points.forEach(function (p) {
            if (p.rxr > maxRate) maxRate = p.rxr;
            if (p.txr > maxRate) maxRate = p.txr;
        });
        // 向上取整到可读刻度
        if (maxRate < 1024) maxRate = 1024;
        else if (maxRate < 1048576) maxRate = 1048576;
        else maxRate = 1048576 * Math.ceil(maxRate / 1048576);

        function yFor(v) {
            return padT + usableH - (Math.min(maxRate, v) / maxRate) * usableH;
        }

        var parts = ['<g class="axis-y">'];
        for (var t = 0; t <= maxRate; t += Math.max(1, Math.floor(maxRate / 4))) {
            var tt = Math.min(maxRate, +t);
            var yy = yFor(tt);
            parts.push('<line x1="' + padL + '" y1="' + yy + '" x2="' + (W - padR) + '" y2="' + yy + '" class="grid"/>');
            parts.push('<text x="' + (padL - 3) + '" y="' + (yy + 3) + '" text-anchor="end" class="tick-label">' + zycStatsFmtRate(tt) + '</text>');
        }
        if (parts[parts.length - 1] !== ('<text x="' + (padL - 3) + '" y="' + (yFor(maxRate) + 3) + '" text-anchor="end" class="tick-label">' + zycStatsFmtRate(maxRate) + '</text>')) {
            parts.push('<text x="' + (padL - 3) + '" y="' + (yFor(maxRate) + 3) + '" text-anchor="end" class="tick-label">' + zycStatsFmtRate(maxRate) + '</text>');
        }
        parts.push('</g>');

        function lineFor(key, cls) {
            var pts = [];
            points.forEach(function (p, i) {
                var x = padL + (usableW * i / Math.max(1, points.length - 1));
                var y = yFor(p[key]);
                pts.push(x.toFixed(1) + ',' + y.toFixed(1));
            });
            return '<polyline points="' + pts.join(' ') + '" class="net-line net-' + key + '"/>';
        }
        // 注：rxr 字段已存服务器 TX（用户下载），txr 字段已存服务器 RX（用户上传）
        // 绿色=↓入=用户下载=rxr，紫色=↑出=用户上传=txr
        parts.push(lineFor('rxr', 'rx'));
        parts.push(lineFor('txr', 'tx'));

        var xl1 = padL + (usableW * 0 / Math.max(1, points.length - 1));
        var xl2 = padL + (usableW * 0.5 / Math.max(1, points.length - 1));
        var xl3 = padL + usableW;
        function tsLabel(ts) {
            var d = new Date(ts * 1000);
            return d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0');
        }
        parts.push('<text x="' + xl1 + '" y="' + (H - 2) + '" text-anchor="start" class="tick-label">' + (points[0] ? tsLabel(points[0].ts) : '') + '</text>');
        parts.push('<text x="' + xl2 + '" y="' + (H - 2) + '" text-anchor="middle" class="tick-label">' + (points[Math.floor(points.length/2)] ? tsLabel(points[Math.floor(points.length/2)].ts) : '') + '</text>');
        parts.push('<text x="' + xl3 + '" y="' + (H - 2) + '" text-anchor="end" class="tick-label">' + (points[points.length - 1] ? tsLabel(points[points.length - 1].ts) : '') + '</text>');

        svgEl.innerHTML = parts.join('');

        // 注册 hover 交互
        function fmtTipNet(p) {
            var d = new Date(p.ts * 1000);
            var t = d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0') + ':' + d.getSeconds().toString().padStart(2, '0');
            return '<div class="zyc-tip-time">' + t + '</div>' +
                   '<div><i class="zyc-tip-dot" style="background:#22c55e"></i>下行: <b>' + zycStatsFmtRate(p.rxr) + '/s</b></div>' +
                   '<div><i class="zyc-tip-dot" style="background:#a855f7"></i>上行: <b>' + zycStatsFmtRate(p.txr) + '/s</b></div>';
        }
        zycChartRegister('zyc-net-chart', {
            W: W, H: H, padL: padL, padR: padR, padT: padT, padB: padB,
            usableW: usableW, points: points, dots: ['rxr', 'txr'],
            yFor: yFor, fmtTip: fmtTipNet
        });
    }

    function zycStatsRefresh() {
        var p = zycStats.period;
        fetch(STATS_URL + '?action=read&t=' + p + '&_=' + Date.now(), { cache: 'no-store' })
            .then(function (r) { return r.json(); })
            .then(function (d) {
                zycStats.data = d;
                var unit = zycStats.unit;

                var rxEl = document.getElementById('zyc-stats-rx');
                var txEl = document.getElementById('zyc-stats-tx');
                if (rxEl) rxEl.textContent = zycStatsFmt(d.rxBytes || 0, unit);
                if (txEl) txEl.textContent = zycStatsFmt(d.txBytes || 0, unit);

                // 流量提示
                var hintEl = document.getElementById('zyc-stats-hint');
                if (hintEl && d.firstTs && d.lastTs) {
                    var now = d.lastTs || Date.now() / 1000;
                    var span = Math.round((now - d.firstTs) / 60);
                    var rxPerMin = d.rxBytes > 0 ? (d.rxBytes / Math.max(1, span)) : 0;
                    var txPerMin = d.txBytes > 0 ? (d.txBytes / Math.max(1, span)) : 0;
                    hintEl.textContent = (p === 4 ? '近 4 小时' : '近 24 小时') + '  ·  均速  下行' + zycStatsFmt(rxPerMin, unit) + '/分  上行' + zycStatsFmt(txPerMin, unit) + '/分';
                }

                // CPU 图
                var svgEl = document.getElementById('zyc-cpu-chart');
                var cpuHint = document.getElementById('zyc-cpu-hint');
                if (d.cpu && d.cpu.length > 0) {
                    zycStatsDrawChart(svgEl, d.cpu, d.cpuCores || 1);
                    // 提示：当前 load1
                    var lastCpu = d.cpu[d.cpu.length - 1];
                    if (cpuHint) {
                        var cores = d.cpuCores || 1;
                        var status = lastCpu.load1 > cores ? '⚠ 负载偏高' : '✓ 负载正常';
                        cpuHint.textContent = '当前负载 1m=' + lastCpu.load1 + '  5m=' + lastCpu.load5 + '  15m=' + lastCpu.load15 + '  ' + status;
                    }
                } else {
                    if (svgEl) svgEl.innerHTML = '<text x="140" y="34" text-anchor="middle" class="chart-empty">等待数据…</text>';
                    if (cpuHint) cpuHint.textContent = '等待数据…';
                }

                // 流量速率图
                var netSvgEl = document.getElementById('zyc-net-chart');
                var netHintEl = document.getElementById('zyc-net-hint');
                if (d.net && d.net.length >= 2) {
                    zycStatsDrawNetChart(netSvgEl, d.net);
                    // 提示：当前速率
                    var lastNet = d.net[d.net.length - 1];
                    if (netHintEl) {
                        netHintEl.textContent = '当前速率  下行 ' + zycStatsFmtRate(lastNet.rxr) + '/s  上行 ' + zycStatsFmtRate(lastNet.txr) + '/s';
                    }
                } else {
                    if (netSvgEl) netSvgEl.innerHTML = '<text x="140" y="28" text-anchor="middle" class="chart-empty">等待数据…</text>';
                    if (netHintEl) netHintEl.textContent = '等待数据…';
                }
            })
            .catch(function () {
                var hintEl = document.getElementById('zyc-stats-hint');
                if (hintEl) hintEl.textContent = '计量接口暂不可用';
            });
    }

    function zycStatsReport() {
        fetch(STATS_URL + '?action=record&_=' + Date.now(), { cache: 'no-store' });
    }

    // 时段切换
    document.querySelectorAll('.zyc-stats-tab').forEach(function (btn) {
        btn.addEventListener('click', function () {
            document.querySelectorAll('.zyc-stats-tab').forEach(function (b) { b.classList.remove('active'); });
            btn.classList.add('active');
            zycStats.period = parseInt(btn.getAttribute('data-period'), 10);
            zycStatsRefresh();
        });
    });

    // 单位切换
    document.querySelectorAll('.zyc-unit-tab').forEach(function (btn) {
        btn.addEventListener('click', function () {
            document.querySelectorAll('.zyc-unit-tab').forEach(function (b) { b.classList.remove('active'); });
            btn.classList.add('active');
            zycStats.unit = btn.getAttribute('data-unit');
            if (zycStats.data) zycStatsRefresh();
        });
    });

    zycStatsRefresh();
    if (zycStats.refreshTimer) clearInterval(zycStats.refreshTimer);
    zycStats.refreshTimer = setInterval(zycStatsRefresh, 30000);
    // 顺便后台记录一次快照
    zycStatsReport();
    setInterval(zycStatsReport, 60000);
    <?php endif; ?>
})();
</script>