<template>
  <p><RouterLink to="/hosts">← Хосты</RouterLink></p>
  <p v-if="error" class="error">{{ error }}</p>
  <p v-else-if="loading">Загрузка…</p>
  <template v-else-if="host">
    <h1>{{ host.display_name || host.hostname }}</h1>
    <div class="card report-meta">
      <p>
        <strong>Hostname:</strong> {{ host.hostname }}
        · <strong>ID:</strong> {{ host.id }}
        · <strong>Агент:</strong> <span :class="'agent-' + host.agent_status">{{ agentLabel(host.agent_status) }}</span>
      </p>
      <p>
        <strong>Версия агента:</strong> {{ host.product_version || "—" }}
        · <strong>OS:</strong> {{ host.os_family }} {{ host.os_version || "" }}
        · <strong>IPv4:</strong> {{ host.ipv4 || "—" }}
      </p>
      <p>
        <strong>Heartbeat:</strong> {{ host.last_heartbeat_at ? formatDt(host.last_heartbeat_at) : "—" }}
        · <strong>Last seen:</strong> {{ formatDt(host.last_seen_at) }}
        · <strong>Инвентаризация:</strong>
        {{ host.last_inventory_at ? formatDt(host.last_inventory_at) : "—" }}
        · <strong>Событий:</strong> {{ host.event_count ?? 0 }}
      </p>
    </div>

    <section v-if="inventory" class="host-inventory card">
      <h2>Железо и ПО</h2>
      <div v-if="windowsInfo" class="inv-block">
        <h3>Windows</h3>
        <p>{{ windowsInfo }}</p>
      </div>
      <div v-if="computerName" class="inv-block">
        <p><strong>Имя компьютера:</strong> {{ computerName }}</p>
      </div>
      <div v-if="processors.length" class="inv-block">
        <h3>Процессор</h3>
        <ul>
          <li v-for="(p, i) in processors" :key="'cpu-' + i">
            {{ p.name }}
            <span v-if="p.cores != null"> — {{ p.cores }} ядер / {{ p.logical_processors }} потоков</span>
          </li>
        </ul>
      </div>
      <div v-if="motherboard" class="inv-block">
        <h3>Материнская плата</h3>
        <p>{{ motherboard }}</p>
      </div>
      <div v-if="memoryGb != null" class="inv-block">
        <h3>Память</h3>
        <p>{{ memoryGb }} GB</p>
      </div>
      <div v-if="disks.length" class="inv-block">
        <h3>Диски</h3>
        <table class="dash-table">
          <thead>
            <tr>
              <th>Имя</th>
              <th>Тип</th>
              <th>Размер, GB</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(d, i) in disks" :key="'disk-' + i">
              <td>{{ d.friendly_name || "—" }}</td>
              <td>{{ d.media_type || "—" }}</td>
              <td>{{ d.size_gb ?? "—" }}</td>
            </tr>
          </tbody>
        </table>
      </div>
      <div v-if="video.length" class="inv-block">
        <h3>Видео</h3>
        <ul>
          <li v-for="(v, i) in video" :key="'gpu-' + i">{{ v.name }}</li>
        </ul>
      </div>
      <div v-if="ipv4List.length" class="inv-block">
        <h3>IPv4</h3>
        <p>{{ ipv4List.join(", ") }}</p>
      </div>
    </section>
    <p v-else class="muted">Инвентаризация ещё не поступала с агента (agent.inventory).</p>

    <h2>События хоста</h2>
    <p v-if="eventsLoading">Загрузка событий…</p>
    <p v-else-if="eventsError" class="error">{{ eventsError }}</p>
    <template v-else>
      <p>Всего: {{ events?.total ?? 0 }}</p>
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>Время</th>
            <th>Severity</th>
            <th>Type</th>
            <th>Title</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="e in events?.items ?? []" :key="e.id">
            <td>
              <RouterLink :to="{ path: `/events/${e.id}`, query: eventsBackQuery }">{{ e.id }}</RouterLink>
            </td>
            <td>{{ formatDt(e.occurred_at) }}</td>
            <td :class="'sev-' + e.severity">{{ e.severity }}</td>
            <td><code>{{ e.type }}</code></td>
            <td>{{ e.title }}</td>
          </tr>
        </tbody>
      </table>
      <div class="filters" style="margin-top: 1rem">
        <button type="button" class="secondary" :disabled="eventsPage <= 1" @click="loadEvents(eventsPage - 1)">
          Назад
        </button>
        <span>Стр. {{ eventsPage }}</span>
        <button
          type="button"
          class="secondary"
          :disabled="!events || eventsPage * eventsPageSize >= events.total"
          @click="loadEvents(eventsPage + 1)"
        >
          Вперёд
        </button>
      </div>
    </template>
  </template>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
