<script setup>
import BaseAlert from "../../components/base/BaseAlert.vue";
import BaseButton from "../../components/base/BaseButton.vue";
import BaseTag from "../../components/base/BaseTag.vue";
import { useBaseToast } from "../../composables/useBaseToast.js";
import { computed, onMounted, ref } from "vue";

import { api, ensureCsrf } from "../../services/api.js";

const toast = useBaseToast();

const loading = ref(false);
const error = ref("");
const report = ref(null);

function severityFor(status) {
  if (status === "ok") return "success";
  if (status === "warn") return "warn";
  return "danger";
}

function statusLabel(status) {
  if (status === "ok") return "OK";
  if (status === "warn") return "Aandacht";
  return "Geblokkeerd";
}

function overallSeverity(overall) {
  return severityFor(overall ?? "warn");
}

function overallLabel(overall) {
  if (overall === "ok") return "Alle basiscontroles geslaagd.";
  if (overall === "warn") return "Er is iets om te controleren.";
  return "Blokkerende problemen — zie onderstaande CLI-stappen.";
}

const overall = computed(() => {
  const r = report.value;
  if (!r) return null;
  return r.overall_core ?? r.overall ?? null;
});
const checkedAt = computed(() => report.value?.checked_at ?? "");
const coreGroup = computed(() => {
  const groups = report.value?.groups;
  if (!Array.isArray(groups)) return null;
  return groups.find((g) => g.id === "core") ?? null;
});
const versions = computed(() => report.value?.maestro_core_versions ?? {});

async function load() {
  loading.value = true;
  error.value = "";
  try {
    await ensureCsrf();
    const { data } = await api.get("/api/superadmin/installation-health");
    report.value = data?.data ?? null;
  } catch (e) {
    error.value =
      e?.response?.data?.message ??
      "Installatiecontrole kon niet geladen worden (geen toestemming of serverfout).";
    report.value = null;
  } finally {
    loading.value = false;
  }
}

async function copyText(text, kind) {
  try {
    await navigator.clipboard.writeText(text);
    toast.add({
      severity: "success",
      summary: "Gekopieerd",
      detail: `${kind} is naar het klembord gekopieerd.`,
      life: 2500,
    });
  } catch {
    toast.add({
      severity: "error",
      summary: "Kopiëren mislukt",
      detail: "Klembord is in deze context niet beschikbaar.",
      life: 4500,
    });
  }
}

onMounted(load);
</script>

