<script>
  // Full searchable emoji picker for the Publishing Desk. Data is bundled locally
  // (emoji-data.js) — no runtime/CDN fetch. Calls onpick(char) for each selection;
  // stays open so several can be inserted in a row. Recents persist in localStorage.
  import { EMOJI_GROUPS } from './emoji-data.js';

  let { onpick } = $props();

  let q = $state('');
  let recent = $state([]);
  const RECENT_KEY = 'ub.pub.emojiRecent';

  $effect(() => {
    try { recent = JSON.parse(localStorage.getItem(RECENT_KEY) || '[]'); } catch { recent = []; }
  });

  function pick(c) {
    onpick(c);
    const next = [c, ...recent.filter((x) => x !== c)].slice(0, 24);
    recent = next;
    try { localStorage.setItem(RECENT_KEY, JSON.stringify(next)); } catch { /* private mode */ }
  }

  // search across name + keyword slug; null when the box is empty (→ show grouped view)
  const matches = $derived.by(() => {
    const term = q.trim().toLowerCase();
    if (!term) return null;
    const res = [];
    for (const g of EMOJI_GROUPS)
      for (const e of g.emojis)
        if (e.n.includes(term) || e.k.includes(term)) res.push(e);
    return res;
  });

  let sections = {};   // group name -> section element, for the jump tabs
  function jump(name) { sections[name]?.scrollIntoView({ block: 'start', behavior: 'smooth' }); }
</script>

<div class="ep">
  <input class="ep-search" placeholder="Search emoji…" bind:value={q} autocomplete="off" />

  {#if !q.trim()}
    <div class="ep-tabs">
      {#if recent.length}<button type="button" title="Recent" onclick={() => jump('__recent')}>🕘</button>{/if}
      {#each EMOJI_GROUPS as g (g.name)}
        <button type="button" title={g.name} onclick={() => jump(g.name)}>{g.emojis[0].c}</button>
      {/each}
    </div>
  {/if}

  <div class="ep-scroll">
    {#if matches}
      {#if matches.length}
        <div class="ep-grid">
          {#each matches as e (e.c)}<button type="button" class="ep-em" title={e.n} onclick={() => pick(e.c)}>{e.c}</button>{/each}
        </div>
      {:else}
        <p class="ep-none">No emoji match “{q}”.</p>
      {/if}
    {:else}
      {#if recent.length}
        <div class="ep-sec" bind:this={sections['__recent']}>
          <div class="ep-h">Recent</div>
          <div class="ep-grid">
            {#each recent as c (c)}<button type="button" class="ep-em" onclick={() => pick(c)}>{c}</button>{/each}
          </div>
        </div>
      {/if}
      {#each EMOJI_GROUPS as g (g.name)}
        <div class="ep-sec" bind:this={sections[g.name]}>
          <div class="ep-h">{g.name}</div>
          <div class="ep-grid">
            {#each g.emojis as e (e.c)}<button type="button" class="ep-em" title={e.n} onclick={() => pick(e.c)}>{e.c}</button>{/each}
          </div>
        </div>
      {/each}
    {/if}
  </div>
</div>

<style>
  .ep { width: 300px; }
  .ep-search { width: 100%; box-sizing: border-box; font: inherit; font-size: 0.85rem; padding: 6px 9px;
               border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--ink); }
  .ep-tabs { display: flex; flex-wrap: wrap; gap: 1px; margin: 6px 0; }
  .ep-tabs button { font-size: 1.05rem; line-height: 1; padding: 3px; border: 0; border-radius: 6px;
                    background: transparent; cursor: pointer; }
  .ep-tabs button:hover { background: var(--accent-soft); }
  .ep-scroll { max-height: 230px; overflow-y: auto; margin-top: 4px; }
  .ep-sec { scroll-margin-top: 2px; }
  .ep-h { position: sticky; top: 0; background: var(--card, var(--bg)); font-size: 0.72rem; font-weight: 700;
          color: var(--muted); text-transform: uppercase; letter-spacing: .04em; padding: 4px 2px; }
  .ep-grid { display: grid; grid-template-columns: repeat(8, 1fr); }
  .ep-em { font-size: 1.25rem; line-height: 1; padding: 4px 0; border: 0; border-radius: 7px;
           background: transparent; cursor: pointer; }
  .ep-em:hover { background: var(--accent-soft); }
  .ep-none { font-size: 0.82rem; color: var(--muted); padding: 8px 2px; }
</style>
