<script lang="ts">
  import { onMount } from 'svelte';
  import Screen from '../components/Screen.svelte';
  import { gateway } from '../lib/gateway';
  import { app, handleError, showToast } from '../lib/app.svelte';
  import { connection } from '../lib/connection.svelte';
  import { navigate } from '../lib/router.svelte';
  import { t, type MessageKey } from '../lib/i18n/index.svelte';
  import type { AccountRef, Variant } from '../lib/model';
  import {
    availableVariants,
    VARIANT_FLAG,
    VARIANT_RULES,
    supportsMultipleWordsToggle,
    multipleWordsForRequest,
  } from '../lib/variants';

  // The auto-match move clock (mirrors backend game.DefaultTurnTimeout = 24h).
  const AUTO_MATCH_HOURS = 24;

  // The offered variants are gated by the player's profile preferences (the variants
  // they enabled in Settings); the auto-match list and the friend-invite picker both use this.
  const variants = $derived(availableVariants(app.profile?.variantPreferences));
  // "Multiple words per turn" off is the single-word rule; it is offered for Russian games
  // only (English is always standard and shows no toggle). Shared by both flows.
  let multipleWords = $state(false);
  // Auto-match: the variant is a select (highlight, no immediate enqueue) confirmed by the
  // Start button. A lone offered variant is pre-selected; with several the player must pick.
  let selectedAuto = $state<Variant | ''>('');
  $effect(() => {
    if (variants.length === 1 && !selectedAuto) selectedAuto = variants[0].id;
  });
  const timeouts = [
    { secs: 300, key: 'time.minutes' as MessageKey, n: 5 },
    { secs: 1800, key: 'time.minutes' as MessageKey, n: 30 },
    { secs: 3600, key: 'time.hours' as MessageKey, n: 1 },
    { secs: 86400, key: 'time.hours' as MessageKey, n: 24 },
  ];

  const guest = $derived(app.profile?.isGuest ?? true);
  let mode = $state<'auto' | 'friends'>('auto');
  // The quick-game opponent: an honest AI (a robot that joins and moves at once, shown as 🤖)
  // or a random human via auto-match. AI is the default.
  let opponent = $state<'ai' | 'random'>('ai');

  // --- auto-match ---
  // Enqueue drops the player straight into a real game — a freshly opened one awaiting an
  // opponent, or another player's open game they just joined — so we navigate into it at once
  // and the player waits inside. The opponent (a human or, after the wait, a robot) takes the
  // empty seat later via the opponent_joined push; there is no separate "searching" screen.
  let starting = $state(false);

  async function find(v: Variant) {
    if (starting) return;
    starting = true;
    try {
      const r = await gateway.lobbyEnqueue(v, multipleWordsForRequest(v, multipleWords), opponent === 'ai');
      if (r.game) navigate(`/game/${r.game.id}`);
    } catch (e) {
      handleError(e);
    } finally {
      starting = false;
    }
  }

  // --- friend game ---
  let friends = $state<AccountRef[]>([]);
  let selected = $state<string[]>([]);
  let friendFilter = $state('');
  // A lone offered variant is pre-selected and its picker disabled (nothing else to choose);
  // with several, the player picks. '' renders the disabled placeholder option.
  let inviteVariant = $state<Variant | ''>('');
  $effect(() => {
    if (variants.length === 1 && !inviteVariant) inviteVariant = variants[0].id;
  });
  let timeoutSecs = $state(86400);
  let hints = $state(1);

  const filteredFriends = $derived(
    friendFilter.trim()
      ? friends.filter((f) => f.displayName.toLowerCase().includes(friendFilter.trim().toLowerCase()))
      : friends,
  );

  onMount(async () => {
    if (guest) return;
    try {
      friends = await gateway.friendsList();
    } catch (e) {
      handleError(e);
    }
  });

  function toggle(id: string) {
    selected = selected.includes(id) ? selected.filter((x) => x !== id) : [...selected, id];
  }

  async function sendInvite() {
    if (selected.length === 0 || selected.length > 3 || !inviteVariant) return;
    try {
      await gateway.invitationCreate(selected, {
        variant: inviteVariant,
        turnTimeoutSecs: timeoutSecs,
        hintsAllowed: hints > 0,
        hintsPerPlayer: hints,
        dropoutTiles: 'remove',
        multipleWordsPerTurn: multipleWordsForRequest(inviteVariant, multipleWords),
      });
      showToast(t('new.invited'));
      navigate('/');
    } catch (e) {
      handleError(e);
    }
  }

