<template>
  <v-menu location="bottom start" :close-on-content-click="false">
    <template #activator="{ props }">
      <button
        v-bind="props" type="button"
        class="fc-pulse" :class="`fc-pulse--${schedHealth}`"
        :aria-label="`pipeline: ${running} running, ${queued} queued, ${failing} failing`"
      >
        <span class="fc-pulse__dot" />
        <span v-if="running" class="fc-pulse__stat">
          <v-icon size="13">mdi-progress-download</v-icon>{{ running }}
        </span>
        <span v-if="queued" class="fc-pulse__stat">
          <v-icon size="13">mdi-tray-full</v-icon>{{ queued }}
        </span>
        <span v-if="failing" class="fc-pulse__stat fc-pulse__stat--err">
          <v-icon size="13">mdi-alert-circle</v-icon>{{ failing }}
        </span>
        <span v-if="!running && !queued && !failing" class="fc-pulse__idle">idle</span>
      </button>
    </template>

    <v-card min-width="300" class="fc-pulse__panel pa-3">
      <div class="fc-pulse__row">
        <span class="fc-pulse__rowdot" :class="`fc-pulse--${schedHealth}`" />
        <strong>Scheduler</strong>
        <v-spacer />
        <span class="fc-pulse__muted">{{ schedLabel }}</span>
      </div>

      <div class="fc-pulse__sec">
        <div class="fc-pulse__sechead">Queues</div>
        <div v-if="busyQueues.length === 0" class="fc-pulse__muted">All idle</div>
        <div v-for="q in busyQueues" :key="q.name" class="fc-pulse__qrow">
          <span>{{ q.name }}</span><v-spacer /><strong>{{ q.depth }}</strong>
        </div>
      </div>

      <div class="fc-pulse__sec fc-pulse__grid">
        <div><span class="fc-pulse__muted">Running</span><div class="fc-pulse__big">{{ running }}</div></div>
        <div><span class="fc-pulse__muted">Queued</span><div class="fc-pulse__big">{{ queued }}</div></div>
        <div>
          <span class="fc-pulse__muted">Failures 24h</span>
          <div class="fc-pulse__big" :class="{ 'fc-pulse__big--err': failing }">{{ failing }}</div>
        </div>
      </div>

      <RouterLink
        class="fc-pulse__link"
        :to="{ path: '/subscriptions', query: { tab: 'downloads' } }"
      >Open downloads →</RouterLink>
    </v-card>
  </v-menu>
</template>

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

import { useSystemActivityStore } from '../stores/systemActivity.js'
import { formatRelative } from '../utils/date.js'

const store = useSystemActivityStore()

// Beat ticks every 60s; flag the scheduler stale past ~3 min.
const STALE_MS = 180_000
const summary = computed(() => store.summary)
const running = computed(() => summary.value?.running ?? 0)
const queued = computed(() => summary.value?.queued_total ?? 0)
const failing = computed(() => summary.value?.failing ?? 0)

const schedHealth = computed(() => {
  const t = summary.value?.scheduler?.last_tick_at
  if (!t) return 'unknown'
  return (Date.now() - new Date(t).getTime()) <= STALE_MS ? 'ok' : 'stale'
})
const schedLabel = computed(() => {
  const s = summary.value?.scheduler
  if (!s) return '—'
  const ran = formatRelative(s.last_tick_at, { nullText: 'never' })
  if (s.due_now > 0) return `ran ${ran} · ${s.due_now} due`
  return `ran ${ran}`
})
const busyQueues = computed(() => {
  const q = summary.value?.queues || {}
  return Object.entries(q)
    .filter(([, depth]) => typeof depth === 'number' && depth > 0)
    .map(([name, depth]) => ({ name, depth }))
})

const POLL_MS = 8000
let timer = null
onMounted(() => {
  store.loadSummary()
  timer = setInterval(() => {
    if (!document.hidden) store.loadSummary()
  }, POLL_MS)
})
onUnmounted(() => { if (timer) clearInterval(timer) })
</script>

<style scoped>
.fc-pulse {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px; border-radius: 999px;
  background: rgb(var(--v-theme-on-surface) / 0.08);
  color: rgb(var(--v-theme-on-surface));
  font-size: 0.78rem; font-variant-numeric: tabular-nums;
  cursor: pointer; border: 0;
}
.fc-pulse:hover { background: rgb(var(--v-theme-on-surface) / 0.16); }
.fc-pulse__dot {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  background: rgb(var(--v-theme-on-surface-variant));
}
.fc-pulse--ok .fc-pulse__dot,
.fc-pulse--ok.fc-pulse__rowdot { background: rgb(var(--v-theme-success)); }
.fc-pulse--stale .fc-pulse__dot,
.fc-pulse--stale.fc-pulse__rowdot { background: rgb(var(--v-theme-error)); }
.fc-pulse__stat { display: inline-flex; align-items: center; gap: 2px; }
.fc-pulse__stat--err { color: rgb(var(--v-theme-error)); }
.fc-pulse__idle {
  text-transform: uppercase; letter-spacing: 0.06em;
  color: rgb(var(--v-theme-on-surface-variant)); font-size: 0.68rem;
}

.fc-pulse__panel { background: rgb(var(--v-theme-surface)); }
.fc-pulse__row { display: flex; align-items: center; gap: 8px; }
.fc-pulse__rowdot {
  width: 9px; height: 9px; border-radius: 50%;
  background: rgb(var(--v-theme-on-surface-variant));
}
.fc-pulse__muted { color: rgb(var(--v-theme-on-surface-variant)); font-size: 0.8rem; }
.fc-pulse__sec { margin-top: 12px; }
.fc-pulse__sechead {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: rgb(var(--v-theme-on-surface-variant)); margin-bottom: 4px;
}
.fc-pulse__qrow { display: flex; align-items: center; font-size: 0.85rem; padding: 2px 0; }
.fc-pulse__grid { display: flex; gap: 16px; }
.fc-pulse__big { font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.fc-pulse__big--err { color: rgb(var(--v-theme-error)); }
.fc-pulse__link {
  display: inline-block; margin-top: 14px;
  color: rgb(var(--v-theme-accent)); text-decoration: none; font-size: 0.85rem;
}
</style>
