<script lang="ts">
  import { onMount } from 'svelte';
  import { cubicOut } from 'svelte/easing';
  import { app, bootstrap } from './lib/app.svelte';
  import { navigate, router } from './lib/router.svelte';
  import { t } from './lib/i18n/index.svelte';
  import { insideTelegram, telegramBackButton } from './lib/telegram';
  import Toast from './components/Toast.svelte';
  import Login from './screens/Login.svelte';
  import Lobby from './screens/Lobby.svelte';
  import NewGame from './screens/NewGame.svelte';
  import Profile from './screens/Profile.svelte';
  import Settings from './screens/Settings.svelte';
  import About from './screens/About.svelte';
  import Friends from './screens/Friends.svelte';
  import Stats from './screens/Stats.svelte';
  import Game from './game/Game.svelte';
  import ChatScreen from './game/ChatScreen.svelte';
  import CheckScreen from './game/CheckScreen.svelte';

  onMount(() => {
    void bootstrap();
  });

  // Inside Telegram, drive its native header back button: show it on any sub-screen
  // (everything returns to the lobby root), hide it on the lobby/login. The app's own
  // back chevron is hidden in Telegram (Header.svelte) so only the native one shows.
  $effect(() => {
    if (!insideTelegram()) return;
    const r = router.route;
    // The chat / check sub-screens step back to their game; every other sub-screen to the lobby.
    const sub = r.name === 'gameChat' || r.name === 'gameCheck';
    const target = sub ? `/game/${r.params.id}` : '/';
    telegramBackButton(r.name !== 'lobby' && r.name !== 'login', () => navigate(target));
  });

  // Screen transitions: the lobby is the navigation root. Entering a screen from the
  // lobby slides it in from the right (forward); returning to the lobby slides the
  // screen out to the right and reveals the lobby (back). Transitions are local, so
  // they do not play on the initial mount, and collapse to nothing under reduce-motion.
  const dir = $derived(router.route.name === 'lobby' ? 'back' : 'forward');
  const enterSign = $derived(dir === 'forward' ? 1 : -1);
  const leaveSign = $derived(dir === 'forward' ? -1 : 1);
  const routeKey = $derived(router.route.name + (router.route.params.id ?? ''));
  const animMs = $derived(app.reduceMotion ? 0 : 260);

  // slideX slides a pane horizontally by a full width. sign>0 enters from / exits to
  // the right; sign<0 the left. Percentage keeps it viewport-relative without reading
  // innerWidth, and the .router clips the off-screen pane.
  function slideX(_node: Element, { duration, sign }: { duration: number; sign: number }) {
    return {
      duration,
      easing: cubicOut,
      css: (tt: number) => `transform: translateX(${(1 - tt) * sign * 100}%)`,
    };
  }
</script>

{#if !app.ready}
  <div class="splash">{t('common.loading')}</div>
{:else}
  <div class="router">
    {#key routeKey}
      <div class="pane" in:slideX={{ duration: animMs, sign: enterSign }} out:slideX={{ duration: animMs, sign: leaveSign }}>
        {#if router.route.name === 'login'}
          <Login />
        {:else if router.route.name === 'new'}
          <NewGame />
        {:else if router.route.name === 'game'}
          <Game id={router.route.params.id} />
        {:else if router.route.name === 'gameChat'}
          <ChatScreen id={router.route.params.id} />
        {:else if router.route.name === 'gameCheck'}
          <CheckScreen id={router.route.params.id} />
        {:else if router.route.name === 'profile'}
          <Profile />
        {:else if router.route.name === 'settings'}
          <Settings />
        {:else if router.route.name === 'about'}
          <About />
        {:else if router.route.name === 'friends'}
          <Friends />
        {:else if router.route.name === 'stats'}
          <Stats />
        {:else}
          <Lobby />
        {/if}
      </div>
    {/key}
  </div>
{/if}

<Toast />

<style>
  .splash {
    height: 100%;
    display: grid;
    place-items: center;
    color: var(--text-muted);
  }
  .router {
    position: relative;
    height: 100%;
    overflow: hidden;
  }
  .pane {
    position: absolute;
    inset: 0;
  }
</style>
