<script lang="ts">
  import { navigate } from '../lib/router.svelte';
  import { connection } from '../lib/connection.svelte';
  import { offlineMode, dictPreloadWarning } from '../lib/offline.svelte';
  import { t } from '../lib/i18n/index.svelte';
  import { app, openDebug } from '../lib/app.svelte';
  import Spinner from './Spinner.svelte';
  import AdBanner from './AdBanner.svelte';

  let { title, back, grow = false }: { title: string; back?: string; grow?: boolean } = $props();

  // The app always shows its own back chevron when there is a back target — on every platform, in
  // and out of Telegram. The native Telegram BackButton is not used: it does not render reliably in
  // the windowed Mini App (relying on it would lose back navigation there).
  const showBack = $derived(!!back);

  // Ten quick taps on the title open the hidden debug panel (components/DebugPanel) — a support aid.
  let titleTaps = 0;
  let lastTitleTap = 0;
  function onTitleTap(): void {
    const now = Date.now();
    titleTaps = now - lastTitleTap < 400 ? titleTaps + 1 : 1;
    lastTitleTap = now;
    if (titleTaps >= 10) {
      titleTaps = 0;
      openDebug();
    }
  }
</script>

<header class="nav" class:grow class:offline={offlineMode.active}>
  <div class="bar">
    {#if showBack}
      <button class="icon back" onclick={() => back && navigate(back)} aria-label="Back">
        <span class="chev"></span>
      </button>
    {:else}
      <span class="spacer"></span>
    {/if}
    {#if connection.online || offlineMode.active}
      <!-- svelte-ignore a11y_click_events_have_key_events -->
      <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
      <h1 onclick={onTitleTap}>{title}</h1>
    {:else}
      <h1 class="connecting"><Spinner /> <span>{t('connection.connecting')}</span></h1>
    {/if}
    <!-- A right-hand spacer balances the back button so the title stays centred; in offline mode it
         carries the "Offline" chip so the deliberate mode is always visible (not just the blue tint). -->
    {#if offlineMode.active}
      <span class="chip">{t('settings.offline')}</span>
    {:else}
      <span class="spacer"></span>
    {/if}
  </div>
  <!-- The ad banner lives inside the nav, directly under the title bar, so it sits in the
       same place on every screen — and in the game (grown nav) the spare height falls below
       it (banner under the title, board pinned to the bottom). It is hidden while a first-run
       coachmark overlay is up (app.coachActive) so the scrolling strip does not run behind the
       dimmed onboarding layer; the engine keeps rotating (module scope) and the strip reappears,
       per this same condition, once onboarding closes. -->
  {#if dictPreloadWarning.active}
    <!-- A background dictionary preload for offline readiness failed (poor connection): a soft
         notice takes the ad banner's slot until a later preload succeeds and clears it. -->
    <p class="preload-warn" role="alert">{t('offline.preloadWarning')}</p>
  {:else if app.profile?.banner && app.profile.banner.campaigns.length && !app.coachActive}
    <AdBanner
      campaigns={app.profile.banner.campaigns}
      timings={app.profile.banner.timings}
      reduceMotion={app.reduceMotion}
    />
  {/if}
</header>

<style>
  /* By default the nav bar is minimal and the content fills the screen. In the game
     it grows (class `grow`) to push the board and controls to the bottom. */
  .nav {
    flex: 0 0 auto;
    min-height: 52px;
    background: var(--bg-elev);
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    user-select: none;
    -webkit-user-select: none;
  }
  /* Deliberate offline mode: a blue-tinted nav, mixed from the accent so it tracks the light/dark
     theme (and any Telegram theme override) — the offline state is unmistakable at a glance. */
  .nav.offline {
    background: color-mix(in srgb, var(--accent) 20%, var(--bg-elev));
    border-bottom-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  }
  .nav.grow {
    /* Grow into spare height (banner under the title, the board pinned to the bottom), but
       never shrink: on a short viewport the banner keeps its height and the board's own
       scroll (.stage) absorbs the squeeze, instead of the banner and the board splitting it. */
    flex: 1 0 auto;
  }
  .bar {
    display: flex;
    align-items: center;
    gap: var(--gap);
    padding: 5px var(--pad);
    /* Clear the top safe area on the native build: under Android 15+ edge-to-edge the WebView draws
       behind the status bar, so the header row must drop below it. --safe-area-inset-top is injected by
       the Capacitor SystemBars plugin (native only — unset, so 0, on web / PWA / Telegram / VK, which do
       not draw behind our header). Telegram fullscreen overrides this with its own nav-band rule below. */
    padding-top: calc(var(--safe-area-inset-top, 0px) + 5px);
  }
  h1 {
    font-size: 1.05rem;
    margin: 0;
    flex: 1;
    text-align: center;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* The "Connecting…" indicator replaces the title while offline: a spinner + muted label,
     centred like the title so the bar does not shift. */
  h1.connecting {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--text-muted);
    font-weight: 500;
  }
  .icon,
  .spacer {
    min-width: 40px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* The offline chip: a compact accent-tinted pill in the header's right slot. */
  .chip {
    min-width: 40px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 8px;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
    border-radius: 999px;
    white-space: nowrap;
  }
  /* The offline-readiness preload warning: a soft, muted strip in the ad banner's slot, sized like
     the banner region so the bar does not jump when it appears. */
  .preload-warn {
    margin: 0;
    padding: 7px var(--pad);
    font-size: 0.78rem;
    line-height: 1.3;
    text-align: center;
    color: var(--text-muted);
    background: var(--surface-2);
    border-top: 1px solid var(--border);
  }
  .back {
    background: none;
    border: none;
    color: var(--text);
    border-radius: var(--radius-sm);
    padding: 0 8px;
  }
  .back:hover {
    background: var(--surface-2);
  }
  /* Android in-app WebViews (Telegram, VK) flash a selection-like box on the two tappable header
     controls — the title (a 10-tap debug target) and the back chevron — on a plain tap. The global
     -webkit-user-select / -webkit-tap-highlight-color on #app is inherited, but those WebViews only
     suppress the artifact when the properties sit DIRECTLY on the tapped element. */
  h1,
  .back {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
  }
  /* A thin, compact "<" drawn from two borders — lighter than a glyph. */
  .chev {
    width: 11px;
    height: 11px;
    border-left: 2.5px solid currentColor;
    border-bottom: 2.5px solid currentColor;
    transform: rotate(45deg);
    margin-left: 3px;
  }
  /* Telegram fullscreen: TG's native nav occupies the band between the device notch
     (--tg-safe-top) and --tg-content-top. Our header spans that full band (so the layout below
     is unchanged) and centres the title within it, BELOW the notch — lining it up vertically
     with Telegram's own back/menu controls, which sit in the band's corners. */
  :global(html.tg-fullscreen) .bar {
    /* The bar is sized by its content + padding — in Telegram the title is the only child (the
       back chevron is hidden), so min-height (the nav-band height) doesn't bind. Without the
       (removed) hamburger that content shrank and the bar sat flush under Telegram's native nav
       band. So **padding-top** is the lever: it drops the title clear of the band — the notch
       plus an **8px** gap (halved from 16). A fixed px (not rem/em) gap so the clearance from
       Telegram's native controls stays constant if the user scales up the font (the title then
       grows downward and the bar with it). (Owner-tunable: the 8px.) */
    min-height: var(--tg-content-top);
    box-sizing: border-box;
    align-items: center;
    justify-content: center;
    padding-top: calc(var(--tg-safe-top) + 8px);
    padding-bottom: 3px;
  }
  :global(html.tg-fullscreen) .spacer {
    display: none;
  }
  :global(html.tg-fullscreen) h1 {
    flex: 0 1 auto;
  }
</style>
