<script>
  import { onMount } from 'svelte';
  import { goto } from '$app/navigation';
  import { page } from '$app/stores';
  import { auth, refresh as refreshAuth } from '$lib/auth.svelte.js';
  import { isDevGated, blockedForViewer } from '$lib/devgate.js';
  import Footer from '$lib/components/Footer.svelte';

  let canvas = $state();
  let failed = $state(false);
  let loading = $state(true);

  // Live tuning panel (admins, /zen?debug=1) — dial in the render without redeploys.
  let handle = $state(null);
  let dbg = $state(null);
  let debug = $state(false);
  let copied = $state(false);

  function apply() { handle?.setParams($state.snapshot(dbg)); }
  async function copyValues() {
    try {
      await navigator.clipboard.writeText(JSON.stringify($state.snapshot(dbg), null, 2));
      copied = true; setTimeout(() => (copied = false), 1500);
    } catch { /* clipboard blocked — values are still visible in the panel */ }
  }

  onMount(() => {
    let h;
    let cancelled = false;   // guard the async load against an early unmount
    (async () => {
      // Don't decide the gate until we actually KNOW who's here. A cold load / hard
      // refresh / direct link mounts before auth has revalidated, so auth.user is still
      // null and an admin would be wrongly bounced. Revalidate first, THEN gate.
      if (!auth.ready) { try { await refreshAuth(); } catch { /* offline → treat as gated */ } }
      if (cancelled) return;
      // Dev-gated while UB is being ironed out: non-admins (no preview token) bounce.
      if (blockedForViewer('zen', auth.user, $page.url)) { goto('/play'); return; }
      debug = $page.url.searchParams.get('debug') === '1';
      try {
        // WebGL guard — fall back to a warm card rather than a blank canvas.
        const t = document.createElement('canvas');
        if (!t.getContext('webgl2') && !t.getContext('webgl')) throw new Error('no-webgl');
        const { createAquarium } = await import('$lib/zen/aquarium.js');  // lazy: three loads only here
        h = await createAquarium(canvas);
        if (cancelled) { h.dispose(); return; }   // left /zen mid-load — don't start a loop
        handle = h;
        if (debug) dbg = h.getParams();
        loading = false;
      } catch (e) {
        console.warn('Zen Den could not start:', e);
        if (!cancelled) { failed = true; loading = false; }
      }
    })();
    return () => { cancelled = true; h?.dispose(); };
  });
</script>

