<script lang="ts">
  import { allCardDefs } from "@wizwar/engine";
  import Card from "./Card.svelte";
  import { HOW_TO_PLAY, RULES_SECTIONS } from "./rules";

  let {
    onclose,
    initialTab = "play",
    stats = null,
    onstats,
  }: {
    onclose: () => void;
    initialTab?: "play" | "rules" | "cards" | "about" | "tally";
    stats?: Record<string, number | string | null> | null;
    onstats?: () => void;
  } = $props();

  // svelte-ignore state_referenced_locally -- the initial tab is intentionally a one-time value
  let tab = $state<"play" | "rules" | "cards" | "about" | "tally">(initialTab);

  function openTally() {
    tab = "tally";
    onstats?.();
  }
  function hours(mins: number): string {
    return mins < 90 ? `${mins} minutes` : `${Math.round(mins / 6) / 10} hours`;
  }
  let search = $state("");

  // The playable pool: every card actually in the 6e game (base + Exp1).
  const pool = allCardDefs().filter(
    (d) => (d.set === "basic" || d.set === "expansion1") && (d.quantity ?? 0) > 0,
  );
  const filtered = $derived.by(() => {
    const q = search.trim().toLowerCase();
    const list = q
      ? pool.filter(
          (d) => d.name.toLowerCase().includes(q) || (d.text ?? "").toLowerCase().includes(q),
        )
      : pool;
    return [...list].sort((a, b) => a.name.localeCompare(b.name));
  });

  function onkeydown(e: KeyboardEvent) {
    if (e.key === "Escape") onclose();
  }
</script>

<svelte:window {onkeydown} />

