<script>
  import { chat } from "../chat.svelte.js";

  let { version = "" } = $props();

  const running = $derived(chat.turn?.status === "running" && chat.turn?.session_id === chat.currentSessionId);
  const turnLabel = $derived(running ? `Turn ${String(chat.turn?.id ?? "").slice(0, 6).toUpperCase()}` : "");
  const stats = $derived(chat.currentStats);
  const context = $derived(stats?.context ?? null);
  const lifetime = $derived(stats?.lifetime_usage ?? null);
  const percent = $derived(context?.effective_window_tokens
    ? context.used_tokens / context.effective_window_tokens * 100
    : 0);
  const boundedPercent = $derived(Math.max(0, Math.min(percent, 100)));
  const thresholdPercent = $derived(context?.effective_window_tokens
    ? context.compression_threshold_tokens / context.effective_window_tokens * 100
    : 100);
  const boundedThresholdPercent = $derived(Math.max(0, Math.min(thresholdPercent, 100)));
  const pressure = $derived(percent >= 100 ? "danger" : percent > thresholdPercent ? "warning" : "normal");

  function compactTokens(value) {
    if (!Number.isFinite(value)) return "—";
    if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(value >= 10_000_000 ? 1 : 2)}M`;
    if (value >= 1_000) return `${(value / 1_000).toFixed(value >= 100_000 ? 0 : 1)}k`;
    return String(value);
  }

  function exactTokens(value) {
    return Number.isFinite(value) ? new Intl.NumberFormat("zh-CN").format(value) : "—";
  }

  function sourceLabel(value) {
    return value === "observed" ? "Provider 实测" : "字符估算";
  }

  function trackedSince(value) {
    if (!Number.isFinite(value)) return "尚无已提交 Turn";
    return `自 ${new Date(value).toLocaleString("zh-CN", { hour12: false })}`;
  }
</script>

<details class="spine-shell mono" data-pressure={pressure} title={version}>
  <summary class="spine">
    {#if running}
      <span class="spine-turn active"><i class="pulse-dot active"></i>{turnLabel} · 生成中</span>
    {:else}
      <span class="spine-turn idle"><i class="pulse-dot idle"></i>{chat.connected ? "空闲" : "重连中"}</span>
    {/if}

    {#if context}
      <span class="context-readout">
        <span class="context-label">上下文</span>
        <span
          class="context-rail"
          role="progressbar"
          aria-label="当前上下文窗口占用"
          aria-valuemin="0"
          aria-valuemax="100"
          aria-valuenow={Math.round(boundedPercent)}
          style={`--context-fill: ${boundedPercent}%; --context-threshold: ${boundedThresholdPercent}%`}
        ><i></i><b></b></span>
        <span class="context-value">{compactTokens(context.used_tokens)} / {compactTokens(context.effective_window_tokens)}</span>
        <strong class="context-percent">{percent.toFixed(1)}%</strong>
      </span>
      <span class="usage-summary"><span>↑ {compactTokens(lifetime?.input_tokens)}</span><span>↓ {compactTokens(lifetime?.output_tokens)}</span></span>
    {:else}
      <span class="context-pending">等待会话统计</span>
    {/if}

    <span class="spine-right" class:spine-ok={chat.connected} class:spine-down={!chat.connected}>
      {chat.connected ? "已连接" : "重连中"}
    </span>
  </summary>

  {#if stats && context && lifetime}
    <section class="stats-panel" aria-label="会话 Token 与上下文详情">
      <header>
        <div><span>当前上下文</span><strong>{percent.toFixed(1)}%</strong></div>
        <small>{sourceLabel(context.source)}</small>
      </header>
      <div class="detail-rail" role="presentation" style={`--context-fill: ${boundedPercent}%; --context-threshold: ${boundedThresholdPercent}%`}><i></i><b></b></div>
      <dl class="context-grid">
        <div><dt>占用</dt><dd>{exactTokens(context.used_tokens)} / {exactTokens(context.effective_window_tokens)}</dd></div>
        <div><dt>剩余</dt><dd>{exactTokens(context.remaining_tokens)}</dd></div>
        <div><dt>预留（有效 / 配置）</dt><dd>{exactTokens(context.reserve_tokens)} / {exactTokens(context.configured_reserve_tokens)}</dd></div>
        <div><dt>近期保留（有效 / 配置）</dt><dd>{exactTokens(context.effective_keep_recent_tokens)} / {exactTokens(context.configured_keep_recent_tokens)}</dd></div>
        <div><dt>压缩阈值</dt><dd>{exactTokens(context.compression_threshold_tokens)}</dd></div>
        <div><dt>最近实测</dt><dd>{exactTokens(context.last_observed_prompt_tokens)}</dd></div>
        {#if context.active_checkpoint_id}
          <div><dt>Checkpoint</dt><dd title={context.active_checkpoint_id}>#{context.checkpoint_generation} · {exactTokens(context.checkpoint_tokens_before)} → {exactTokens(context.checkpoint_tokens_after)}{context.checkpoint_degraded ? " · 降级" : ""}</dd></div>
        {/if}
      </dl>

      <div class="usage-heading"><span>会话累计</span><small>Provider 报告 · 已提交 Turns</small></div>
      <dl class="usage-grid">
        <div><dt>输入</dt><dd>{exactTokens(lifetime.input_tokens)}</dd></div>
        <div><dt>输出</dt><dd>{exactTokens(lifetime.output_tokens)}</dd></div>
        <div><dt>缓存输入</dt><dd>{exactTokens(lifetime.cached_input_tokens)}</dd></div>
        <div><dt>请求 / Turns</dt><dd>{exactTokens(lifetime.request_count)} / {exactTokens(lifetime.turn_count)}</dd></div>
      </dl>
      <footer>{stats.provider} / {stats.model}<span>{trackedSince(lifetime.tracked_since)}</span></footer>
    </section>
  {/if}
</details>

<style>
  .spine-shell { position: relative; margin-left: auto; min-width: 0; }
  .spine-shell summary { list-style: none; }
  .spine-shell summary::-webkit-details-marker { display: none; }
  .spine { display: flex; align-items: center; gap: 10px; min-height: 32px; padding: 0 11px; border: 1px solid var(--line); border-radius: 6px; font-size: 11px; color: var(--text-soft); background: var(--panel-2); font-variant-numeric: tabular-nums; cursor: pointer; user-select: none; }
  .spine:hover { border-color: var(--line-strong); background: var(--color-neutral-background-4); }
  .spine:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .spine-turn { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; white-space: nowrap; }
  .spine-turn.active { color: var(--accent); }
  .spine-turn.idle, .spine-ok { color: var(--signal); }
  .context-readout { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
  .context-label { color: var(--muted); }
  .context-rail, .detail-rail { position: relative; overflow: hidden; background: var(--color-neutral-background-4); }
  .context-rail { width: 74px; height: 6px; border-radius: 99px; }
  .context-rail i, .detail-rail i { position: absolute; inset: 0 auto 0 0; width: var(--context-fill); background: var(--accent); }
  .context-rail b, .detail-rail b { position: absolute; inset: 0 auto 0 var(--context-threshold); width: 1px; background: var(--warning); }
  .context-value { color: var(--text-soft); }
  .context-percent { color: var(--accent); font-weight: 700; }
  [data-pressure="warning"] .context-percent, [data-pressure="warning"] .context-rail i, [data-pressure="warning"] .detail-rail i { color: var(--warning); background: var(--warning); }
  [data-pressure="danger"] .context-percent, [data-pressure="danger"] .context-rail i, [data-pressure="danger"] .detail-rail i { color: var(--danger); background: var(--danger); }
  .usage-summary { display: inline-flex; gap: 8px; padding-left: 10px; border-left: 1px solid var(--line); color: var(--muted); white-space: nowrap; }
  .spine-right { padding-left: 10px; border-left: 1px solid var(--line); white-space: nowrap; }
  .spine-down { color: var(--danger); }
  .context-pending { color: var(--muted); }

  .stats-panel { position: absolute; z-index: 30; top: calc(100% + 8px); right: 0; width: min(390px, calc(100vw - 28px)); padding: 17px; border: 1px solid var(--line-strong); border-radius: 10px; color: var(--text); background: var(--surface-acrylic); backdrop-filter: var(--acrylic-blur); -webkit-backdrop-filter: var(--acrylic-blur); box-shadow: var(--shadow-16); font-family: var(--font-ui); }
  .stats-panel header, .usage-heading, .stats-panel footer { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
  .stats-panel header div { display: flex; align-items: baseline; gap: 10px; }
  .stats-panel header span, .usage-heading span { font-size: 12px; font-weight: 700; }
  .stats-panel header strong { font-family: var(--font-mono); font-size: 21px; letter-spacing: -0.04em; }
  .stats-panel small, .stats-panel footer { color: var(--muted); font-size: 10px; }
  .detail-rail { height: 8px; margin: 12px 0 15px; border-radius: 99px; }
  .context-grid, .usage-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; margin: 0; overflow: hidden; border: 1px solid var(--line); border-radius: 8px; background: var(--line); }
  .context-grid div, .usage-grid div { min-width: 0; padding: 9px 10px; background: var(--panel); }
  dt { color: var(--muted); font-size: 10px; }
  dd { margin: 3px 0 0; overflow: hidden; font-family: var(--font-mono); font-size: 11px; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; }
  .usage-heading { margin: 16px 0 8px; }
  .stats-panel footer { margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--line); }
  .stats-panel footer span { text-align: right; }

  @media (max-width: 1180px) {
    .context-value, .usage-summary { display: none; }
    .context-rail { width: 58px; }
  }
  @media (max-width: 760px) {
    .spine-shell { margin-left: 0; }
    .spine { padding: 0 9px; }
    .spine-turn, .context-label, .context-rail, .spine-right, .context-pending { display: none; }
    .context-readout { gap: 4px; }
    .context-percent::before { content: "上下文 "; color: var(--muted); font-weight: 400; }
    .stats-panel { position: fixed; top: auto; right: 14px; bottom: 14px; left: 14px; width: auto; }
  }
  @media (prefers-reduced-motion: reduce) {
    .context-rail i, .detail-rail i { transition: none; }
  }
  @media (prefers-reduced-transparency: reduce) {
    .stats-panel { background: var(--overlay); backdrop-filter: none; -webkit-backdrop-filter: none; }
  }
</style>
