<template>
  <h1>Dashboard</h1>
  <p v-if="error" class="error">{{ error }}</p>
  <p v-else-if="loading">Загрузка…</p>
  <template v-else-if="data">
    <div class="dashboard-cards">
      <div class="dash-card">
        <div class="dash-value">{{ data.events_last_24h }}</div>
        <div class="dash-label">Событий за 24 ч</div>
        <RouterLink to="/events">Все события →</RouterLink>
      </div>
      <div class="dash-card">
        <div class="dash-value">{{ data.problems_open }}</div>
        <div class="dash-label">Открытых проблем</div>
        <RouterLink :to="{ path: '/problems', query: { status: 'open' } }">Проблемы →</RouterLink>
      </div>
      <div class="dash-card">
        <div class="dash-value">{{ data.hosts_total }}</div>
        <div class="dash-label">Хостов</div>
        <RouterLink to="/hosts">Хосты →</RouterLink>
      </div>
      <div class="dash-card" :class="{ 'dash-warn': data.hosts_stale > 0 }">
        <div class="dash-value">{{ data.hosts_stale }}</div>
        <div class="dash-label">Устаревший heartbeat</div>
        <RouterLink to="/hosts">Хосты →</RouterLink>
      </div>
      <div class="dash-card">
        <div class="dash-value">{{ data.heartbeats_24h }}</div>
        <div class="dash-label">Heartbeat за 24 ч</div>
        <RouterLink to="/events?type=agent.heartbeat">События →</RouterLink>
      </div>
      <div class="dash-card">
        <div class="dash-value">{{ data.daily_reports_24h }}</div>
        <div class="dash-label">Отчёты за 24 ч</div>
        <RouterLink to="/reports">Отчёты →</RouterLink>
      </div>
    </div>

    <h2>Severity за 24 ч</h2>
    <ul class="severity-list">
      <li v-for="(count, sev) in data.severity_24h" :key="sev">
        <span :class="'sev-' + sev">{{ sev }}</span>: {{ count }}
      </li>
      <li v-if="!Object.keys(data.severity_24h).length">Нет событий</li>
    </ul>

    <h2>Последние события</h2>
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Время</th>
          <th>Хост</th>
          <th>Severity</th>
          <th>Title</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="e in data.recent_events" :key="e.id">
          <td>
            <RouterLink :to="`/events/${e.id}`">{{ e.id }}</RouterLink>
          </td>
          <td>{{ formatDt(e.occurred_at) }}</td>
          <td>{{ e.hostname }}</td>
          <td :class="'sev-' + e.severity">{{ e.severity }}</td>
          <td>{{ e.title }}</td>
        </tr>
      </tbody>
    </table>
    <div class="filters" style="margin-top: 1rem">
      <button type="button" class="secondary" @click="load">Обновить</button>
      <span v-if="live" class="live-badge">live</span>
    </div>
  </template>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";
import { apiFetch, getToken, type DashboardSummary } from "../api";

const data = ref<DashboardSummary | null>(null);
const loading = ref(false);
const error = ref("");
const live = ref(false);
let eventSource: EventSource | null = null;

function formatDt(iso: string) {
  return new Date(iso).toLocaleString("ru-RU");
}

async function load() {
  loading.value = true;
  error.value = "";
  try {
    data.value = await apiFetch<DashboardSummary>("/api/v1/dashboards/summary");
  } catch (e) {
    error.value = e instanceof Error ? e.message : String(e);
  } finally {
    loading.value = false;
  }
}

function connectLive() {
  const token = getToken();
  if (!token) return;
  eventSource?.close();
  const url = `/api/v1/stream/events?token=${encodeURIComponent(token)}`;
  eventSource = new EventSource(url);
  eventSource.onopen = () => {
    live.value = true;
  };
  eventSource.onmessage = (ev) => {
    try {
      const msg = JSON.parse(ev.data) as {
        type?: string;
        events_last_24h?: number;
        problems_open?: number;
        hosts_stale?: number;
        heartbeats_24h?: number;
        daily_reports_24h?: number;
      };
      if (msg.type !== "dashboard" || !data.value) return;
      if (typeof msg.events_last_24h === "number") {
        data.value.events_last_24h = msg.events_last_24h;
      }
      if (typeof msg.problems_open === "number") {
        data.value.problems_open = msg.problems_open;
      }
      if (typeof msg.hosts_stale === "number") {
        data.value.hosts_stale = msg.hosts_stale;
      }
      if (typeof msg.heartbeats_24h === "number") {
        data.value.heartbeats_24h = msg.heartbeats_24h;
      }
      if (typeof msg.daily_reports_24h === "number") {
        data.value.daily_reports_24h = msg.daily_reports_24h;
      }
    } catch {
      /* ignore malformed SSE */
    }
  };
  eventSource.onerror = () => {
    live.value = false;
  };
}

onMounted(() => {
  load().then(() => connectLive());
});

onUnmounted(() => {
  eventSource?.close();
  eventSource = null;
});
</script>