import { apiFetch, type EventListResponse, type HostDetail } from "../api";

const props = defineProps<{ id: string }>();
const route = useRoute();

const host = ref<HostDetail | null>(null);
const events = ref<EventListResponse | null>(null);
const loading = ref(false);
const eventsLoading = ref(false);
const error = ref("");
const eventsError = ref("");
const eventsPage = ref(1);
const eventsPageSize = 50;

const hostId = computed(() => parseInt(props.id, 10));

const inventory = computed(() => host.value?.inventory ?? null);

const windowsInfo = computed(() => {
  const w = inventory.value?.windows as Record<string, string> | undefined;
  if (!w) return "";
  const parts = [w.product_name, w.version, w.os_hardware_abstraction_layer].filter(Boolean);
  return parts.join(" · ");
});

const computerName = computed(() => {
  const v = inventory.value?.computer_name;
  return typeof v === "string" && v.trim() ? v : "";
});

const processors = computed(() => {
  const raw = inventory.value?.processor;
  if (!Array.isArray(raw)) return [];
  return raw.filter((p): p is Record<string, unknown> => p != null && typeof p === "object");
});

const motherboard = computed(() => {
  const m = inventory.value?.motherboard as Record<string, string> | undefined;
  if (!m) return "";
  return [m.manufacturer, m.product].filter(Boolean).join(" ");
});

const memoryGb = computed(() => {
  const v = inventory.value?.memory_gb;
  return typeof v === "number" ? v : null;
});

const disks = computed(() => {
  const raw = inventory.value?.disks;
  if (!Array.isArray(raw)) return [];
  return raw.filter((d): d is Record<string, unknown> => d != null && typeof d === "object");
});

const video = computed(() => {
  const raw = inventory.value?.video;
  if (!Array.isArray(raw)) return [];
  return raw.filter((v): v is Record<string, string> => v != null && typeof v === "object");
});

const ipv4List = computed(() => {
  const raw = inventory.value?.ipv4;
  if (!Array.isArray(raw)) return [];
  return raw.map(String).filter(Boolean);
});

const eventsBackQuery = computed(() => ({ host_id: String(hostId.value) }));

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

function agentLabel(status: string) {
  if (status === "online") return "online";
  if (status === "stale") return "stale";
  return "unknown";
}

async function loadHost() {
  loading.value = true;
  error.value = "";
  try {
    host.value = await apiFetch<HostDetail>(`/api/v1/hosts/${hostId.value}`);
  } catch (e) {
    error.value = e instanceof Error ? e.message : "Ошибка загрузки хоста";
  } finally {
    loading.value = false;
  }
}

async function loadEvents(page = 1) {
  eventsLoading.value = true;
  eventsError.value = "";
  eventsPage.value = page;
  try {
    const params = new URLSearchParams({
      page: String(page),
      page_size: String(eventsPageSize),
      host_id: String(hostId.value),
    });
    events.value = await apiFetch<EventListResponse>(`/api/v1/events?${params}`);
  } catch (e) {
    eventsError.value = e instanceof Error ? e.message : "Ошибка загрузки событий";
  } finally {
    eventsLoading.value = false;
  }
}

onMounted(async () => {
  await loadHost();
  await loadEvents(1);
});

watch(
  () => route.params.id,
  async () => {
    await loadHost();
    await loadEvents(1);
  },
);
</script>

<style scoped>
.host-inventory {
  margin: 1rem 0 1.5rem;
}

.inv-block {
  margin-bottom: 1rem;
}

.inv-block h3 {
  margin: 0 0 0.35rem;
  font-size: 1rem;
}

.muted {
  color: #9aa4b2;
}
</style>
