<script>
  import { onMount } from "svelte";
  import { api, formatTime } from "../api.js";

  let report = $state(null);
  let error = $state("");
  let loading = $state(false);
  let checkedAt = $state(null);

  const counts = $derived.by(() => {
    const result = { pass: 0, warning: 0, fail: 0 };
    for (const check of report?.checks || []) {
      if (check.status in result) result[check.status] += 1;
    }
    return result;
  });

  const overallLabel = $derived(
    report?.overall === "healthy" ? "健康" : report?.overall === "degraded" ? "存在警告" : "检查失败"
  );

  const statusLabels = {
    pass: "通过",
    warning: "警告",
    fail: "失败"
  };

  const categoryLabels = {
    core: "核心",
    configured: "已配置功能",
    service: "系统服务"
  };

  async function runCheck() {
    if (loading) return;
    loading = true;
    error = "";
    try {
      report = await api("/api/health");
      checkedAt = Date.now();
    } catch (caught) {
      error = caught.message;
    } finally {
      loading = false;
    }
  }

  onMount(runCheck);
</script>

<div class="health-pane" aria-busy={loading}>
  <div class="panel health-summary" class:healthy={report?.overall === "healthy"} class:degraded={report?.overall === "degraded"} class:unhealthy={report?.overall === "unhealthy"}>
    <div class="summary-main">
      <span class="summary-mark" aria-hidden="true">{report?.overall === "healthy" ? "✓" : report?.overall === "degraded" ? "!" : report ? "×" : "…"}</span>
      <div>
        <span class="label-caps">Gateway 健康状态</span>
        <strong>{loading && !report ? "正在检查…" : report ? overallLabel : "尚未完成检查"}</strong>
        <small>
          {#if report}PicoBot v{report.version} · {report.checks?.length || 0} 项检查{:else}复用 picobot health 的只读诊断逻辑{/if}
        </small>
      </div>
    </div>
    <div class="summary-actions">
      {#if report}
        <div class="count-row" aria-label="检查结果统计">
          <span class="count pass">{counts.pass} 通过</span>
          <span class="count warning">{counts.warning} 警告</span>
          <span class="count fail">{counts.fail} 失败</span>
        </div>
      {/if}
      <button class="primary" onclick={runCheck} disabled={loading}>{loading ? "检查中…" : "重新检查"}</button>
    </div>
  </div>

  {#if error}
    <div class="health-error" role="alert">无法完成健康检查：{error}</div>
  {/if}

  {#if report}
    <div class="check-list" aria-live="polite">
      {#each report.checks || [] as check}
        <article class="panel check-card {check.status}">
          <span class="check-mark" aria-hidden="true">{check.status === "pass" ? "✓" : check.status === "warning" ? "!" : "×"}</span>
          <div class="check-content">
            <div class="check-heading">
              <strong>{check.name}</strong>
              <span class="badge {check.status === "pass" ? "ok" : check.status === "warning" ? "run" : "fail"}">{statusLabels[check.status] || check.status}</span>
              <span class="badge">{categoryLabels[check.category] || check.category}</span>
              <span class="requirement">{check.required ? "必需" : "可选"}</span>
            </div>
            <p>{check.detail}</p>
            {#if check.remediation}
              <div class="remediation"><b>建议</b><span>{check.remediation}</span></div>
            {/if}
          </div>
        </article>
      {/each}
    </div>
    <p class="health-footnote">上次检查：{formatTime(checkedAt)}。检查不会安装依赖、修改配置或连接模型服务。</p>
  {:else if !loading && !error}
    <div class="panel empty-health">点击“重新检查”获取当前运行环境的诊断结果。</div>
  {/if}
</div>

<style>
  .health-pane { min-width: 0; display: grid; gap: 14px; }
  .health-summary { min-height: 112px; display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 18px 20px; border-left: 4px solid var(--line-strong); }
  .health-summary.healthy { border-left-color: var(--signal); }
  .health-summary.degraded { border-left-color: var(--warning); }
  .health-summary.unhealthy { border-left-color: var(--danger); }
  .summary-main { min-width: 0; display: flex; align-items: center; gap: 14px; }
  .summary-mark { width: 42px; height: 42px; flex: 0 0 42px; display: grid; place-items: center; border-radius: 50%; color: var(--text-soft); background: var(--panel-2); font-size: 23px; font-weight: 700; }
  .healthy .summary-mark { color: var(--signal); background: var(--signal-soft); }
  .degraded .summary-mark { color: var(--warning); background: var(--warning-soft); }
  .unhealthy .summary-mark { color: var(--danger); background: var(--danger-soft); }
  .summary-main strong, .summary-main small { display: block; }
  .summary-main strong { margin-top: 4px; font-size: 20px; line-height: 28px; }
  .summary-main small { margin-top: 2px; color: var(--muted); font-size: 12px; }
  .summary-actions { display: flex; align-items: flex-end; flex-direction: column; gap: 12px; }
  .count-row { display: flex; gap: 12px; color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
  .count.pass { color: var(--signal); }
  .count.warning { color: var(--warning); }
  .count.fail { color: var(--danger); }
  .health-error { padding: 11px 13px; border: 1px solid var(--danger-border); border-radius: var(--radius); color: var(--danger); background: var(--danger-soft); font-size: 13px; }
  .check-list { display: grid; gap: 9px; }
  .check-card { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 11px; padding: 14px 16px; border-left: 3px solid var(--line-strong); }
  .check-card.warning { border-left-color: var(--warning); }
  .check-card.fail { border-left-color: var(--danger); }
  .check-mark { width: 28px; height: 28px; display: grid; place-items: center; border-radius: 50%; color: var(--signal); background: var(--signal-soft); font-weight: 700; }
  .warning .check-mark { color: var(--warning); background: var(--warning-soft); }
  .fail .check-mark { color: var(--danger); background: var(--danger-soft); }
  .check-content { min-width: 0; }
  .check-heading { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
  .check-heading strong { margin-right: 3px; font-size: 14px; overflow-wrap: anywhere; }
  .requirement { color: var(--muted); font-size: 11px; }
  .check-content p { margin: 7px 0 0; color: var(--text-soft); font-size: 13px; line-height: 20px; white-space: pre-wrap; overflow-wrap: anywhere; }
  .remediation { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px; margin-top: 9px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px; color: var(--text-soft); background: var(--panel-2); font-size: 12px; line-height: 18px; }
  .remediation b { color: var(--accent); }
  .health-footnote { margin: 0; color: var(--muted); font-size: 11px; text-align: right; }
  .empty-health { padding: 28px; color: var(--muted); text-align: center; }
  @media (max-width: 760px) {
    .health-summary { align-items: stretch; flex-direction: column; }
    .summary-actions { align-items: stretch; }
    .count-row { justify-content: space-between; }
  }
</style>