<template>
  <div>
    <h1 class="title-h5 mb-2">Installatiecontrole</h1>
    <p class="body-small text-surface-600 dark:text-surface-400 mb-4">
      Basiscontrole van deze omgeving: database, Maestro-registratie en cache.
      Migraties en seeden gebeuren via
      <code class="text-xs px-1 rounded bg-surface-100 dark:bg-surface-800"
        >php artisan</code
      >
      op de server — niet vanuit de browser.
    </p>

    <div
      v-if="report && !loading"
      class="mb-6 rounded-lg border border-surface-200 dark:border-surface-700 bg-surface-50 dark:bg-surface-950/50 px-4 py-3"
    >
      <p class="text-xs font-medium text-surface-500 uppercase tracking-wide mb-2">
        Huidige @maestro/core-versie
      </p>
      <ul class="text-sm text-surface-800 dark:text-surface-200 space-y-1">
        <li>
          <span class="text-surface-500">Composer (maestro/core):</span>
          {{ versions.composer_package ?? "—" }}
        </li>
        <li>
          <span class="text-surface-500">npm (@maestro/core):</span>
          {{ versions.npm_package ?? "—" }}
        </li>
      </ul>
      <p class="text-xs text-surface-500 mt-2">
        Een streepje betekent dat het pad op deze machine niet bestaat (npm ontbreekt vaak op productieservers).
      </p>
    </div>

    <BaseAlert v-if="error" severity="error" class="mb-4" :closable="false">
      {{ error }}
    </BaseAlert>

    <div class="flex flex-wrap items-start justify-between gap-3 mb-6">
      <div
        v-if="overall"
        class="flex flex-wrap items-center gap-3 rounded-lg border px-4 py-3"
        :class="{
          'border-green-300 bg-green-50 dark:border-green-800 dark:bg-green-950/40':
            overall === 'ok',
          'border-amber-300 bg-amber-50 dark:border-amber-900/40 dark:bg-amber-950/30':
            overall === 'warn',
          'border-red-300 bg-red-50 dark:border-red-900/40 dark:bg-red-950/30':
            overall === 'fail',
        }"
      >
        <span
          class="inline-flex h-3 w-3 shrink-0 rounded-full"
          :class="{
            'bg-green-500': overall === 'ok',
            'bg-amber-500': overall === 'warn',
            'bg-red-500': overall === 'fail',
          }"
          aria-hidden="true"
        />
        <BaseTag :severity="overallSeverity(overall)" :value="statusLabel(overall)" />
        <span class="body-small text-surface-700 dark:text-surface-200">
          {{ overallLabel(overall) }}
        </span>
      </div>
      <BaseButton
        label="Vernieuwen"
        icon="refresh"
        variant="secondary"
        outlined
        :loading="loading"
        @click="load"
      />
    </div>

    <p v-if="checkedAt && !loading" class="text-xs text-surface-500 mb-6">
      Laatst gecontroleerd: {{ checkedAt }}
    </p>

    <div v-if="coreGroup" class="flex flex-col gap-6">
      <section
        class="rounded-xl border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-900 overflow-hidden"
      >
        <div
          class="px-4 py-3 border-b border-surface-200 dark:border-surface-700 bg-surface-50 dark:bg-surface-950/60"
        >
          <h2 class="font-semibold text-surface-800 dark:text-surface-100">
            {{ coreGroup.title }}
          </h2>
        </div>
        <ul class="divide-y divide-surface-200 dark:divide-surface-700">
          <li
            v-for="step in coreGroup.steps"
            :key="step.id"
            class="px-4 py-4 flex flex-col gap-2 sm:flex-row sm:gap-6 sm:items-start"
          >
            <span
              class="mt-1 inline-flex h-2.5 w-2.5 shrink-0 rounded-full sm:mt-1.5"
              :class="{
                'bg-green-500': step.status === 'ok',
                'bg-amber-500': step.status === 'warn',
                'bg-red-500': step.status === 'fail',
              }"
              :title="statusLabel(step.status)"
            />
            <div class="min-w-0 flex-1">
              <div class="flex flex-wrap items-center gap-2 mb-1">
                <span class="font-medium text-surface-800 dark:text-surface-100">
                  {{ step.label }}
                </span>
                <BaseTag
                  :severity="severityFor(step.status)"
                  :value="statusLabel(step.status)"
                  class="text-xs"
                />
              </div>
              <p class="body-small text-surface-600 dark:text-surface-400">
                {{ step.detail }}
              </p>
              <div v-if="step.fix_commands?.length" class="mt-3 flex flex-wrap gap-x-4 gap-y-2">
                <div
                  v-for="cmd in step.fix_commands"
                  :key="`${step.id}-${cmd}`"
                  class="flex items-center gap-1 min-w-0 max-w-full"
                >
                  <code
                    class="text-xs px-2 py-1.5 rounded bg-surface-100 dark:bg-surface-800 break-all flex-1 min-w-0"
                  >
                    {{ cmd }}
                  </code>
                  <BaseButton
                    variant="secondary"
                    icon="copy"
                    text
                    rounded
                    size="small"
                    :icon-only="true"
                    v-tooltip.bottom="'Commando kopiëren'"
                    aria-label="Commando kopiëren"
                    @click="copyText(cmd, 'Commando')"
                  />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </section>
    </div>
  </div>
</template>
