<script lang="ts">
  import { formatMetricValue } from "../format";
  import type { UiTelemetryCard } from "../types";
  import IconGlyph from "./IconGlyph.svelte";

  let { card }: { card: UiTelemetryCard } = $props();

  let progress = $derived(resolveProgress(card));
  let value = $derived(formatMetricValue(card.value));
</script>

<article class="telemetry-card" data-severity={card.severity} data-model-id={card.id}>
  <header>
    {#if card.icon}
      <IconGlyph name={card.icon} size="sm" />
    {/if}
    <h3>{card.label}</h3>
  </header>
  <strong>{value}</strong>
  {#if progress !== null}
    <div class="telemetry-card__bar" aria-hidden="true">
      <span style={`--metric-progress: ${progress}%`}></span>
    </div>
  {/if}
  {#if card.sparkline?.length}
    <svg class="telemetry-card__sparkline" viewBox="0 0 100 24" aria-hidden="true">
      <polyline points={sparklinePoints(card.sparkline)} />
    </svg>
  {/if}
  {#if card.detail || card.description}
    <p>{card.detail || card.description}</p>
  {/if}
</article>

<style>
  .telemetry-card {
    display: grid;
    min-height: 7.15rem;
    border: var(--ui-border);
    background: linear-gradient(180deg, rgba(13, 15, 14, 0.82), rgba(2, 3, 2, 0.92));
    padding: var(--ui-space-3);
    color: var(--ui-color-text);
    gap: var(--ui-space-2);
  }

  .telemetry-card[data-severity="warning"] {
    border-color: color-mix(in srgb, var(--ui-color-warning), transparent 42%);
  }

  .telemetry-card[data-severity="danger"] {
    border-color: color-mix(in srgb, var(--ui-color-danger), transparent 22%);
    color: var(--ui-color-danger);
  }

  .telemetry-card[data-severity="stale"],
  .telemetry-card[data-severity="unavailable"] {
    color: var(--ui-color-stale);
  }

  .telemetry-card[data-severity="loading"] {
    color: var(--ui-color-accent);
  }

  .telemetry-card[data-severity="loading"] .telemetry-card__bar span {
    min-width: 1.25rem;
  }

  header {
    display: flex;
    min-width: 0;
    align-items: center;
    gap: var(--ui-space-2);
  }

  h3,
  p {
    margin: 0;
  }

  h3 {
    overflow-wrap: anywhere;
    color: inherit;
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0;
    text-transform: uppercase;
  }

  strong {
    font-family: var(--ui-font-display);
    font-size: clamp(2rem, 4vw, 3rem);
    font-weight: 800;
    letter-spacing: 0;
    line-height: 0.82;
  }

  p {
    color: var(--ui-color-muted);
    font-size: 0.67rem;
    line-height: 1.2;
    text-transform: uppercase;
  }

  .telemetry-card__bar {
    height: 0.35rem;
    border: var(--ui-border);
    background: #030403;
  }

  .telemetry-card__bar span {
    display: block;
    width: var(--metric-progress);
    height: 100%;
    background: currentColor;
  }

  .telemetry-card__sparkline {
    width: 100%;
    height: 1.5rem;
    color: var(--ui-color-accent);
  }

  .telemetry-card__sparkline polyline {
    fill: none;
    stroke: currentColor;
    stroke-linecap: square;
    stroke-linejoin: miter;
    stroke-width: 2;
  }
</style>

<script lang="ts" module>
  import { clampPercent } from "../format";

  function resolveProgress(card: {
    progress?: number;
    value: { kind: string; value: number | string };
  }): number | null {
    if (typeof card.progress === "number") return clampPercent(card.progress);
    if (card.value.kind !== "percent") return null;

    const progress = Number(card.value.value);
    return Number.isFinite(progress) ? clampPercent(progress) : null;
  }

  function sparklinePoints(values: number[]): string {
    const max = Math.max(...values, 1);
    const step = values.length > 1 ? 100 / (values.length - 1) : 100;

    return values
      .map((value, index) => {
        const x = index * step;
        const y = 24 - (Math.max(0, value) / max) * 22;
        return `${x.toFixed(2)},${y.toFixed(2)}`;
      })
      .join(" ");
  }
</script>
