<script setup>
import Button from "primevue/button";
import Message from "primevue/message";
import Tag from "primevue/tag";
import { useToast } from "primevue/usetoast";
import { computed, onMounted, ref } from "vue";

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

const toast = useToast();

const loading = ref(false);
const activatingSlug = ref("");
const error = ref("");
const checkedAt = ref("");
const coreHealth = ref(null);
const modules = ref([]);
const coreExpanded = ref(false);

async function load() {
  loading.value = true;
  error.value = "";
  try {
    await ensureCsrf();
    const { data } = await api.get("/api/superadmin/modules");
    checkedAt.value = data?.checked_at ?? "";
    coreHealth.value = data?.core_health ?? null;
    modules.value = Array.isArray(data?.modules) ? data.modules : [];
  } catch (e) {
    error.value =
      e?.response?.data?.message ?? "Could not load modules. Forbidden?";
    modules.value = [];
  } finally {
    loading.value = false;
  }
}

async function activate(mod) {
  activatingSlug.value = mod.slug;
  error.value = "";
  try {
    await ensureCsrf();
    await api.post(`/api/superadmin/modules/${mod.slug}/activate`);
    mod.is_enabled = true;
    await hydrateUser();
    toast.add({
      severity: "success",
      summary: "Module activated",
      detail: `${mod.label} is now active.`,
      life: 3000,
    });
    await load();
  } catch (e) {
    const msg =
      e?.response?.data?.message ?? "Could not activate module. Try again.";
    error.value = msg;
    toast.add({ severity: "error", summary: "Activation failed", detail: msg, life: 5000 });
  } finally {
    activatingSlug.value = "";
  }
}

async function copyText(text) {
  try {
    await navigator.clipboard.writeText(text);
    toast.add({ severity: "success", summary: "Copied", detail: "Command copied to clipboard.", life: 2000 });
  } catch {
    toast.add({ severity: "error", summary: "Copy failed", detail: "Clipboard API unavailable.", life: 4000 });
  }
}

function signalClass(status) {
  if (status === "ok") return "bg-green-500";
  if (status === "warn") return "bg-amber-400";
  return "bg-red-500";
}

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

function signalLabel(status) {
  if (status === "ok") return "OK";
  if (status === "warn") return "Warn";
  return "Fail";
}

function overallSeverity(overall) {
  return signalSeverity(overall ?? "fail");
}

function overallLabel(overall) {
  if (overall === "ok") return "All checks passed";
  if (overall === "warn") return "Attention needed";
  return "Blocked";
}

function canActivate(mod) {
  const h = mod.health;
  return (
    !mod.is_enabled &&
    h.config.status !== "fail" &&
    h.database.status !== "fail"
  );
}

const coreOverall = computed(() => coreHealth.value?.overall ?? null);

const SIGNAL_LABELS = {
  config: "Config",
  database: "Database",
  seeder: "Seeder",
  routes: "Routes",
};

onMounted(load);
</script>

