<script>
  import { getGame, bundleUrl } from "../lib/api.js";
  import { push } from "../lib/router.js";

  let { id } = $props();

  let game = $state(null);
  let loading = $state(true);
  let error = $state("");
  let booting = $state(false);
  let running = $state(false);
  let started = false;

  let dosContainer;
  let dosCI = null;

  async function load() {
    loading = true;
    try {
      game = await getGame(id);
    } catch (e) {
      error = "Game not found";
    }
    loading = false;
  }

  async function startEmulator() {
    if (started || !game?.ready || !dosContainer) return;
    started = true;
    booting = true;

    // Load js-dos CSS
    const link = document.createElement("link");
    link.rel = "stylesheet";
    link.href = "https://v8.js-dos.com/latest/js-dos.css";
    document.head.appendChild(link);

    // Load js-dos script from CDN
    if (!window.Dos) {
      try {
        await new Promise((resolve, reject) => {
          const s = document.createElement("script");
          s.src = "https://v8.js-dos.com/latest/js-dos.js";
          s.onload = resolve;
          s.onerror = reject;
          document.head.appendChild(s);
        });
      } catch {
        error = "Failed to load emulator. Check your internet connection.";
        booting = false;
        return;
      }
    }

    // Start the DOS emulator
    try {
      const url = bundleUrl(game);
      if (!url || !window.Dos) throw new Error("Failed to resolve game bundle");
      dosCI = await window.Dos(dosContainer, { url });
      running = true;
    } catch (e) {
      error = e.message;
    }
    booting = false;
  }

  function stopEmulator() {
    // Force full page reload which terminates all workers, AudioContexts
    // and WASM threads. Hash is preserved so the SPA routes correctly.
    window.location.hash = `#/game/${game.id}`;
    window.location.reload();
  }

  $effect(() => { load(); });

  // Auto-start when both game data and the container exist
  $effect(() => {
    if (game?.ready && dosContainer && !started) {
      startEmulator();
    }
  });

  // Cleanup emulator on component unmount (browser back, nav away)
  $effect(() => {
    return () => {
      if (dosCI) {
        try { dosCI.exit(); } catch (_) {}
        dosCI = null;
      }
      if (dosContainer) {
        dosContainer.innerHTML = "";
      }
    };
  });
</script>

<div class="play-page">
  <!-- Top bar: shown when game is loaded -->
  <div class="play-header" class:active={game}>
    {#if game}
      <button class="link-button" onclick={stopEmulator}>← {game.title}</button>
      {#if running}
        <button class="btn stop-btn" onclick={stopEmulator}>⏹ Stop</button>
      {/if}
    {/if}
  </div>

  <!-- Error state -->
  {#if error && !booting}
    <div class="error-box">{error}</div>
  {/if}

  <!-- Loading / booting overlay (covers the canvas while loading) -->
  {#if !running}
    <div class="overlay">
      {#if loading}
        <div class="overlay-icon">⏳</div>
        <p>Loading game data...</p>
      {:else if booting}
        <div class="overlay-icon">⚙️</div>
        <h2>{game?.title || ""}</h2>
        <p>Starting emulator...</p>
        <p class="save-hint">💾 Game saves are stored automatically</p>
      {:else if error}
        <div class="overlay-icon">⚠️</div>
        <h2>Failed to start</h2>
        <p>{error}</p>
      {:else if !game?.ready}
        <div class="overlay-icon">🕹️</div>
        <h2>Not ready</h2>
        <p>This game hasn't been processed yet.</p>
      {/if}
    </div>
  {/if}

  <!-- dos-container is always in the DOM so bind:this works on first render -->
  <div bind:this={dosContainer} class="dos-container"></div>
</div>

<style>
  .play-page { padding: 16px 0; position: relative; }
  @media (max-width: 640px) { .play-page { padding: 8px 0; } }
  .play-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    opacity: 0;
    transition: opacity 0.2s;
  }
  .play-header.active { opacity: 1; }
  .link-button {
    background: none;
    border: none;
    color: var(--text-dim);
    font-size: 0.9rem;
    cursor: pointer;
    padding: 0;
    font-family: var(--font-sans);
  }
  .link-button:hover { color: var(--phosphor); }
  .stop-btn {
    border-color: #cc3333;
    color: #ff4444;
  }
  .stop-btn:hover {
    background: #331111;
    box-shadow: 0 0 12px #331111;
  }

  /* Emulator canvas — always mounted */
  .dos-container {
    width: 100%;
    aspect-ratio: 4/3;
    max-height: 80vh;
    background: #000;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--border);
  }
  @media (max-width: 640px) {
    .dos-container { aspect-ratio: 4/3; max-height: 50vh; border-radius: var(--radius-sm); }
  }
  .dos-container :global(canvas) {
    width: 100% !important;
    height: 100% !important;
  }

  /* Overlay shown while loading / booting, covers the empty container */
  .overlay {
    position: absolute;
    inset: 0;
    top: 50px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    background: var(--bg);
    z-index: 10;
    border-radius: var(--radius);
    border: 1px dashed var(--border);
    margin-top: 4px;
    padding: 20px;
  }
  @media (max-width: 640px) {
    .overlay { top: 44px; border-radius: var(--radius-sm); padding: 16px; }
    .overlay-icon { font-size: 2rem; }
    .overlay h2 { font-size: 1rem; }
    .overlay p { font-size: 0.85rem; }
  }
  .overlay-icon { font-size: 3rem; margin-bottom: 12px; }
  .overlay h2 {
    color: var(--phosphor);
    font-family: var(--font-mono);
    margin-bottom: 4px;
  }
  .overlay p { color: var(--text-dim); }
  .save-hint {
    display: inline-block;
    margin-top: 16px;
    padding: 6px 16px;
    border-radius: 12px;
    background: var(--phosphor-burn);
    color: var(--phosphor-dim);
    font-size: 0.85rem;
  }

  .error-box {
    position: absolute;
    inset: 0;
    top: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 4px;
    background: #331111;
    border: 1px solid #cc3333;
    color: #ff6666;
    border-radius: var(--radius);
    z-index: 10;
  }
</style>
