<template>
  <v-container fluid class="pt-2 pb-6">
    <Teleport to="#fc-nav-actions">
      <v-btn
        prepend-icon="mdi-shuffle-variant" variant="tonal" color="accent"
        size="small" :loading="store.loading" @click="store.shuffle()"
      >Shuffle</v-btn>
    </Teleport>

    <v-alert v-if="store.error" type="error" variant="tonal" closable class="my-4">
      Failed to load: {{ store.error }}
    </v-alert>
    <v-alert v-else-if="store.isEmpty" type="info" variant="tonal" class="my-4">
      No images yet.
    </v-alert>

    <MasonryGrid
      :items="store.images"
      :loading="store.loading"
      :has-more="store.hasMore"
      :animate-from-index="animateFromIndex"
      @load-more="store.fetchPage()"
      @open="openImage"
    />
  </v-container>
</template>

<script setup>
import { onMounted, onUnmounted, ref, watch } from 'vue'

import MasonryGrid from '../components/discovery/MasonryGrid.vue'
import { useModalStore } from '../stores/modal.js'
import { useShowcaseStore } from '../stores/showcase.js'

const store = useShowcaseStore()
const modal = useModalStore()

// Track when items were appended vs replaced so MasonryGrid only animates
// items new to the current batch (mirrors IR's behavior: animate on
// initial load and on shuffle, but skip silent infinite-scroll appends).
const animateFromIndex = ref(0)
let prevCount = 0
watch(() => store.images.length, (newCount) => {
  if (newCount < prevCount || prevCount === 0) {
    // Reset (shuffle) or initial load — animate everything from 0.
    animateFromIndex.value = 0
  } else {
    // Append — only animate the newly-added tail.
    animateFromIndex.value = prevCount
  }
  prevCount = newCount
})

function openImage(id) {
  modal.open(id)
}

// IR-parity keyboard shuffle: press R anywhere on the page (not inside a
// text input, not while a Vuetify overlay is open) to reshuffle.
function onKeydown(e) {
  const t = e.target
  if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.isContentEditable)) return
  // Vuetify marks the active overlay (v-dialog, v-menu) on the body when
  // open. Skip shuffle when a modal is in the way.
  if (document.querySelector('.v-overlay--active')) return
  if (e.key === 'r' || e.key === 'R') {
    e.preventDefault()
    store.shuffle()
  }
}

onMounted(() => {
  // Operator-stated 2026-06-02: every load of the showcase view should
  // show new images. Pinia persists the store across navigations, so
  // returning to /showcase used to render the same set as before. Now
  // we always reshuffle on mount — loadInitial() resets `seen`,
  // `images`, and `exhausted` and pipelines a fresh batch.
  store.loadInitial()
  window.addEventListener('keydown', onKeydown)
})
onUnmounted(() => window.removeEventListener('keydown', onKeydown))
</script>