<template>
  <div>
    <div class="flex flex-wrap items-start justify-between gap-3 mb-6">
      <div>
        <h1 class="title-h5 mb-1">Modules</h1>
        <p class="body-small text-surface-600 dark:text-surface-400">
          Install modules by running the listed commands, then activate them here.
          Once active, a module cannot be deactivated.
        </p>
      </div>
      <Button
        label="Refresh"
        icon="pi pi-refresh"
        severity="secondary"
        outlined
        :loading="loading"
        @click="load"
      />
    </div>

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

    <!-- Core health collapsible -->
    <div
      class="mb-8 rounded-xl border border-surface-200 dark:border-surface-700 overflow-hidden"
    >
      <button
        class="w-full flex items-center justify-between gap-3 px-4 py-3 bg-surface-50 dark:bg-surface-950/60 text-left hover:bg-surface-100 dark:hover:bg-surface-900 transition-colors"
        @click="coreExpanded = !coreExpanded"
      >
        <div class="flex items-center gap-3">
          <span
            v-if="coreOverall"
            class="inline-flex h-2.5 w-2.5 shrink-0 rounded-full"
            :class="signalClass(coreOverall)"
          />
          <span class="font-semibold text-surface-800 dark:text-surface-100">
            Core installation health
          </span>
          <Tag
            v-if="coreOverall"
            :severity="overallSeverity(coreOverall)"
            :value="overallLabel(coreOverall)"
            class="text-xs"
          />
        </div>
        <i
          class="text-surface-500"
          :class="coreExpanded ? 'pi pi-chevron-up' : 'pi pi-chevron-down'"
        />
      </button>

      <div v-show="coreExpanded">
        <div
          v-for="group in coreHealth?.groups ?? []"
          :key="group.id"
          class="border-t border-surface-200 dark:border-surface-700"
        >
          <div
            class="px-4 py-2 bg-surface-50/50 dark:bg-surface-950/30 text-xs font-medium text-surface-500 uppercase tracking-wide"
          >
            {{ group.title }}
          </div>
          <ul class="divide-y divide-surface-100 dark:divide-surface-800">
            <li
              v-for="step in group.steps"
              :key="step.id"
              class="px-4 py-3 flex gap-4 items-start"
            >
              <span
                class="mt-1.5 inline-flex h-2 w-2 shrink-0 rounded-full"
                :class="signalClass(step.status)"
              />
              <div class="min-w-0 flex-1">
                <div class="flex flex-wrap items-center gap-2 mb-0.5">
                  <span class="text-sm font-medium text-surface-800 dark:text-surface-100">
                    {{ step.label }}
                  </span>
                </div>
                <p class="text-xs text-surface-500 dark:text-surface-400">
                  {{ step.detail }}
                </p>
                <div v-if="step.fix_commands?.length" class="mt-2 flex flex-wrap gap-2">
                  <div
                    v-for="cmd in step.fix_commands"
                    :key="cmd"
                    class="flex items-center gap-1 min-w-0"
                  >
                    <code class="text-xs px-2 py-1 rounded bg-surface-100 dark:bg-surface-800 break-all">
                      {{ cmd }}
                    </code>
                    <Button
                      icon="pi pi-copy"
                      severity="secondary"
                      text
                      rounded
                      size="small"
                      v-tooltip.bottom="'Copy'"
                      @click="copyText(cmd)"
                    />
                  </div>
                </div>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>

    <!-- Module cards -->
    <div
      v-if="!loading && modules.length === 0"
      class="text-center py-12 text-surface-500"
    >
      No modules found. Run migrations and seeders first.
    </div>

    <div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-6">
      <div
        v-for="mod in modules"
        :key="mod.slug"
        class="rounded-xl border overflow-hidden flex flex-col"
        :class="
          mod.is_enabled
            ? 'border-green-300 dark:border-green-800'
            : 'border-surface-200 dark:border-surface-700'
        "
      >
        <!-- Card header -->
        <div
          class="px-4 py-3 flex items-center justify-between gap-3"
          :class="
            mod.is_enabled
              ? 'bg-green-50 dark:bg-green-950/30'
              : 'bg-surface-50 dark:bg-surface-900'
          "
        >
          <div class="flex items-center gap-2">
            <span
              class="inline-flex h-2.5 w-2.5 rounded-full shrink-0"
              :class="signalClass(mod.health.overall)"
            />
            <span class="font-semibold text-surface-800 dark:text-surface-100">
              {{ mod.label }}
            </span>
          </div>
          <Tag
            v-if="mod.is_enabled"
            severity="success"
            value="Active"
            class="text-xs"
          />
          <Tag
            v-else
            :severity="overallSeverity(mod.health.overall)"
            :value="overallLabel(mod.health.overall)"
            class="text-xs"
          />
        </div>

        <!-- Traffic lights grid -->
        <div class="px-4 py-3 grid grid-cols-2 gap-x-6 gap-y-1 border-b border-surface-100 dark:border-surface-800">
          <div
            v-for="(key, _) in SIGNAL_LABELS"
            :key="key"
            class="flex items-center gap-2"
          >
            <span
              class="inline-flex h-2 w-2 rounded-full shrink-0"
              :class="signalClass(mod.health[key]?.status)"
            />
            <span class="text-xs text-surface-600 dark:text-surface-400">
              {{ SIGNAL_LABELS[key] }}
            </span>
          </div>
        </div>

        <!-- Signal details with commands (only for warn/fail) -->
        <div class="flex-1 px-4 py-3 flex flex-col gap-3">
          <div
            v-for="key in Object.keys(SIGNAL_LABELS)"
            :key="`detail-${key}`"
            v-show="mod.health[key]?.status !== 'ok'"
          >
            <div class="flex items-center gap-2 mb-1">
              <span
                class="inline-flex h-1.5 w-1.5 rounded-full shrink-0"
                :class="signalClass(mod.health[key]?.status)"
              />
              <span class="text-xs font-medium text-surface-700 dark:text-surface-300">
                {{ SIGNAL_LABELS[key] }}
              </span>
              <Tag
                :severity="signalSeverity(mod.health[key]?.status)"
                :value="signalLabel(mod.health[key]?.status)"
                class="text-xs"
              />
            </div>
            <p class="text-xs text-surface-500 dark:text-surface-400 ml-3.5 mb-1">
              {{ mod.health[key]?.detail }}
            </p>
            <div
              v-if="mod.health[key]?.commands?.length"
              class="ml-3.5 flex flex-col gap-1"
            >
              <div
                v-for="cmd in mod.health[key].commands"
                :key="cmd"
                class="flex items-center gap-1"
              >
                <code
                  class="text-xs px-2 py-1 rounded bg-surface-100 dark:bg-surface-800 flex-1 break-all"
                >
                  {{ cmd }}
                </code>
                <Button
                  icon="pi pi-copy"
                  severity="secondary"
                  text
                  rounded
                  size="small"
                  v-tooltip.bottom="'Copy'"
                  @click="copyText(cmd)"
                />
              </div>
            </div>
          </div>

          <!-- No issues state -->
          <p
            v-if="mod.health.overall === 'ok' && !mod.is_enabled"
            class="text-xs text-surface-500 dark:text-surface-400"
          >
            All checks passed. Ready to activate.
          </p>
          <p
            v-if="mod.is_enabled"
            class="text-xs text-green-600 dark:text-green-400"
          >
            Module is active and available to users.
          </p>
        </div>

        <!-- Dependencies -->
        <div
          v-if="mod.dependencies.length || mod.dependents.length"
          class="px-4 py-2 border-t border-surface-100 dark:border-surface-800 flex flex-wrap gap-x-4 gap-y-1"
        >
          <span
            v-if="mod.dependencies.length"
            class="text-xs text-surface-500 dark:text-surface-400"
          >
            Requires:
            <span
              v-for="dep in mod.dependencies"
              :key="dep"
              class="font-medium text-surface-700 dark:text-surface-300"
            >
              {{ dep }}
            </span>
          </span>
          <span
            v-if="mod.dependents.length"
            class="text-xs text-surface-400 dark:text-surface-500"
          >
            Depended on by:
            <span
              v-for="dep in mod.dependents"
              :key="dep"
              class="font-medium"
            >
              {{ dep }}
            </span>
          </span>
        </div>

        <!-- Activate button -->
        <div
          v-if="!mod.is_enabled"
          class="px-4 py-3 border-t border-surface-100 dark:border-surface-800 bg-surface-50/50 dark:bg-surface-950/20"
        >
          <Button
            label="Activate module"
            icon="pi pi-check-circle"
            :disabled="!canActivate(mod) || activatingSlug === mod.slug"
            :loading="activatingSlug === mod.slug"
            class="w-full"
            v-tooltip.top="
              !canActivate(mod)
                ? 'Fix config and database issues before activating'
                : null
            "
            @click="activate(mod)"
          />
        </div>
      </div>
    </div>

    <p v-if="checkedAt && !loading" class="text-xs text-surface-400 mt-6">
      Last checked {{ checkedAt }}
    </p>
  </div>
</template>
