<template>
  <BaseBottomSheet :model-value="modelValue" label="Add sticker" @update:model-value="$emit('update:modelValue', $event)">
    <div class="sticker-tray">
      <!-- Recently used row — surfaces the user's last picks first so
           common stickers (a heart, a snowflake) are one tap away. -->
      <section v-if="recents.length" class="sticker-tray__section">
        <h3 class="sticker-tray__heading">Recent</h3>
        <div class="sticker-tray__row">
          <button
            v-for="r in recents"
            :key="r.key"
            type="button"
            class="sticker-tray__chip"
            :aria-label="r.label"
            @click="pickRecent(r)"
          >
            <span v-if="r.kind === 'emoji'" class="sticker-tray__emoji" aria-hidden="true">{{ r.emoji }}</span>
            <img v-else :src="r.url" alt="" class="sticker-tray__img" />
          </button>
        </div>
      </section>

      <!-- Custom (non-emoji) sprites the user asked for. Renders alongside
           recents so they're easy to grab without navigating away. -->
      <section class="sticker-tray__section">
        <h3 class="sticker-tray__heading">Stickers</h3>
        <div class="sticker-tray__row">
          <button
            v-for="a in CUSTOM_STICKER_ASSETS"
            :key="a.id"
            type="button"
            class="sticker-tray__chip"
            :aria-label="a.label"
            @click="pickCustom(a)"
          >
            <img :src="a.url" :alt="a.label" class="sticker-tray__img" />
          </button>
        </div>
      </section>

      <!-- Emoji input — focusing the field opens the OS emoji keyboard
           on iOS/Android. Desktop users can paste or type any emoji.
           We capture the *last* grapheme so users can pick several in a
           row without the field accumulating. -->
      <section class="sticker-tray__section">
        <h3 class="sticker-tray__heading">Any emoji</h3>
        <p class="sticker-tray__hint">Tap the box, then pick from your keyboard's emoji button.</p>
        <input
          type="text"
          class="sticker-tray__emoji-input"
          inputmode="text"
          autocomplete="off"
          autocorrect="off"
          autocapitalize="off"
          spellcheck="false"
          placeholder="😀 🎉 🐶 …"
          aria-label="Emoji input — use your keyboard's emoji button"
          @input="onEmojiInput"
        />
      </section>
    </div>
  </BaseBottomSheet>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import BaseBottomSheet from '@/components/BaseBottomSheet.vue'
import { CUSTOM_STICKER_ASSETS, type CustomStickerAsset } from '@/assets/stickers/customAssets'

defineProps<{ modelValue: boolean }>()
const emit = defineEmits<{
  (e: 'update:modelValue', v: boolean): void
  (e: 'pick', payload: { emoji?: string; imageAsset?: string }): void
}>()

interface RecentItem {
  key: string
  kind: 'emoji' | 'image'
  label: string
  emoji?: string
  imageAsset?: string
  url?: string
}

const RECENTS_KEY = 'pf.stickerTray.recents'
const MAX_RECENTS = 12

const recents = ref<RecentItem[]>([])

onMounted(() => {
  recents.value = loadRecents()
})

function loadRecents(): RecentItem[] {
  try {
    const raw = localStorage.getItem(RECENTS_KEY)
    if (!raw) return []
    const parsed = JSON.parse(raw) as RecentItem[]
    // Re-hydrate image URLs from the asset registry — assets may move
    // across builds, but the id stays stable.
    return parsed.map(r => {
      if (r.kind === 'image' && r.imageAsset) {
        const a = CUSTOM_STICKER_ASSETS.find(x => x.id === r.imageAsset)
        return { ...r, url: a?.url, label: a?.label ?? r.label }
      }
      return r
    }).filter(r => r.kind === 'emoji' ? !!r.emoji : !!r.url)
  } catch {
    return []
  }
}

function persistRecents() {
  try {
    localStorage.setItem(RECENTS_KEY, JSON.stringify(recents.value))
  } catch { /* quota / private mode — non-fatal */ }
}

function rememberRecent(item: RecentItem) {
  recents.value = [item, ...recents.value.filter(r => r.key !== item.key)].slice(0, MAX_RECENTS)
  persistRecents()
}

function firstGrapheme(input: string): string | null {
  if (!input) return null
  // Intl.Segmenter understands ZWJ-joined emoji ("👨‍👩‍👧" is one grapheme,
  // not five) so multi-codepoint emoji come through whole.
  if (typeof Intl !== 'undefined' && (Intl as any).Segmenter) {
    const seg = new (Intl as any).Segmenter(undefined, { granularity: 'grapheme' })
    const list = [...seg.segment(input)] as Array<{ segment: string }>
    return list[list.length - 1]?.segment ?? null
  }
  // Fallback for older browsers without Intl.Segmenter.
  return [...input].pop() ?? null
}

function onEmojiInput(e: Event) {
  const el = e.target as HTMLInputElement
  const grapheme = firstGrapheme(el.value)
  el.value = ''
  if (!grapheme) return
  const item: RecentItem = {
    key: `emoji:${grapheme}`,
    kind: 'emoji',
    label: grapheme,
    emoji: grapheme,
  }
  rememberRecent(item)
  emit('pick', { emoji: grapheme })
}

function pickCustom(a: CustomStickerAsset) {
  rememberRecent({
    key: `image:${a.id}`,
    kind: 'image',
    label: a.label,
    imageAsset: a.id,
    url: a.url,
  })
  emit('pick', { imageAsset: a.id })
}

function pickRecent(r: RecentItem) {
  rememberRecent(r)
  if (r.kind === 'emoji' && r.emoji) {
    emit('pick', { emoji: r.emoji })
  } else if (r.kind === 'image' && r.imageAsset) {
    emit('pick', { imageAsset: r.imageAsset })
  }
}
</script>

<style scoped lang="scss">
.sticker-tray {
  &__section {
    margin-bottom: var(--space-4);
    &:last-child { margin-bottom: 0; }
  }

  &__heading {
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text-muted);
    margin: 0 0 var(--space-2);
  }

  &__hint {
    font-size: var(--text-xs);
    color: var(--color-text-muted);
    margin: 0 0 var(--space-2);
    line-height: 1.4;
  }

  &__row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
  }

  &__chip {
    width: 56px;
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    cursor: pointer;
    transition: background var(--duration-fast), border-color var(--duration-fast);

    &:active {
      background: var(--color-surface-2);
      border-color: var(--color-primary);
    }
  }

  &__emoji {
    font-size: 32px;
    line-height: 1;
    font-family: "Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif;
  }

  &__img {
    width: 40px;
    height: 40px;
    object-fit: contain;
    pointer-events: none;
  }

  &__emoji-input {
    width: 100%;
    min-height: var(--touch-min);
    padding: 0 var(--space-3);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    // 16px+ avoids iOS Safari's auto-zoom-on-focus.
    font-size: 18px;
    font-family: inherit;

    &:focus {
      outline: 2px solid var(--color-primary);
      outline-offset: 2px;
      border-color: var(--color-primary);
    }
  }
}
</style>
