<script lang="ts">
  // StatusPill — v0.1 UI-hardening deliverable (section 10: "Status labels everywhere").
  //
  // Renders a small rounded-full pill with a leading dot + visible text label for
  // every async / transcription state in Lumotia. Colour is SUPPLEMENTARY — the
  // text label is always visible (WCAG perceivable).
  //
  // Animation (pulse on recording) honours prefers-reduced-motion via both the
  // global html.reduce-motion class (set by preferences.svelte.js) and a plain
  // @media query so it works even before that class is applied.

  type Status =
    | 'ready'
    | 'recording'
    | 'paused'
    | 'transcribing'
    | 'cleaning'
    | 'extracting-tasks'
    | 'saved'
    | 'exported'
    | 'needs-review'
    | 'failed-safely';

  let { status, label = undefined }: { status: Status; label?: string } = $props();

  const DEFAULT_LABELS: Record<Status, string> = {
    'ready':           'Ready',
    'recording':       'Recording',
    'paused':          'Paused',
    'transcribing':    'Transcribing',
    'cleaning':        'Cleaning',
    'extracting-tasks':'Extracting tasks',
    'saved':           'Saved',
    'exported':        'Exported',
    'needs-review':    'Needs review',
    'failed-safely':   'Failed safely',
  };

  // Tailwind bg classes for the leading dot.
  // Colour rationale (from semantic palette + existing DictationPage usage):
  //   ready            → neutral (text-tertiary, no semantic colour — idle state)
  //   recording        → danger  (#e87171 — matches page.statusColor="#e87171" in DictationPage)
  //   paused           → warning (#e8c86e — honey)
  //   transcribing     → accent  (progress / in-flight, uses brand warm accent)
  //   cleaning         → accent  (LLM in flight — same bucket as transcribing)
  //   extracting-tasks → accent  (LLM in flight)
  //   saved            → success (#7ec89a — moss green)
  //   exported         → success
  //   needs-review     → warning (#e8c86e — soft signal, data still editable)
  //   failed-safely    → danger  (#e87171 — failure, but labelled "safely" in copy)
  const DOT_CLASS: Record<Status, string> = {
    'ready':           'bg-text-tertiary',
    'recording':       'bg-danger dot-pulse',
    'paused':          'bg-warning',
    'transcribing':    'bg-accent dot-pulse',
    'cleaning':        'bg-accent dot-pulse',
    'extracting-tasks':'bg-accent dot-pulse',
    'saved':           'bg-success',
    'exported':        'bg-success',
    'needs-review':    'bg-warning',
    'failed-safely':   'bg-danger',
  };

  let displayLabel = $derived(label ?? DEFAULT_LABELS[status]);
  let dotClass     = $derived(DOT_CLASS[status]);
</script>

<!-- aria-live="polite": screen readers announce state changes without interrupting -->
<span
  class="pill"
  aria-live="polite"
  role="status"
>
  <span class="dot {dotClass}"></span>
  <span class="pill-label">{displayLabel}</span>
</span>

<style>
  .pill {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;           /* 6px */
    padding: 2px 8px 2px 6px;
    border-radius: 9999px;
    background: var(--bg-elevated, rgba(255,255,255,0.06));
    border: 1px solid var(--border-subtle);
    font: 500 11px/1 var(--font-body);
    color: var(--text-secondary);
    white-space: nowrap;
    user-select: none;
  }

  .dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 9999px;
    flex-shrink: 0;
  }

  /* Pulse animation for active-process states (recording, transcribing, cleaning, extracting) */
  @keyframes dot-pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.35; }
  }

  .dot-pulse {
    animation: dot-pulse 1.4s ease-in-out infinite;
  }

  /* Honour prefers-reduced-motion via @media (covers cold load before
     preferences.svelte.js sets html.reduce-motion) */
  @media (prefers-reduced-motion: reduce) {
    .dot-pulse {
      animation: none;
    }
  }

  /* Also honour the class-based gate set by preferences.svelte.js */
  :global(html.reduce-motion) .dot-pulse {
    animation: none;
  }
</style>
