<script lang="ts">
  import type { ChatMessage } from '../lib/model';
  import { t } from '../lib/i18n/index.svelte';

  let {
    messages,
    myId,
    busy,
    myTurn = false,
    nudgeOnCooldown = false,
    onsend,
    onnudge,
  }: {
    messages: ChatMessage[];
    myId: string;
    busy: boolean;
    // Chat and nudge are mutually exclusive by turn (Stage 17): on the player's own turn the
    // message field + send are shown (and nudging makes no sense — there is no one to
    // hurry); on the opponent's turn only the nudge button shows. While the hourly nudge
    // cooldown is active the nudge is disabled with an "awaiting reply" caption.
    myTurn?: boolean;
    nudgeOnCooldown?: boolean;
    onsend: (text: string) => void;
    onnudge: () => void;
  } = $props();

  let text = $state('');

  function send() {
    const v = text.trim();
    if (!v) return;
    onsend(v);
    text = '';
  }
</script>

<div class="chat">
  <div class="list">
    {#if messages.length === 0}
      <p class="empty">{t('chat.empty')}</p>
    {/if}
    {#each messages as m (m.id)}
      {#if m.kind === 'nudge'}
        <div class="note">{t('chat.nudge')}</div>
      {:else}
        <div class="msg" class:mine={m.senderId === myId}>{m.body}</div>
      {/if}
    {/each}
  </div>
  <div class="input">
    {#if myTurn}
      <input
        maxlength="60"
        placeholder={t('chat.placeholder')}
        bind:value={text}
        onkeydown={(e) => e.key === 'Enter' && send()}
      />
      <button class="iconbtn" onclick={send} disabled={busy} aria-label={t('chat.send')}>⬆️</button>
    {:else}
      <!-- A flex:1 caption keeps the nudge pinned right whether or not the cooldown text shows. -->
      <span class="cooldown">{nudgeOnCooldown ? t('chat.awaitingReply') : ''}</span>
      <button class="iconbtn" onclick={onnudge} disabled={busy || nudgeOnCooldown} aria-label={t('chat.nudgeAction')}>🛎️</button>
    {/if}
  </div>
</div>

<style>
  .chat {
    display: flex;
    flex-direction: column;
    gap: 10px;
    /* Fill the chat screen; the list scrolls and the input pins to the bottom. The screen
       fits the visual viewport (--vvh), so an open keyboard simply shrinks it and the input
       stays visible — no modal relayout, no page jump (Stage 17). */
    flex: 1;
    min-height: 0;
    padding: 10px var(--pad);
    box-sizing: border-box;
  }
  .list {
    flex: 1;
    overflow: auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 4px;
  }
  .empty {
    color: var(--text-muted);
    text-align: center;
    margin: auto;
  }
  .msg {
    align-self: flex-start;
    max-width: 80%;
    padding: 7px 11px;
    border-radius: 12px;
    background: var(--surface-2);
  }
  .msg.mine {
    align-self: flex-end;
    background: var(--accent);
    color: var(--accent-text);
  }
  .note {
    align-self: center;
    font-size: 0.82rem;
    color: var(--text-muted);
    font-style: italic;
  }
  .input {
    display: flex;
    gap: 6px;
    align-items: center;
  }
  /* The cooldown caption sits to the left of the disabled nudge button. */
  .cooldown {
    flex: 1;
    text-align: right;
    color: var(--text-muted);
    font-size: 0.85rem;
  }
  .input input {
    flex: 1;
    min-width: 0;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg);
    color: var(--text);
  }
  .iconbtn {
    flex: 0 0 auto;
    padding: 8px 12px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--radius-sm);
    font-size: 1.25rem;
    line-height: 1;
  }
  .iconbtn:disabled {
    opacity: 0.45;
  }
</style>
