<template>
  <div>
    <div class="flex items-start justify-between mb-8">
      <div>
        <h1 class="text-xl font-semibold text-white mb-1">Domain-Approval</h1>
        <p class="text-sm text-gray-500">
          Ausstehende Blocker-Domain-Anfragen genehmigen oder ablehnen.
          <span class="text-gray-400">Legend-Requests werden priorisiert behandelt — SLA: 24h.</span>
        </p>
      </div>
      <UButton
        color="neutral"
        variant="ghost"
        icon="heroicons:arrow-path"
        :loading="pending"
        size="sm"
        @click="refresh()"
      >
        Aktualisieren
      </UButton>
    </div>

    <!-- Filter-Bar (Plan-Chips) -->
    <div
      v-if="submissions && submissions.length > 0"
      class="flex items-center gap-2 mb-4 flex-wrap"
    >
      <span class="text-xs uppercase tracking-wider text-gray-500 mr-1">
        Filter:
      </span>
      <UButton
        v-for="opt in filterOptions"
        :key="opt.value"
        :color="filter === opt.value ? 'primary' : 'neutral'"
        :variant="filter === opt.value ? 'solid' : 'soft'"
        size="xs"
        @click="filter = opt.value"
      >
        {{ opt.label }}
        <span v-if="opt.count !== undefined" class="ml-1 opacity-70">
          ({{ opt.count }})
        </span>
      </UButton>
      <span class="text-xs text-gray-500 ml-auto">
        {{ filteredSubmissions.length }} / {{ submissions.length }} sichtbar
        <span v-if="overdueCount > 0" class="text-red-400 ml-2">
          {{ overdueCount }} überfällig
        </span>
      </span>
    </div>

    <!-- Error-State -->
    <div
      v-if="error"
      class="rounded-lg border border-red-900 bg-red-950/40 p-4 mb-4 flex items-start gap-3"
    >
      <UIcon
        name="heroicons:exclamation-triangle"
        class="h-5 w-5 text-red-400 shrink-0 mt-0.5"
      />
      <div class="flex-1">
        <p class="text-sm font-medium text-red-300">
          Fehler beim Laden der Anfragen
        </p>
        <p class="text-xs text-red-400/80 mt-1">
          {{ error.statusMessage || error.message || "Unbekannter Fehler" }}
        </p>
      </div>
    </div>

    <!-- Loading-State (initial) -->
    <div
      v-else-if="pending && !submissions"
      class="rounded-lg border border-gray-800 bg-gray-900 p-12 text-center"
    >
      <UIcon
        name="heroicons:arrow-path"
        class="h-6 w-6 text-gray-600 mx-auto mb-3 animate-spin"
      />
      <p class="text-sm text-gray-500">Lade Domain-Anfragen…</p>
    </div>

    <!-- Empty-State -->
    <div
      v-else-if="!filteredSubmissions || filteredSubmissions.length === 0"
      class="rounded-lg border border-dashed border-gray-700 bg-gray-900 p-12 text-center"
    >
      <UIcon
        name="heroicons:inbox"
        class="h-8 w-8 text-gray-600 mx-auto mb-3"
      />
      <p class="text-sm text-gray-500">
        {{
          submissions && submissions.length > 0
            ? "Keine Treffer für aktuellen Filter"
            : "Keine pending requests"
        }}
      </p>
      <p class="text-xs text-gray-600 mt-2">
        Alle Domain-Anfragen sind aktuell bearbeitet.
      </p>
    </div>

    <!-- Card-Liste statt Table — wegen border-left urgency-color besser sichtbar -->
    <div v-else class="space-y-2">
      <div
        v-for="sub in filteredSubmissions"
        :key="sub.id"
        class="rounded-lg border border-gray-800 bg-gray-900 overflow-hidden flex"
        :class="{ 'opacity-90': busyId === sub.id }"
      >
        <!-- Urgency-Stripe (border-left thick) -->
        <div
          class="w-1 shrink-0"
          :class="urgencyStripeClass(sub)"
          :title="urgencyLabel(sub)"
        />

        <div class="flex-1 p-4">
          <!-- Row 1: Domain + Plan-Badge + Status -->
          <div class="flex items-center gap-2 flex-wrap mb-2">
            <span class="font-mono text-white text-sm">{{ sub.domain }}</span>
            <UBadge
              :color="planBadgeColor(sub.user?.plan)"
              variant="subtle"
              size="xs"
              class="uppercase"
            >
              <UIcon
                v-if="sub.user?.plan === 'legend'"
                name="heroicons:sparkles"
                class="h-3 w-3 mr-0.5"
              />
              {{ sub.user?.plan ?? "free" }}
            </UBadge>
            <UBadge
              v-if="sub.status === 'in_review'"
              color="warning"
              variant="subtle"
              size="xs"
            >
              in_review
            </UBadge>
            <UBadge
              v-else-if="sub.status === 'pending'"
              color="neutral"
              variant="subtle"
              size="xs"
            >
              voting
            </UBadge>
          </div>

          <!-- Row 2: User + Zeit-Info -->
          <div class="flex items-center gap-4 text-xs text-gray-400 flex-wrap">
            <span class="inline-flex items-center gap-1">
              <UIcon name="heroicons:user" class="h-3.5 w-3.5" />
              {{ sub.user?.nickname ?? "—" }}
            </span>
            <span class="inline-flex items-center gap-1">
              <UIcon name="heroicons:clock" class="h-3.5 w-3.5" />
              {{ relativeTime(sub.createdAt) }}
            </span>
            <span
              class="inline-flex items-center gap-1 font-medium"
              :class="deadlineTextClass(sub)"
            >
              <UIcon
                :name="
                  isOverdue(sub)
                    ? 'heroicons:exclamation-triangle'
                    : 'heroicons:bell-alert'
                "
                class="h-3.5 w-3.5"
              />
              {{ deadlineLabel(sub) }}
            </span>
            <span class="inline-flex items-center gap-3 ml-auto">
              <span class="inline-flex items-center gap-1 text-green-400">
                <UIcon name="heroicons:hand-thumb-up" class="h-3.5 w-3.5" />
                {{ sub.yesVotes }}
              </span>
              <span class="inline-flex items-center gap-1 text-red-400">
                <UIcon name="heroicons:hand-thumb-down" class="h-3.5 w-3.5" />
                {{ sub.noVotes }}
              </span>
            </span>
          </div>
        </div>

        <!-- Actions -->
        <div class="flex items-center gap-2 px-4 shrink-0">
          <UButton
            color="success"
            variant="soft"
            size="xs"
            icon="heroicons:check"
            :loading="busyId === sub.id && busyAction === 'approve'"
            :disabled="!!busyId"
            @click="onApprove(sub)"
          >
            Approve
          </UButton>
          <UButton
            color="error"
            variant="soft"
            size="xs"
            icon="heroicons:x-mark"
            :loading="busyId === sub.id && busyAction === 'reject'"
            :disabled="!!busyId"
            @click="askReject(sub)"
          >
            Reject
          </UButton>
        </div>
      </div>
    </div>

    <!-- Reject-Confirm-Dialog -->
    <UModal v-model:open="rejectOpen" title="Domain-Anfrage ablehnen">
      <template #body>
        <div class="space-y-4">
          <p class="text-sm text-gray-300">
            Anfrage für
            <span class="font-mono text-white">{{
              rejectTarget?.domain
            }}</span>
            wirklich ablehnen?
          </p>
          <UTextarea
            v-model="rejectNote"
            placeholder="Optionaler Begründungs-Hinweis (intern)…"
            :rows="3"
            class="w-full"
          />
        </div>
      </template>
      <template #footer>
        <div class="flex justify-end gap-2 w-full">
          <UButton
            color="neutral"
            variant="ghost"
            :disabled="!!busyId"
            @click="rejectOpen = false"
          >
            Abbrechen
          </UButton>
          <UButton
            color="error"
            :loading="!!busyId"
            @click="confirmReject"
          >
            Ablehnen
          </UButton>
        </div>
      </template>
    </UModal>
  </div>
