<script setup lang="ts">
import { PLANNED_SERVICES } from '~/data/fixtures'

// Shape returned by /api/health/platform on platform-api.
interface ProbeResult {
  id: string
  name: string
  role: string
  status: 'ok' | 'warn' | 'bad'
  latencyMs: number | null
  error?: string
  checkedAt: string
}

const { data: probes, pending, refresh } = await useFetch<ProbeResult[]>('/api/health/platform', {
  default: () => [],
})

// Auto-refresh: every 30s while this page is mounted.
const now = ref(Date.now())
let pollTimer: ReturnType<typeof setInterval> | null = null
let clockTimer: ReturnType<typeof setInterval> | null = null

onMounted(() => {
  pollTimer = setInterval(() => refresh(), 30_000)
  clockTimer = setInterval(() => { now.value = Date.now() }, 1_000)
})
onBeforeUnmount(() => {
  if (pollTimer) clearInterval(pollTimer)
  if (clockTimer) clearInterval(clockTimer)
})

const liveCount = computed(() => (probes.value ?? []).filter((p) => p.status === 'ok').length)
const totalCount = computed(() => (probes.value ?? []).length)
const degradedCount = computed(() => (probes.value ?? []).filter((p) => p.status !== 'ok').length)
const incidentActive = computed(() => degradedCount.value > 0)

const lastCheckedAt = computed(() => {
  const first = probes.value?.[0]
  return first ? new Date(first.checkedAt).getTime() : null
})
const checkedAgo = computed(() => {
  if (!lastCheckedAt.value) return '—'
  const s = Math.max(0, Math.floor((now.value - lastCheckedAt.value) / 1000))
  return `${s}s ago`
})

function tone(p: ProbeResult): 'ok' | 'warn' | 'bad' {
  return p.status
}
function label(p: ProbeResult) {
  return p.status === 'ok' ? 'operational' : p.status === 'warn' ? 'degraded' : 'down'
}
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Operations"
      title="Infrastructure"
      :subtitle="`${liveCount} / ${totalCount} services live · checked ${checkedAgo}`"
    >
      <template #actions>
        <UiButton variant="secondary" :disabled="pending" @click="refresh()">
          <template #leading><UiIcon name="refresh" :size="13" /></template>
          Refresh
        </UiButton>
      </template>
    </PageHeader>

    <div class="stage">
      <div v-if="incidentActive" class="incident">
        <span class="pill">
          <span class="dot" />
          DEGRADED
        </span>
        <div class="body">
          <div class="title">{{ degradedCount }} service(s) reporting non-ok status</div>
          <div class="sub">{{ (probes ?? []).filter((p) => p.status !== 'ok').map((p) => p.name).join(', ') }}</div>
        </div>
      </div>

      <Eyebrow class="section-head">Live · {{ totalCount }} services</Eyebrow>

      <div class="grid">
        <Card v-for="p in probes" :key="p.id" :pad="0">
          <div class="head">
            <div>
              <div class="name">{{ p.name }}</div>
              <Mono dim>{{ p.role }}</Mono>
            </div>
            <Badge :tone="tone(p)" dot>{{ label(p) }}</Badge>
          </div>
          <div class="metrics">
            <MetricCell label="uptime · 30d" value="—" :title="'no probe history yet'" />
            <MetricCell
              label="p95 latency"
              :value="p.latencyMs !== null ? `${p.latencyMs}ms` : '—'"
              :tone="p.latencyMs !== null && p.latencyMs > 300 ? 'warn' : undefined"
            />
            <MetricCell label="error rate" value="—" :title="'no probe history yet'" />
          </div>
          <div class="foot">
            <Mono dim>probed {{ checkedAgo }}</Mono>
            <Mono v-if="p.status !== 'ok' && p.error" :class="['err', p.status]" :title="p.error">
              {{ p.status === 'bad' ? 'down' : 'slow' }} · {{ p.error.slice(0, 32) }}
            </Mono>
            <Mono v-else dim>{{ p.status === 'ok' ? 'ok' : 'check details' }}</Mono>
          </div>
        </Card>
      </div>

      <Eyebrow class="section-head">Planned · {{ PLANNED_SERVICES.length }} services · not deployed</Eyebrow>

      <div class="grid planned">
        <Card v-for="s in PLANNED_SERVICES" :key="s.id" :pad="0">
          <div class="head">
            <div>
              <div class="name">{{ s.name }}</div>
              <Mono dim>{{ s.role }}</Mono>
            </div>
            <Badge tone="neutral" dot>not deployed</Badge>
          </div>
          <div class="planned-body">
            <Mono dim>{{ s.note }}</Mono>
          </div>
        </Card>
      </div>

      <Mono dim class="note">
        // probes live in services/platform-api/src/health/. uptime / error rate stay
        em-dashed until a probe history (Prometheus, persisted event log) lands —
        see "Real observability" in NEXT-STEPS.md follow-ups
      </Mono>
    </div>
  </div>
</template>

<style scoped>
.stage { padding: 24px 40px 64px 40px; display: flex; flex-direction: column; gap: 16px; }

.section-head { display: block; padding: 6px 4px; }

.incident {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  background: rgba(226, 48, 48, 0.06);
  border: 1px solid rgba(226, 48, 48, 0.3);
  border-left: 3px solid var(--bad);
  border-radius: 8px;
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  background: var(--bad);
  color: #fff;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.08em;
}
.pill .dot { width: 6px; height: 6px; border-radius: 999px; background: #fff; }
.body { flex: 1; min-width: 0; }
.title { font-size: 14px; font-weight: 600; }
.sub { font-size: 12px; color: var(--text-mute); margin-top: 2px; }

.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.grid.planned { opacity: 0.6; }

.head {
  padding: 16px 18px 12px 18px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
}
.name { font-family: var(--font-display); font-weight: 600; font-size: 17px; }

.metrics {
  padding: 12px 18px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.foot {
  padding: 10px 18px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.err.bad  { color: var(--bad); }
.err.warn { color: var(--warn); }

.planned-body { padding: 14px 18px; }

.note { display: block; padding: 4px 4px 0 4px; }
</style>
