<script setup lang="ts">
import { ref, watch, nextTick, computed } from 'vue'
import Panel from '@framework/components/Panel.vue'
import { useStore } from '@/store'

const { state, activeFrameIndex, selectedFrames, seek, setSelectAll } = useStore()

const cardEls = ref<Record<number, HTMLElement>>({})

// Thumbnail width (px), persisted. Height derives from a ~16:9 ratio.
const MIN_W = 90
const MAX_W = 360
const STEP = 30
const cardW = ref(clampW(Number(localStorage.getItem('meetus.frameW')) || 150))
watch(cardW, (w) => localStorage.setItem('meetus.frameW', String(w)))

const thumbH = computed(() => Math.round(cardW.value * 0.56))

function clampW(w: number) { return Math.max(MIN_W, Math.min(MAX_W, w)) }
function grow() { cardW.value = clampW(cardW.value + STEP) }
function shrink() { cardW.value = clampW(cardW.value - STEP) }

function setCard(i: number, el: Element | null) {
  if (el) cardEls.value[i] = el as HTMLElement
}

function fmt(seconds: number | null): string {
  if (seconds == null) return '—'
  const m = Math.floor(seconds / 60)
  const s = Math.floor(seconds % 60)
  return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
}

watch(activeFrameIndex, async (i) => {
  if (i < 0) return
  await nextTick()
  cardEls.value[i]?.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' })
})
</script>

<template>
  <Panel title="Frames">
    <template #actions>
      <span class="count">{{ selectedFrames.length }}/{{ state.frames.length }} selected</span>
      <div class="sizer">
        <button title="Smaller" :disabled="cardW <= MIN_W" @click="shrink">−</button>
        <button title="Larger" :disabled="cardW >= MAX_W" @click="grow">+</button>
      </div>
      <button @click="setSelectAll(true)">All</button>
      <button @click="setSelectAll(false)">None</button>
    </template>
    <div class="strip">
      <p v-if="!state.frames.length" class="empty">No frames for this run.</p>
      <div
        v-for="(f, i) in state.frames"
        :key="f.file"
        :ref="(el) => setCard(i, el as Element | null)"
        class="card"
        :class="{ active: i === activeFrameIndex, off: !f.selected }"
        :style="{ width: cardW + 'px' }"
      >
        <div
          class="thumb"
          :style="{ height: thumbH + 'px' }"
          @click="f.time != null && seek(f.time)"
          :title="f.time != null ? 'Seek here' : 'No timestamp'"
        >
          <img :src="f.url" loading="lazy" :alt="f.file" />
          <span class="time">{{ fmt(f.time) }}</span>
        </div>
        <label class="pick">
          <input type="checkbox" v-model="f.selected" />
          include
        </label>
      </div>
    </div>
  </Panel>
</template>

<style scoped>
.strip {
  height: 100%;
  overflow-y: auto;
  padding: var(--space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-content: flex-start;
}
.empty {
  color: var(--text-secondary);
  padding: var(--space-4);
}
.card {
  border: 1px solid var(--border);
  border-radius: var(--panel-radius);
  overflow: hidden;
  background: var(--surface-1);
}
.card.active {
  border-color: var(--status-processing);
  box-shadow: 0 0 0 1px var(--status-processing);
}
.card.off {
  opacity: 0.45;
}
.thumb {
  position: relative;
  cursor: pointer;
  line-height: 0;
}
.thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  background: #000;
}
.time {
  position: absolute;
  bottom: 2px;
  right: 2px;
  font-family: var(--font-mono);
  font-size: var(--font-size-sm);
  background: rgba(0, 0, 0, 0.65);
  color: var(--text-primary);
  padding: 0 4px;
  border-radius: 3px;
}
.pick {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  cursor: pointer;
}
.count {
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
}
.sizer {
  display: flex;
  gap: 2px;
}
.sizer button {
  width: 24px;
  padding: var(--space-1) 0;
  font-weight: 600;
  line-height: 1;
}
</style>