</template>

<script setup lang="ts">
definePageMeta({ middleware: "admin-auth" });

interface DomainSubmission {
  id: string;
  domain: string;
  yesVotes: number;
  noVotes: number;
  status: "pending" | "in_review" | "approved" | "rejected";
  createdAt: string;
  userId: string;
  postId: string | null;
  customDomain: { id: string } | null;
  user: { id: string; nickname: string | null; plan: string } | null;
  planPriority: number;
  deadlineAt: string;
  msUntilDeadline: number;
}

const toast = useToast();

const {
  data: submissions,
  pending,
  error,
  refresh,
} = await useFetch<DomainSubmission[]>("/api/domain-submissions", {
  default: () => [],
  server: false, // Auth-Guard erst client-side -> SSR-Fetch wuerde unauthenticated landen
});

// ─── Filter ──────────────────────────────────────────────────────────────────

type FilterValue = "all" | "legend" | "overdue";
const filter = ref<FilterValue>("all");

const filterOptions = computed(() => {
  const all = submissions.value ?? [];
  const legend = all.filter((s) => s.user?.plan === "legend");
  const overdue = all.filter((s) => isOverdue(s));
  return [
    { label: "Alle", value: "all" as const, count: all.length },
    {
      label: "Nur Legend",
      value: "legend" as const,
      count: legend.length,
    },
    {
      label: "Überfällig",
      value: "overdue" as const,
      count: overdue.length,
    },
  ];
});

const filteredSubmissions = computed(() => {
  const all = submissions.value ?? [];
  if (filter.value === "legend") {
    return all.filter((s) => s.user?.plan === "legend");
  }
  if (filter.value === "overdue") {
    return all.filter((s) => isOverdue(s));
  }
  return all;
});

const overdueCount = computed(
  () => (submissions.value ?? []).filter((s) => isOverdue(s)).length,
);

// ─── Helpers ──────────────────────────────────────────────────────────────────