<svelte:head>
  <title>The Zen Den · upbeatBytes</title>
  {#if isDevGated('zen')}<meta name="robots" content="noindex" />{/if}
</svelte:head>

<header class="bar">
  <div class="container inner">
    <a class="brand" href="/"><img class="logo" src="/logo.svg" alt="upbeatBytes" /></a>
    <a class="back" href="/play">
      <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M19 12H5M11 6l-6 6 6 6" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round"/></svg>Play
    </a>
  </div>
</header>

<main class="zen container">
  <h1>The Zen Den</h1>
  <p class="sub">Drop in with UB for a quiet minute.</p>

  <div class="tankwrap">
    {#if failed}
      <div class="fallback">
        <div class="fish">🐟</div>
        <p>UB's tank needs a browser with WebGL. He's resting for now — try again on a different device or browser.</p>
      </div>
    {:else}
      <canvas bind:this={canvas} class="tank" aria-label="UB the koi, swimming"></canvas>
      {#if loading}<p class="loadnote">UB is settling in…</p>{/if}
    {/if}
  </div>

  {#if debug && dbg}
    <div class="panel">
      <div class="prow"><strong>UB render tuner</strong><button class="copy" onclick={copyValues}>{copied ? 'copied ✓' : 'copy values'}</button></div>

      <label>preview clip
        <select bind:value={dbg.preview} onchange={apply}>
          <option value="">— live behavior —</option>
          <option>idle</option><option>cruise</option><option>burst</option><option>turnL</option><option>turnR</option>
        </select></label>

      <label>scale <span>{dbg.scale.toFixed(2)}</span>
        <input type="range" min="0.3" max="2.5" step="0.05" bind:value={dbg.scale} oninput={apply} /></label>

      <hr />
      <div class="ph">Behavior</div>
      <label>cruise speed <span>{dbg.baseSpeed.toFixed(2)}</span>
        <input type="range" min="0.1" max="0.8" step="0.02" bind:value={dbg.baseSpeed} oninput={apply} /></label>
      <label>roam width <span>{dbg.boundsX.toFixed(2)}</span>
        <input type="range" min="0.3" max="2" step="0.05" bind:value={dbg.boundsX} oninput={apply} /></label>
      <label>roam height <span>{dbg.boundsY.toFixed(2)}</span>
        <input type="range" min="0" max="1.2" step="0.05" bind:value={dbg.boundsY} oninput={apply} /></label>
      <label>liveliness <span>{dbg.liveliness.toFixed(2)}</span>
        <input type="range" min="0" max="2" step="0.1" bind:value={dbg.liveliness} oninput={apply} /></label>

      <hr />
      <div class="ph">Fins &amp; tail</div>
      <label class="chk"><input type="checkbox" bind:checked={dbg.finTranslucent} onchange={apply} /> translucent (off = opaque, coherent)</label>
      <label>side
        <select bind:value={dbg.finSide} onchange={apply}><option>front</option><option>back</option><option>double</option></select></label>
      <label>alphaTest <span>{dbg.finAlphaTest.toFixed(3)}</span>
        <input type="range" min="0" max="0.9" step="0.01" bind:value={dbg.finAlphaTest} oninput={apply} /></label>
      {#if dbg.finTranslucent}
        <label>opacity <span>{dbg.finOpacity.toFixed(2)}</span>
          <input type="range" min="0" max="1" step="0.05" bind:value={dbg.finOpacity} oninput={apply} /></label>
      {/if}

      <hr />
      <label class="chk"><input type="checkbox" bind:checked={dbg.paused} onchange={apply} /> freeze</label>
    </div>
  {/if}
</main>

<Footer />

<style>
  header.bar { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20; }
  .inner { display: flex; align-items: center; justify-content: space-between; height: 64px; }
  .logo { height: 40px; display: block; }
  .back { color: var(--accent-deep); font-size: 0.9rem; display: inline-flex; align-items: center; gap: 5px; }
  .back svg { width: 17px; height: 17px; display: block; }

  .zen { padding: 22px 20px 60px; }
  h1 { font-size: clamp(2rem, 5vw, 2.6rem); margin: 6px 0 4px; }
  .sub { color: var(--muted); margin: 0 0 18px; }

  /* A calm tank: soft aqua gradient backdrop; the transparent WebGL canvas sits
     on top so the water reads even before we build the real bowl (Phase C). */
  .tankwrap {
    position: relative; width: 100%; max-width: 640px; aspect-ratio: 4 / 3;
    border-radius: 20px; overflow: hidden; box-shadow: var(--shadow);
    background: radial-gradient(120% 100% at 50% 0%, #d6f0f2 0%, #aadbe0 45%, #7cc3cc 100%);
  }
  .tank { display: block; width: 100%; height: 100%; }
  .loadnote { position: absolute; inset: auto 0 16px 0; text-align: center; color: var(--accent-deep);
              font-family: var(--label); font-size: 0.9rem; }
  .fallback { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center;
              justify-content: center; gap: 12px; text-align: center; padding: 24px; color: #2b5560; }
  .fallback .fish { font-size: 3rem; }
  .fallback p { max-width: 340px; margin: 0; }

  /* Dev tuning panel (admins only, ?debug=1). */
  .panel { margin-top: 18px; max-width: 360px; padding: 14px 16px; border: 1px solid var(--line);
           border-radius: 14px; background: var(--surface); font-size: 0.82rem; }
  .prow { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
  .panel hr { border: none; border-top: 1px solid var(--line); margin: 10px 0 6px; }
  .ph { font-family: var(--label); text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.72rem;
        color: var(--muted); margin-bottom: 4px; }
  .panel label { display: block; margin: 6px 0; color: var(--ink); }
  .panel label span { float: right; color: var(--accent-deep); font-variant-numeric: tabular-nums; }
  .panel label.chk { display: flex; align-items: center; gap: 7px; }
  .panel input[type="range"] { width: 100%; margin-top: 3px; }
  .panel select { width: 100%; margin-top: 3px; }
  .copy { font-size: 0.75rem; padding: 4px 9px; border: 1px solid var(--line); border-radius: 8px;
          background: var(--bg); color: var(--accent-deep); cursor: pointer; }

  @media (max-width: 720px) {
    .tankwrap { aspect-ratio: 3 / 4; }   /* taller on phones */
  }
</style>
