<script lang="ts">
  /**
   * On-screen equivalents for every controller action (FR-3.19, FR-9.10), with
   * the keyboard shortcut shown on each so the rider learns them. Every press
   * flashes, because a rider needs to know the input registered (FR-9.9).
   */
  import { app } from '../lib/app.svelte';
  import { api } from '../lib/bridge';
  import { MODE_LABEL } from '../lib/format';

  const ride = $derived(app.ride);
  const running = $derived(ride?.status === 'running');
  /**
   * Before a ride starts, the gradient trim, the lap marker and End have
   * nothing to act on. The ride screen is showing a large Start button at that
   * point, and nine similar-looking buttons beside it only make it harder to
   * find.
   */
  const started = $derived(ride?.status === 'running' || ride?.status === 'paused');

  let flash = $state<string | null>(null);
  let flashTimer: ReturnType<typeof setTimeout> | null = null;

  $effect(() => {
    const ack = app.lastAck;
    if (!ack) return;
    flash = ack.action;
    if (flashTimer) clearTimeout(flashTimer);
    flashTimer = setTimeout(() => (flash = null), 220);
  });

  const grade = (d: number) => app.run(() => api.nudgeGradient(d));
</script>

<div class="bar">
  {#if started}
    <div class="group">
      <button class="btn" class:lit={flash === 'gradient'} onclick={() => grade(-0.5)}>
        <span class="glyph">−</span> Grade <span class="kbd">↓</span>
      </button>
      <button class="btn" class:lit={flash === 'gradient'} onclick={() => grade(0.5)}>
        <span class="glyph">+</span> Grade <span class="kbd">↑</span>
      </button>
      <button
        class="btn ghost"
        class:lit={flash === 'gradient-reset'}
        onclick={() => app.run(() => api.resetGradient())}
      >
        Zero <span class="kbd">0</span>
      </button>
    </div>
  {/if}

  <div class="group">
    <button class="btn" class:lit={flash === 'mode'} onclick={() => app.run(() => api.cycleMode())}>
      Mode: {MODE_LABEL[ride?.mode ?? 'ManualGrade']} <span class="kbd">M</span>
    </button>
    <button class="btn" onclick={() => (app.showProfiles = true)}>
      Route <span class="kbd">P</span>
    </button>
  </div>

  <div class="group right">
    {#if started}
      <button class="btn" class:lit={flash === 'lap'} onclick={() => app.run(() => api.markLap())}>
        Lap {ride?.lap ?? 1} <span class="kbd">L</span>
      </button>
    {/if}
    {#if running}
      <button class="btn" class:lit={flash === 'toggle-pause'} onclick={() => app.run(() => api.togglePause())}>
        Pause <span class="kbd">␣</span>
      </button>
    {:else}
      <button class="btn primary" onclick={() => app.run(() => api.start())}>
        {ride?.status === 'paused' ? 'Resume' : 'Start ride'} <span class="kbd">␣</span>
      </button>
    {/if}
    {#if started}
      <button class="btn danger" onclick={() => app.run(() => api.stop())}>End</button>
    {/if}
    <!-- The word, not just the key cap: on a touch device the cap is hidden
         (see app.css) and a button with nothing in it is unpressable. -->
    <button class="btn ghost" onclick={() => (app.showHelp = !app.showHelp)} title="Keyboard shortcuts">
      Help <span class="kbd">?</span>
    </button>
  </div>
</div>

<style>
  .bar {
    display: flex;
    align-items: center;
    gap: var(--gap);
    padding: 0.7rem var(--edge) 0.85rem;
    border-top: 1px solid var(--hairline);
    flex-wrap: wrap;
  }

  .group {
    display: flex;
    align-items: center;
    gap: 0.4rem;
  }

  .group.right {
    margin-left: auto;
  }

  /*
   * On a phone this is the only way to control the ride — there is no keyboard
   * behind it — so the buttons grow to fill the row rather than clustering at
   * 30 px each. `flex: 1` inside each group, plus the 48 px `--touch-min` from
   * app.css, is what makes them thumb-sized.
   */
  :global([data-size='compact']) .bar {
    gap: 0.4rem;
    padding: 0.5rem var(--edge) 0.6rem;
  }

  :global([data-size='compact']) .group {
    flex: 1 1 100%;
  }

  :global([data-size='compact']) .group.right {
    margin-left: 0;
  }

  :global([data-size='compact']) .group :global(.btn) {
    flex: 1 1 0;
    min-width: 0;
    padding-inline: 0.5em;
  }

  .glyph {
    font-size: 1.15em;
    line-height: 1;
    font-weight: 500;
  }

  .lit {
    background: var(--route) !important;
    color: #04121a !important;
  }

  .lit :global(.kbd) {
    background: rgba(0, 0, 0, 0.22);
    color: #04121a;
  }
</style>