function planBadgeColor(
  plan: string | null | undefined,
): "primary" | "success" | "warning" | "neutral" {
  if (plan === "legend") return "warning";
  if (plan === "pro") return "primary";
  return "neutral";
}

function relativeTime(iso: string): string {
  if (!iso) return "—";
  const diffMs = Date.now() - new Date(iso).getTime();
  const m = Math.floor(diffMs / 60000);
  if (m < 1) return "gerade eben";
  if (m < 60) return `vor ${m}min`;
  const h = Math.floor(m / 60);
  if (h < 24) return `vor ${h}h`;
  const d = Math.floor(h / 24);
  return `vor ${d}d`;
}

function isOverdue(sub: DomainSubmission): boolean {
  return sub.msUntilDeadline <= 0;
}

function deadlineLabel(sub: DomainSubmission): string {
  if (isOverdue(sub)) {
    const overdueMs = -sub.msUntilDeadline;
    const overdueH = Math.floor(overdueMs / 3_600_000);
    if (overdueH < 1) return "ÜBERFÄLLIG";
    return `ÜBERFÄLLIG (${overdueH}h)`;
  }
  const ms = sub.msUntilDeadline;
  const totalMin = Math.floor(ms / 60000);
  const h = Math.floor(totalMin / 60);
  const m = totalMin % 60;
  if (h === 0) return `noch ${m}min`;
  return `noch ${h}h ${m}min`;
}

function urgencyLevel(sub: DomainSubmission): "overdue" | "critical" | "soon" | "normal" | "legend" {
  if (isOverdue(sub)) return "overdue";
  // Legend bekommt eigene gold-stripe — vor Zeit-basierter Urgency
  if (sub.user?.plan === "legend") return "legend";
  if (sub.msUntilDeadline < 2 * 3_600_000) return "critical";
  if (sub.msUntilDeadline < 12 * 3_600_000) return "soon";
  return "normal";
}

function urgencyStripeClass(sub: DomainSubmission): string {
  switch (urgencyLevel(sub)) {
    case "overdue":
      return "bg-red-600";
    case "critical":
      return "bg-red-500";
    case "legend":
      return "bg-amber-400";
    case "soon":
      return "bg-yellow-500";
    default:
      return "bg-gray-700";
  }
}

function urgencyLabel(sub: DomainSubmission): string {
  switch (urgencyLevel(sub)) {
    case "overdue":
      return "SLA überschritten";
    case "critical":
      return "<2h bis Deadline";
    case "legend":
      return "Legend-Priorität";
    case "soon":
      return "<12h bis Deadline";
    default:
      return "Im Zeitrahmen";
  }
}

function deadlineTextClass(sub: DomainSubmission): string {
  if (isOverdue(sub)) return "text-red-400";
  if (sub.msUntilDeadline < 2 * 3_600_000) return "text-red-400";
  if (sub.msUntilDeadline < 12 * 3_600_000) return "text-yellow-400";
  return "text-gray-400";
}

// ─── Approve / Reject ─────────────────────────────────────────────────────────

const busyId = ref<string | null>(null);
const busyAction = ref<"approve" | "reject" | null>(null);

const rejectOpen = ref(false);
const rejectTarget = ref<DomainSubmission | null>(null);
const rejectNote = ref("");

async function onApprove(row: DomainSubmission) {
  if (busyId.value) return;
  busyId.value = row.id;
  busyAction.value = "approve";
  try {
    await $fetch(`/api/domain-submissions/${row.id}/approve`, {
      method: "POST",
      body: {},
    });
    toast.add({
      title: "Domain genehmigt",
      description: row.domain,
      color: "success",
      icon: "heroicons:check-circle",
    });
    await refresh();
  } catch (err: any) {
    toast.add({
      title: "Approve fehlgeschlagen",
      description:
        err?.statusMessage ?? err?.message ?? "Unbekannter Fehler",
      color: "error",
      icon: "heroicons:exclamation-triangle",
    });
  } finally {
    busyId.value = null;
    busyAction.value = null;
  }
}

function askReject(row: DomainSubmission) {
  if (busyId.value) return;
  rejectTarget.value = row;
  rejectNote.value = "";
  rejectOpen.value = true;
}

async function confirmReject() {
  const target = rejectTarget.value;
  if (!target || busyId.value) return;
  busyId.value = target.id;
  busyAction.value = "reject";
  try {
    await $fetch(`/api/domain-submissions/${target.id}/reject`, {
      method: "POST",
      body: { note: rejectNote.value || undefined },
    });
    toast.add({
      title: "Domain abgelehnt",
      description: target.domain,
      color: "warning",
      icon: "heroicons:x-circle",
    });
    rejectOpen.value = false;
    rejectTarget.value = null;
    rejectNote.value = "";
    await refresh();
  } catch (err: any) {
    toast.add({
      title: "Reject fehlgeschlagen",
      description:
        err?.statusMessage ?? err?.message ?? "Unbekannter Fehler",
      color: "error",
      icon: "heroicons:exclamation-triangle",
    });
  } finally {
    busyId.value = null;
    busyAction.value = null;
  }
}
</script>
