<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5">
    <title>巡检报告 - 服务监测</title>
    <style>
        :root {
            --primary:#2563eb; --primary-hover:#1d4ed8;
            --green:#16a34a; --yellow:#d97706; --red:#dc2626;
            --gray-50:#f9fafb; --gray-100:#f3f4f6; --gray-200:#e5e7eb;
            --gray-500:#6b7280; --gray-700:#374151; --gray-900:#111827;
        }
        * { box-sizing:border-box; margin:0; padding:0; }
        body { font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Microsoft YaHei",sans-serif; background:#f3f4f6; min-height:100vh; }
        .navbar { background:linear-gradient(135deg,#667eea 0%,#764ba2 100%); padding:14px 24px; display:flex; align-items:center; justify-content:space-between; }
        .navbar-left { display:flex; align-items:center; gap:14px; }
        .navbar-brand { color:#fff; font-size:18px; font-weight:700; text-decoration:none; }
        .navbar-module { color:rgba(255,255,255,.7); font-size:14px; }
        .navbar-home { background:rgba(255,255,255,.2); color:#fff; border:1px solid rgba(255,255,255,.35); padding:6px 14px; border-radius:8px; font-size:13px; font-weight:600; text-decoration:none; }
        .navbar-user { color:#fff; font-size:14px; }

        .container { max-width:960px; margin:0 auto; padding:28px 24px; }

        /* 报告头 */
        .report-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:18px; flex-wrap:wrap; gap:12px; }
        .report-meta h2 { font-size:20px; color:var(--gray-900); margin-bottom:4px; }
        .report-meta .sub { font-size:13px; color:var(--gray-500); }
        .export-wrap { position:relative; }
        .btn-export { background:var(--primary); color:#fff; border:none; padding:9px 18px; border-radius:8px; font-size:14px; font-weight:600; cursor:pointer; }
        .export-menu { display:none; position:absolute; right:0; top:44px; background:#fff; border:1px solid var(--gray-200); border-radius:8px; box-shadow:0 4px 16px rgba(0,0,0,.12); overflow:hidden; z-index:10; }
        .export-menu.show { display:block; }
        .export-menu a { display:block; padding:10px 20px; font-size:14px; color:var(--gray-700); text-decoration:none; }
        .export-menu a:hover { background:var(--gray-50); }

        /* 汇总卡片 */
        .summary-cards { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:24px; }
        .sum-card { background:#fff; border-radius:12px; padding:18px; text-align:center; border:1px solid var(--gray-200); }
        .sum-card .num { font-size:28px; font-weight:700; }
        .sum-card .label { font-size:13px; color:var(--gray-500); margin-top:4px; }
        .sum-total .num { color:var(--gray-900); }
        .sum-ok .num { color:var(--green); }
        .sum-warn .num { color:var(--yellow); }
        .sum-crit .num { color:var(--red); }

        /* 异常项 */
        .section-title { font-size:16px; font-weight:700; color:var(--gray-900); margin:24px 0 12px; display:flex; align-items:center; gap:8px; }
        .abnormal-box { background:#fff; border-radius:12px; border:1px solid var(--gray-200); overflow:hidden; }
        .abnormal-row { display:grid; grid-template-columns:24px 2fr 1fr 1fr 1fr auto; gap:12px; align-items:center; padding:12px 18px; border-bottom:1px solid var(--gray-100); font-size:14px; }
        .abnormal-row:last-child { border-bottom:none; }
        .ab-icon { text-align:center; }
        .ab-crit { color:var(--red); } .ab-warn { color:var(--yellow); }
        .ab-name { font-weight:600; color:var(--gray-900); }
        .ab-module { font-size:12px; color:var(--gray-500); }
        .ab-value { font-weight:600; }
        .ab-threshold { font-size:13px; color:var(--gray-500); }
        .btn-fix { background:#fef3c7; color:#92400e; border:none; padding:5px 12px; border-radius:6px; font-size:12px; font-weight:600; cursor:pointer; }

        /* 分模块折叠 */
        .module-block { background:#fff; border-radius:12px; border:1px solid var(--gray-200); margin-bottom:12px; overflow:hidden; }
        .module-header { display:flex; align-items:center; gap:10px; padding:14px 18px; cursor:pointer; user-select:none; }
        .module-header:hover { background:var(--gray-50); }
        .module-toggle { font-size:12px; color:var(--gray-500); transition:transform .2s; flex-shrink:0; }
        .module-block.open .module-toggle { transform:rotate(90deg); }
        .module-title { font-weight:700; color:var(--gray-900); flex:1; }
        .module-mini { display:flex; gap:8px; font-size:13px; }
        .module-body { max-height:0; overflow:hidden; transition:max-height .35s ease; }
        .module-block.open .module-body { max-height:5000px; }

        /* 检测项行 */
        .item-row { display:grid; grid-template-columns:2fr 1.5fr 1fr 1fr; gap:12px; padding:10px 18px; border-top:1px solid var(--gray-100); font-size:14px; }
        .item-name { color:var(--gray-700); }
        .item-value { color:var(--gray-900); font-weight:600; word-break:break-all; }
        .item-threshold { color:var(--gray-500); font-size:13px; }
        .item-status { font-weight:600; }
        .stt-正常 { color:var(--green); } .stt-警告 { color:var(--yellow); } .stt-严重 { color:var(--red); }

        /* 进程列表特殊样式 */
        .process-row { border-top:1px solid var(--gray-100); padding:10px 18px; }
        .process-summary { font-weight:600; color:var(--gray-900); margin-bottom:8px; display:flex; align-items:center; gap:8px; }
        .process-toggle-btn { background:var(--gray-100); border:1px solid var(--gray-200); padding:3px 10px; border-radius:6px; font-size:12px; cursor:pointer; color:var(--gray-700); }
        .process-toggle-btn:hover { background:var(--gray-200); }
        .process-table-wrap { display:none; margin-top:8px; overflow-x:auto; }
        .process-table-wrap.show { display:block; }
        .process-table { width:100%; border-collapse:collapse; font-size:13px; }
        .process-table th { background:var(--gray-50); padding:8px 10px; text-align:left; font-weight:600; color:var(--gray-700); border-bottom:2px solid var(--gray-200); }
        .process-table td { padding:6px 10px; border-bottom:1px solid var(--gray-100); color:var(--gray-900); }
        .process-table tr:hover td { background:var(--gray-50); }
        .process-table .cmd-cell { font-family:monospace; font-size:12px; max-width:300px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

        /* 长值展开 */
        .long-value { cursor:pointer; color:var(--primary); }
        .long-value .truncated { display:inline; }
        .long-value .full { display:none; }
        .long-value.expanded .truncated { display:none; }
        .long-value.expanded .full { display:inline; white-space:pre-wrap; word-break:break-all; }

        .footer { text-align:center; padding:20px; color:var(--gray-500); font-size:12px; }

        @media screen and (max-width:768px) {
            .container { padding:20px 14px; }
            .navbar-module { display:none; }
            .summary-cards { grid-template-columns:repeat(2,1fr); }
            .abnormal-row { grid-template-columns:24px 1fr auto; gap:6px; }
            .abnormal-row .ab-threshold, .abnormal-row .ab-module { display:none; }
            .item-row { grid-template-columns:1fr 1fr; gap:6px; }
            .process-table { font-size:11px; }
            .process-table .cmd-cell { max-width:150px; }
        }
    </style>
</head>
<body>
    <div class="navbar">
        <div class="navbar-left">
            <a href="/" class="navbar-brand">🛠️ 运行维护平台</a>
            <span class="navbar-module">/ 服务监测 / 报告</span>
            <a href="/service-monitor" class="navbar-home">← 返回</a>
        </div>
        <div class="navbar-user">{{ user.username }}（{{ '管理员' if user.role == 'admin' else '用户' }}）</div>
    </div>

    <div class="container">
        <div class="report-head">
            <div class="report-meta">
                <h2>{{ '🖥️' if report.target_type == 'local' else '🌐' }} {{ report.target_name }}</h2>
                <div class="sub">
                    {{ '⚡ 快速巡检' if report.suite == 'quick' else '🔍 全量巡检' }} ·
                    {{ (report.started_at or '').replace('T', ' ') }} ~ {{ (report.finished_at or '')[11:19] }}
                </div>
            </div>
            <div class="export-wrap">
                <button class="btn-export" onclick="toggleExport()">⬇ 导出 ▾</button>
                <div class="export-menu" id="export-menu">
                    <a href="/api/service-monitor/reports/{{ report.id }}/export?format=md">导出 Markdown</a>
                    <a href="/api/service-monitor/reports/{{ report.id }}/export?format=json">导出 JSON</a>
                </div>
            </div>
        </div>

        <!-- 汇总卡片 -->
        {% set s = report.summary or {} %}
        <div class="summary-cards">
            <div class="sum-card sum-total"><div class="num">{{ s.total or 0 }}</div><div class="label">总检测项</div></div>
            <div class="sum-card sum-ok"><div class="num">{{ s['正常'] or 0 }}</div><div class="label">正常</div></div>
            <div class="sum-card sum-warn"><div class="num">{{ s['警告'] or 0 }}</div><div class="label">警告</div></div>
            <div class="sum-card sum-crit"><div class="num">{{ s['严重'] or 0 }}</div><div class="label">严重</div></div>
        </div>

        <!-- 异常项置顶 -->
        {% set ns = namespace(abnormal=[]) %}
        {% for m in report.modules %}
            {% for it in m['items'] %}
                {% if it.status in ['警告', '严重'] %}
                    {% set _ = ns.abnormal.append((m.name, it)) %}
                {% endif %}
            {% endfor %}
        {% endfor %}

        {% if ns.abnormal %}
        <div class="section-title">⚠️ 异常项（{{ ns.abnormal | length }}）</div>
        <div class="abnormal-box">
            {% for mod_name, it in ns.abnormal %}
            <div class="abnormal-row">
                <span class="ab-icon {{ 'ab-crit' if it.status == '严重' else 'ab-warn' }}">{{ '✗' if it.status == '严重' else '⚠' }}</span>
                <span><span class="ab-name">{{ it.name }}</span><br><span class="ab-module">{{ mod_name }}</span></span>
                <span class="ab-value {{ 'ab-crit' if it.status == '严重' else 'ab-warn' }}">{{ it.value }}</span>
                <span class="ab-threshold">{{ it.threshold or '-' }}</span>
                <span class="item-status stt-{{ it.status }}">{{ it.status }}</span>
                {% if user.role == 'admin' %}
                <button class="btn-fix" onclick="tryFix('{{ it.key }}')">修复</button>
                {% else %}
                <span></span>
                {% endif %}
            </div>
            {% endfor %}
        </div>
        {% else %}
        <div class="section-title">✅ 全部正常</div>
        {% endif %}

        <!-- 分模块折叠明细 -->
        <div class="section-title">📋 检测明细（点击展开）</div>
        {% for m in report.modules %}
        {% set ms = m.summary or {} %}
        {% set has_abnormal = (ms.get('警告', 0) or ms.get('严重', 0)) %}
        <div class="module-block{{ ' open' if has_abnormal else '' }}" data-module="{{ m.id }}">
            <div class="module-header" onclick="toggleModule(this)">
                <span class="module-toggle">▶</span>
                <span class="module-title">{{ m.name }}</span>
                <span class="module-mini">
                    {% if ms.get('正常') %}<span class="stt-正常">✓{{ ms['正常'] }}</span>{% endif %}
                    {% if ms.get('警告') %}<span class="stt-警告">⚠{{ ms['警告'] }}</span>{% endif %}
                    {% if ms.get('严重') %}<span class="stt-严重">✗{{ ms['严重'] }}</span>{% endif %}
                </span>
            </div>
            <div class="module-body">
                {% for it in m['items'] %}
                    {# 判断是否为进程列表项 #}
                    {% if it.key.endswith('_PROCESS_LIST') or it.key.endswith('_PROCESSES_DETAIL') %}
                <div class="process-row">
                    <div class="process-summary">
                        <span>{{ it.name }}</span>
                        <button class="process-toggle-btn" onclick="toggleProcessTable(this)">展开详情</button>
                    </div>
                    <div class="process-table-wrap">
                        <table class="process-table">
                            <thead><tr><th>用户</th><th>PID</th><th>CPU%</th><th>内存%</th><th>命令</th></tr></thead>
                            <tbody>
                                {% for line in it.value.split('|') %}
                                {% set parts = line.strip().split() %}
                                {% if parts|length >= 5 %}
                                <tr>
                                    <td>{{ parts[0] }}</td>
                                    <td>{{ parts[1] }}</td>
                                    <td>{{ parts[2] }}</td>
                                    <td>{{ parts[3] }}</td>
                                    <td class="cmd-cell" title="{{ ' '.join(parts[4:]) }}">{{ ' '.join(parts[4:]) }}</td>
                                </tr>
                                {% endif %}
                                {% endfor %}
                            </tbody>
                        </table>
                    </div>
                </div>
                    {% else %}
                <div class="item-row">
                    <span class="item-name">{{ it.name }}</span>
                    {% if it.value|length > 80 %}
                    <span class="item-value long-value" onclick="this.classList.toggle('expanded')">
                        <span class="truncated">{{ it.value[:80] }}…</span>
                        <span class="full">{{ it.value }}</span>
                    </span>
                    {% else %}
                    <span class="item-value">{{ it.value }}</span>
                    {% endif %}
                    <span class="item-threshold">{{ it.threshold or '-' }}</span>
                    <span class="item-status stt-{{ it.status }}">{{ it.status }}</span>
                </div>
                    {% endif %}
                {% endfor %}
            </div>
        </div>
        {% endfor %}
    </div>

    <div class="footer">运行维护平台 · 服务监测模块</div>

    <script>
        function toggleExport() { document.getElementById('export-menu').classList.toggle('show'); }
        document.addEventListener('click', (e) => {
            if (!e.target.closest('.export-wrap')) document.getElementById('export-menu').classList.remove('show');
        });

        function toggleModule(header) {
            const block = header.parentElement;
            block.classList.toggle('open');
        }

        function toggleProcessTable(btn) {
            const wrap = btn.closest('.process-row').querySelector('.process-table-wrap');
            wrap.classList.toggle('show');
            btn.textContent = wrap.classList.contains('show') ? '收起详情' : '展开详情';
        }

        async function tryFix(key) {
            const r = await fetch('/api/service-monitor/fix', {method:'POST', headers:{'Content-Type':'application/json'}, credentials:'include', body: JSON.stringify({key})});
            const d = await r.json();
            alert(d.message || '修复能力开发中');
        }
    </script>
</body>
</html>