</script>

<Screen title={t('new.title')} back="/">
  <div class="page">
      {#if !guest}
        <div class="seg modes">
          <button class="opt" class:active={mode === 'auto'} onclick={() => (mode = 'auto')}>{t('new.auto')}</button>
          <button class="opt" class:active={mode === 'friends'} onclick={() => (mode = 'friends')}>{t('new.withFriends')}</button>
        </div>
      {/if}

      {#if mode === 'auto'}
        <div class="seg modes">
          <button class="opt" class:active={opponent === 'ai'} onclick={() => (opponent = 'ai')}>🤖 {t('new.opponentAI')}</button>
          <button class="opt" class:active={opponent === 'random'} onclick={() => (opponent = 'random')}>👤 {t('new.opponentRandom')}</button>
        </div>
        <div class="variants">
          {#each variants as v (v.id)}
            <button
              class="variant"
              class:selected={selectedAuto === v.id}
              onclick={() => (selectedAuto = v.id)}
              disabled={!connection.online}
            >
              <span class="vmain">
                <span class="vname">{t(v.label)}</span>
                {#if VARIANT_FLAG[v.id]}
                  <span class="vflag">{VARIANT_FLAG[v.id]}</span>
                {:else}
                  <img class="vflag-img" src="flag-ussr.svg" alt="" />
                {/if}
              </span>
              <span class="vrules">{t(VARIANT_RULES[v.id])}</span>
            </button>
          {/each}
        </div>
        {#if variants.some((v) => supportsMultipleWordsToggle(v.id))}
          <label class="toggle">
            <span>{t('new.multipleWordsPerTurn')}</span>
            <input type="checkbox" bind:checked={multipleWords} />
          </label>
        {/if}
        <div class="grow"></div>
        <p class="movelimit">{opponent === 'ai' ? t('new.aiInactiveLimit') : t('new.moveLimit', { n: AUTO_MATCH_HOURS })}</p>
        {#if opponent === 'random'}<p class="searchhint">{t('new.searchHint')}</p>{/if}
        <button
          class="invite"
          disabled={!selectedAuto || !connection.online || starting}
          onclick={() => selectedAuto && find(selectedAuto)}
        >{t('new.start')}</button>
      {:else if friends.length === 0}
        <p class="subtitle">{t('new.noFriends')}</p>
      {:else}
        <div class="fg">
          <div class="picked">
            <span class="ftitle">{t('new.pickFriends')} ({selected.length})</span>
            <input class="search" bind:value={friendFilter} placeholder={t('new.searchFriends')} />
          </div>
          <div class="friends-scroll">
            {#each filteredFriends as f (f.accountId)}
              <label class="friend">
                <input type="checkbox" checked={selected.includes(f.accountId)} onchange={() => toggle(f.accountId)} />
                <span>{f.displayName}</span>
              </label>
            {/each}
            {#if filteredFriends.length === 0}<p class="muted">—</p>{/if}
          </div>
          <div class="settings-row">
            <label class="field">
              <span>{t('new.gameType')}</span>
              <select bind:value={inviteVariant} class:placeholder={!inviteVariant} disabled={variants.length === 1}>
                <option value="" disabled>—</option>
                {#each variants as v (v.id)}<option value={v.id}>{t(v.label)}</option>{/each}
              </select>
            </label>
            <label class="field">
              <span>{t('new.moveTime')}</span>
              <select bind:value={timeoutSecs}>
                {#each timeouts as to (to.secs)}<option value={to.secs}>{t(to.key, { n: to.n })}</option>{/each}
              </select>
            </label>
            <label class="field">
              <span>{t('new.hintsPerPlayer')}</span>
              <select bind:value={hints}>
                {#each [0, 1, 2] as h (h)}<option value={h}>{h}</option>{/each}
              </select>
            </label>
          </div>
          {#if inviteVariant && supportsMultipleWordsToggle(inviteVariant)}
            <label class="toggle">
              <span>{t('new.multipleWordsPerTurn')}</span>
              <input type="checkbox" bind:checked={multipleWords} />
            </label>
          {/if}
          <button class="invite" disabled={selected.length === 0 || !inviteVariant || !connection.online} onclick={sendInvite}>{t('new.invite')}</button>
        </div>
      {/if}
  </div>
</Screen>

<style>
  .page {
    padding: var(--pad);
    display: flex;
    flex-direction: column;
    gap: 14px;
    height: 100%;
    box-sizing: border-box;
  }
  .subtitle {
    color: var(--text-muted);
    margin: 0;
  }
  .variants {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  /* A plaque per variant (like the lobby game cards): the name with its flag on the right,
     and a one-line rules summary below. */
  .variant {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--radius);
    text-align: left;
    user-select: none;
  }
  .vmain {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
  }
  .vname {
    font-size: 1.05rem;
    font-weight: 600;
  }
  .vflag {
    font-size: 1.3rem;
    line-height: 1;
  }
  .vflag-img {
    width: 1.6rem;
    height: auto;
    border-radius: 2px;
  }
  .vrules {
    font-size: 0.8rem;
    color: var(--text-muted);
  }
  /* Selected auto-match variant: an accent inset border (the button no longer enqueues on
     tap; the Start button confirms the choice). */
  .variant.selected {
    border-color: var(--accent);
    box-shadow: inset 0 0 0 2px var(--accent);
  }
  .movelimit {
    margin: 0;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.85rem;
  }
  .seg {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
  }
  .modes {
    margin-bottom: 4px;
  }
  .opt {
    flex: 1;
    min-width: 64px;
    padding: 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--radius-sm);
    user-select: none;
  }
  .opt.active {
    background: var(--accent);
    color: var(--accent-text);
    border-color: var(--accent);
  }
  .fg {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  .picked {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .ftitle {
    font-size: 0.9rem;
    color: var(--text-muted);
  }
  .search {
    min-width: 0;
    padding: 9px 11px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--radius-sm);
  }
  .friends-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .friend {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: var(--radius-sm);
  }
  .settings-row {
    display: flex;
    gap: 8px;
  }
  .field {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .field span {
    font-size: 0.78rem;
    color: var(--text-muted);
  }
  .field select {
    width: 100%;
    box-sizing: border-box;
    min-width: 0;
    padding: 9px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--radius-sm);
  }
  .field select.placeholder {
    color: var(--text-muted);
  }
  .toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 11px;
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: var(--radius-sm);
    user-select: none;
  }
  .toggle span {
    font-size: 0.85rem;
    color: var(--text);
  }
  .muted {
    color: var(--text-muted);
    margin: 0;
  }
  /* Pushes the auto-match start cluster (move-limit hint + Start button) to the bottom,
     mirroring the friend-game invite button pinned by the .fg scroll area. */
  .grow {
    flex: 1;
  }
  .invite {
    flex: 0 0 auto;
    padding: 14px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: var(--accent-text);
    border-radius: var(--radius);
    font-weight: 600;
  }
  .invite:disabled {
    opacity: 0.5;
  }
  .searchhint {
    margin: 0;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.4;
  }
</style>
