<template>
  <div v-if="status" class="fc-sched" :class="`fc-sched--${health}`">
    <span class="fc-sched__dot" />
    <span class="fc-sched__label">Scheduler</span>
    <span class="fc-sched__sep">·</span>
    <span class="fc-sched__item">
      <v-icon size="x-small">mdi-clock-outline</v-icon>
      last ran {{ lastRanLabel }}
    </span>
    <span class="fc-sched__sep">·</span>
    <span class="fc-sched__item">
      <v-icon size="x-small">mdi-calendar-clock</v-icon>
      {{ nextLabel }}
    </span>
    <span class="fc-sched__sep">·</span>
    <span class="fc-sched__item">
      {{ status.auto_sources }} on schedule
    </span>
    <v-tooltip activator="parent" location="bottom">
      {{ tooltip }}
    </v-tooltip>
  </div>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  // { last_tick_at, next_due_at, due_now, auto_sources } | null
  status: { type: Object, default: null },
})

// The Beat tick fires every 60s; if the last stamp is older than ~3
// minutes the scheduler (Beat) is almost certainly down.
const STALE_MS = 180_000

const tickAgeMs = computed(() => {
  const t = props.status?.last_tick_at
  if (!t) return null
  return Date.now() - new Date(t).getTime()
})

const health = computed(() => {
  if (tickAgeMs.value == null) return 'unknown'
  return tickAgeMs.value <= STALE_MS ? 'ok' : 'stale'
})

function rel(ms) {
  const s = Math.max(0, Math.floor(ms / 1000))
  if (s < 60) return `${s}s ago`
  if (s < 3600) return `${Math.floor(s / 60)}m ago`
  if (s < 86400) return `${Math.floor(s / 3600)}h ago`
  return `${Math.floor(s / 86400)}d ago`
}

const lastRanLabel = computed(() =>
  tickAgeMs.value == null ? 'never' : rel(tickAgeMs.value),
)

const nextLabel = computed(() => {
  const due = props.status?.due_now || 0
  if (due > 0) return `${due} due now`
  const n = props.status?.next_due_at
  if (!n) return 'nothing scheduled'
  const diff = new Date(n).getTime() - Date.now()
  if (diff <= 0) return 'check due'
  const s = Math.floor(diff / 1000)
  if (s < 60) return `next in ${s}s`
  if (s < 3600) return `next in ${Math.floor(s / 60)}m`
  if (s < 86400) return `next in ${Math.floor(s / 3600)}h`
  return `next in ${Math.floor(s / 86400)}d`
})

const tooltip = computed(() => {
  if (health.value === 'unknown') return 'The scheduler has not ticked yet (or the worker just started).'
  if (health.value === 'stale') return 'The scheduler tick is overdue — check that Celery Beat is running.'
  return 'Celery Beat is firing the periodic source-check tick on schedule.'
})
</script>

<style scoped>
.fc-sched {
  display: inline-flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
  font-size: 0.78rem;
  color: rgb(var(--v-theme-on-surface-variant));
  padding: 4px 10px;
  border-radius: 6px;
  background: rgb(var(--v-theme-on-surface) / 0.04);
}
.fc-sched__dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex: 0 0 auto;
  background: rgb(var(--v-theme-on-surface-variant));
}
.fc-sched--ok .fc-sched__dot { background: rgb(var(--v-theme-success)); }
.fc-sched--stale .fc-sched__dot { background: rgb(var(--v-theme-error)); }
.fc-sched--unknown .fc-sched__dot { background: rgb(var(--v-theme-on-surface-variant)); }
.fc-sched--stale { color: rgb(var(--v-theme-error)); }
.fc-sched__label {
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: rgb(var(--v-theme-on-surface));
}
.fc-sched--stale .fc-sched__label { color: rgb(var(--v-theme-error)); }
.fc-sched__sep { opacity: 0.4; }
.fc-sched__item {
  display: inline-flex; align-items: center; gap: 3px;
  white-space: nowrap;
}
</style>