<div class="scrim" role="button" tabindex="-1" onclick={onclose} onkeydown={() => {}}>
  <div
    class="booklet"
    role="dialog"
    aria-modal="true"
    aria-label="help"
    tabindex="-1"
    onclick={(e) => e.stopPropagation()}
    onkeydown={() => {}}
  >
    <header class="booklet-head">
      <span class="booklet-title">Wiz-War</span>
      <nav class="tabs">
        <button class:current={tab === "play"} onclick={() => (tab = "play")}>How to play</button>
        <button class:current={tab === "rules"} onclick={() => (tab = "rules")}>The rules</button>
        <button class:current={tab === "cards"} onclick={() => (tab = "cards")}>Card library</button>
        <button class:current={tab === "about"} onclick={() => (tab = "about")}>About</button>
        <button class:current={tab === "tally"} onclick={openTally}>The tally</button>
      </nav>
      <button class="close" onclick={onclose} aria-label="close help">×</button>
    </header>

    <div class="booklet-body">
      {#if tab === "tally"}
        <div class="tally">
          <h3>How much love the maze is getting</h3>
          {#if stats}
            <dl class="tally-list">
              <dt>{stats.gamesCreated}</dt><dd>games chronicled — {stats.gamesStarted} begun, {stats.gamesFinished} fought to a finish</dd>
              <dt>{stats.wizardsSeated}</dt><dd>distinct wizards have taken a seat</dd>
              <dt>{stats.commandsPlayed}</dt><dd>spells, steps, and punches recorded in the ledgers</dd>
              <dt>{hours(Number(stats.minutesAtTable))}</dt><dd>spent at the table, by the clock between moves</dd>
              <dt>{stats.winsByTreasure} / {stats.winsByLastStanding}</dt><dd>victories by treasure-theft / by last wizard standing</dd>
              <dt>{stats.longestGameCommands}</dt><dd>actions in the longest game yet played — every step, spell, and pass in its ledger</dd>
              <dt>{stats.fullestTable}</dt><dd>wizards at the fullest table</dd>
              <dt>{stats.hotseatGames}</dt><dd>of the games were hotseat tables, reporting in anonymously</dd>
            </dl>
            {#if stats.firstGameAt}
              <p class="colophon">The first game was dealt {new Date(String(stats.firstGameAt)).toLocaleDateString(undefined, { year: "numeric", month: "long", day: "numeric" })}. Hotseat tables send only counts — names and moves stay on the device.</p>
            {/if}
          {:else}
            <p>Counting the ledgers…</p>
          {/if}
        </div>
      {:else if tab === "about"}
        <div class="about">
          <h3>What this is</h3>
          <p>
            Wiz-War is a game of magical combat in a stone labyrinth: two to six
            wizards prowl a maze, hurling fireballs, walking through walls,
            summoning trolls, and stealing each other's treasure. It was created
            by <strong>Tom Jolly</strong> in 1983 and first published under his
            own Jolly Games label; the edition reproduced here is the
            <strong>sixth edition</strong>, published by Chessex in 1993, together
            with its one expansion — monsters and magic wands included.
          </p>
          <h3>Why it exists</h3>
          <p>
            In the early nineties, a group of friends played this exact edition
            for countless hours — the slammed doors, the ambushes around
            corners, the goat charges, the laughter. That box is long out of
            print, and its cardboard is worn soft at the edges. This digital
            table was built from that very copy: every card was photographed and
            transcribed word for word, every board layout verified wall by wall,
            and the tokens on this screen are the actual hand-inked art from
            those counter sheets. It is a faithful reproduction of the game as
            it was played at that table, made so the same friends — and their
            friends — can keep playing it.
          </p>
          <h3>Whose game it is</h3>
          <p>
            Wiz-War is Tom Jolly's design, and the rights to it now rest with
            <strong>Steve Jackson Games</strong>, who publish the current
            edition. This project is an unofficial, non-commercial fan work,
            made with love and admiration for the original — nothing here is
            endorsed by or affiliated with Tom Jolly, Chessex, or Steve Jackson
            Games. If this game delights you, honor it the right way:
            <a href="https://www.sjgames.com/wiz-war/" target="_blank" rel="noreferrer">buy
            the edition currently in print</a>, and deal seven cards to
            somebody at a real table.
          </p>
          <h3>Send word</h3>
          <p>
            Feedback, bug reports, and faint praise all welcome — ravens fly to
            <a href="mailto:eric@ericwagoner.com">eric@ericwagoner.com</a>,
            <a href="https://bsky.app/profile/kestrelsnest.social" target="_blank" rel="noreferrer">@kestrelsnest.social</a> on Bluesky,
            or <a href="https://toots.kestrelsnest.social/@eric" target="_blank" rel="noreferrer">@eric@toots.kestrelsnest.social</a> on Mastodon.
            The keeper of this table roosts at
            <a href="https://kestrelsnest.social" target="_blank" rel="noreferrer">kestrelsnest.social</a>.
          </p>
          <p class="colophon">
            Wiz-War © Tom Jolly. Sixth edition published by Chessex, 1993.
            Built by Eric and a very enthusiastic AI, 2026.
          </p>
        </div>
      {:else if tab === "play"}
        {#each HOW_TO_PLAY as section (section.title)}
          <h3>{section.title}</h3>
          {#each section.body as p, i (i)}<p>{p}</p>{/each}
        {/each}
      {:else if tab === "rules"}
        <p class="colophon">
          Sixth edition rules, from the original rulebook. © 1985 Jolly Games —
          this digital adaptation is a fan project.
        </p>
        {#each RULES_SECTIONS as section (section.title)}
          <h3>{section.title}</h3>
          {#each section.body as p, i (i)}<p>{p}</p>{/each}
        {/each}
      {:else}
        <div class="search-row">
          <input
            bind:value={search}
            placeholder="search {pool.length} cards…"
            aria-label="search cards"
          />
        </div>
        <div class="card-grid">
          {#each filtered as def (def.id)}
            <div class="card-slot">
              <Card card={{ instanceId: `lib-${def.id}`, cardId: def.id }} />
              <span class="card-meta">
                ×{def.quantity}{def.alsoIn?.length ? ` (+${def.alsoIn[0]!.quantity} exp)` : ""}
                · {def.set === "basic" ? "base" : "exp 1"}
              </span>
            </div>
          {/each}
        </div>
      {/if}
    </div>
  </div>
</div>

<style>
  .scrim {
    position: fixed;
    inset: 0;
    background: rgba(10, 12, 16, 0.72);
    display: grid;
    place-items: center;
    z-index: 40;
    padding: 2rem 1rem;
  }
  .booklet {
    background: #efe8d4;
    color: #43331f;
    width: min(58rem, 100%);
    max-height: calc(100vh - 4rem);
    border-radius: 6px;
    border: 1px solid #b3a687;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.6);
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }
  .booklet-head {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.7rem 1rem;
    border-bottom: 2px solid #43331f;
    flex-wrap: wrap;
  }
  .booklet-title {
    font-family: "Oswald", sans-serif;
    font-weight: 700;
    font-size: 1.15rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  .tabs { display: flex; gap: 0.3rem; }
  .tabs button {
    font-family: "Oswald", sans-serif;
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    background: none;
    border: 1.5px solid transparent;
    border-radius: 3px;
    color: #6b5a41;
    padding: 0.3rem 0.6rem;
    cursor: pointer;
  }
  .tabs button.current {
    border-color: #43331f;
    color: #43331f;
    background: #e4dbc2;
  }
  .close {
    margin-left: auto;
    background: none;
    border: none;
    font-size: 1.4rem;
    color: #6b5a41;
    cursor: pointer;
    line-height: 1;
  }
  .close:hover { color: #b3372b; }

  .booklet-body {
    overflow-y: auto;
    padding: 1rem 1.4rem 1.4rem;
    font-family: "Archivo Narrow", sans-serif;
    font-size: 0.98rem;
    line-height: 1.5;
  }
  .booklet-body h3 {
    font-family: "Oswald", sans-serif;
    font-size: 0.85rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    border-bottom: 1px solid #b3a687;
    padding-bottom: 0.15rem;
    margin: 1.2rem 0 0.4rem;
  }
  .booklet-body h3:first-child { margin-top: 0; }
  .booklet-body p { margin: 0.35rem 0; }
  .colophon { font-style: italic; color: #6b5a41; font-size: 0.85rem; }
  .booklet-body a { color: #8a4a1f; text-decoration-style: dotted; }
  .booklet-body a:hover { color: #43331f; }
  .tally-list { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 0.8rem; margin: 0.6rem 0 1rem; }
  .tally-list dt {
    font-family: "Oswald", sans-serif; font-weight: 700; font-size: 1.05rem;
    color: #b3372b; text-align: right; white-space: nowrap;
  }
  .tally-list dd { margin: 0; align-self: center; }

  .search-row { margin-bottom: 0.8rem; }
  .search-row input {
    width: 100%;
    box-sizing: border-box;
    background: #f6f0df;
    border: 1px solid #b3a687;
    border-radius: 4px;
    padding: 0.5rem 0.7rem;
    font-family: inherit;
    font-size: 0.95rem;
    color: #43331f;
  }
  .card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8.4rem, 1fr));
    gap: 0.8rem;
    justify-items: center;
  }
  .card-slot { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; }
  .card-slot :global(.card) { cursor: default; }
  .card-slot :global(.card:hover) { transform: none; box-shadow: 0 3px 8px rgba(10, 8, 4, 0.45); }
  .card-meta {
    font-family: "Courier Prime", monospace;
    font-size: 0.68rem;
    color: #6b5a41;
  }
</style>
