<template>
  <div class="fc-facets">
    <v-progress-linear
      v-if="store.facetsLoading" indeterminate color="accent"
      class="fc-facets__bar" height="2"
    />

    <div class="fc-facets__group">
      <span class="fc-facets__label">Platform</span>
      <div class="fc-facets__chips">
        <v-chip
          v-for="p in platformOptions" :key="p.key"
          size="small" label
          :variant="p.key === store.filter.platform ? 'flat' : 'tonal'"
          :color="p.key === store.filter.platform ? 'accent' : undefined"
          @click="selectPlatform(p.key)"
        >{{ p.label }}<span class="fc-facets__count">{{ p.count }}</span></v-chip>
        <span v-if="!platformOptions.length" class="fc-facets__empty">none</span>
      </div>
    </div>

    <div class="fc-facets__group">
      <span class="fc-facets__label">Curation</span>
      <div class="fc-facets__chips">
        <v-chip
          size="small" label
          :variant="store.filter.untagged ? 'flat' : 'tonal'"
          :color="store.filter.untagged ? 'accent' : undefined"
          @click="toggleFlag('untagged')"
        >Untagged<span class="fc-facets__count">{{ facetCount('untagged') }}</span></v-chip>
        <v-chip
          size="small" label
          :variant="store.filter.no_artist ? 'flat' : 'tonal'"
          :color="store.filter.no_artist ? 'accent' : undefined"
          @click="toggleFlag('no_artist')"
        >No artist<span class="fc-facets__count">{{ facetCount('no_artist') }}</span></v-chip>
        <!-- Reveal presentation chrome (banner / editor screenshot) the gallery
             hides by default (milestone 141). A browse-mode toggle, not a count. -->
        <v-chip
          size="small" label
          :variant="store.filter.include_hidden ? 'flat' : 'tonal'"
          :color="store.filter.include_hidden ? 'accent' : undefined"
          title="Show hidden — reveal banners / editor screenshots the gallery sets aside by default"
          @click="toggleFlag('include_hidden')"
        >Show hidden</v-chip>
      </div>
    </div>

    <div class="fc-facets__group">
      <span class="fc-facets__label">Date</span>
      <v-text-field
        type="date" density="compact" hide-details variant="outlined"
        :model-value="store.filter.date_from" :min="dateMin" :max="dateMax"
        class="fc-facets__date"
        @update:model-value="setDate('date_from', $event)"
      />
      <span class="fc-facets__dash">–</span>
      <v-text-field
        type="date" density="compact" hide-details variant="outlined"
        :model-value="store.filter.date_to" :min="dateMin" :max="dateMax"
        class="fc-facets__date"
        @update:model-value="setDate('date_to', $event)"
      />
    </div>
  </div>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { cloneFilter, filterToQuery, useGalleryStore } from '../../stores/gallery.js'

// Mirrors backend gallery_service.UNSOURCED_PLATFORM — the sentinel that
// selects filesystem-imported content (the null/"no platform" bucket).
const UNSOURCED = '__unsourced__'

const store = useGalleryStore()
const router = useRouter()

const platformOptions = computed(() =>
  (store.facets?.platforms || []).map((p) => ({
    key: p.value === null ? UNSOURCED : p.value,
    label: p.value === null ? 'No platform' : p.value,
    count: p.count,
  }))
)

function facetCount(flag) {
  const v = store.facets?.[flag]
  return v == null ? '–' : v
}

const dateMin = computed(() => (store.facets?.date_min || '').slice(0, 10) || undefined)
const dateMax = computed(() => (store.facets?.date_max || '').slice(0, 10) || undefined)

// Single write path, shared format with the bar: clone → patch → URL. The
// route watcher in GalleryView reloads the store (and our filter-watch below
// refetches the facet counts for the new scope).
function pushPatch(patch) {
  const n = cloneFilter(store.filter)
  Object.assign(n, patch)
  router.push({ name: 'gallery', query: filterToQuery(n) })
}

function selectPlatform(key) {
  // Single-select, click-active-to-clear (the platform param is one value).
  pushPatch({ platform: store.filter.platform === key ? null : key })
}
function toggleFlag(name) {
  pushPatch({ [name]: !store.filter[name] })
}
function setDate(field, val) {
  pushPatch({ [field]: val || null })
}

// Fetch when the panel opens; refetch (debounced) whenever the active filter
// changes so the live counts track the current scope. Never fires on scroll —
// the panel is the only caller of loadFacets.
onMounted(() => store.loadFacets())

let debounce = null
watch(() => store.filter, () => {
  if (debounce) clearTimeout(debounce)
  debounce = setTimeout(() => store.loadFacets(), 250)
})
onBeforeUnmount(() => { if (debounce) clearTimeout(debounce) })
</script>

<style scoped>
.fc-facets {
  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  padding: 4px 12px 12px;
}
.fc-facets__bar { position: absolute; top: 0; left: 0; right: 0; }
.fc-facets__group { display: flex; align-items: center; gap: 8px; }
.fc-facets__label {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: rgb(var(--v-theme-on-surface-variant));
}
.fc-facets__chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* The count rides inside the chip as a dimmer trailing number. */
.fc-facets__count {
  margin-left: 6px;
  opacity: 0.7;
  font-variant-numeric: tabular-nums;
  font-size: 0.78em;
}
.fc-facets__empty { color: rgb(var(--v-theme-on-surface-variant)); font-size: 0.8rem; }
.fc-facets__date { max-width: 160px; }
.fc-facets__dash { color: rgb(var(--v-theme-on-surface-variant)); }

/* Phones: let each facet group wrap and the side-by-side date inputs grow to
   full width so they don't overflow a ~360px viewport. */
@media (max-width: 480px) {
  .fc-facets__group { flex-wrap: wrap; }
  .fc-facets__date { max-width: none; flex: 1 1 9rem; }
}
</style>
