<template>
  <div class="min-h-full py-16 bg-gray-50">
    <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="flex flex-col gap-4 mb-8 sm:flex-row sm:items-start sm:justify-between">
        <div>
          <h1 class="text-4xl font-display font-bold text-gray-900">
            Passwort-Reset-Diagnose
          </h1>
          <div class="w-24 h-1 bg-primary-600 mt-4" />
        </div>
        <NuxtLink
          to="/cms"
          class="self-start px-4 py-2 bg-gray-200 hover:bg-gray-300 text-gray-800 rounded-lg transition-colors"
        >
          Zurück zum CMS
        </NuxtLink>
      </div>

      <section class="bg-white border border-gray-200 rounded-lg shadow-sm p-6 mb-6">
        <form
          class="grid gap-4 lg:grid-cols-[minmax(240px,1fr)_auto_auto]"
          @submit.prevent="loadDiagnostics"
        >
          <label class="block">
            <span class="block text-sm font-medium text-gray-700 mb-2">E-Mail oder Name</span>
            <input
              v-model="searchTerm"
              type="search"
              autocomplete="off"
              placeholder="z.B. user@example.com"
              class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-600 focus:border-primary-600"
            >
          </label>
          <label class="flex items-end gap-2 pb-2 text-sm font-medium text-gray-700">
            <input
              v-model="failedOnly"
              type="checkbox"
              class="h-4 w-4 text-primary-600 border-gray-300 rounded focus:ring-primary-500"
            >
            Nur Auffälligkeiten
          </label>
          <button
            type="submit"
            :disabled="loading"
            class="self-end px-5 py-2 bg-primary-600 hover:bg-primary-700 disabled:opacity-50 text-white rounded-lg transition-colors flex items-center justify-center gap-2"
          >
            <Search :size="17" />
            Prüfen
          </button>
        </form>
        <p class="mt-4 text-sm text-gray-600">
          Diagnoseeinträge werden nach {{ retentionHours }} Stunden automatisch gelöscht. E-Mail-Adressen sind im Log maskiert.
        </p>
      </section>

      <div
        v-if="errorMessage"
        class="bg-red-50 border border-red-200 rounded-lg p-4 mb-6 text-sm text-red-800"
      >
        {{ errorMessage }}
      </div>

      <section
        v-if="searchTerm.trim()"
        class="bg-white border border-gray-200 rounded-lg shadow-sm mb-6 overflow-hidden"
      >
        <header class="px-6 py-4 border-b border-gray-200">
          <h2 class="text-xl font-semibold text-gray-900">
            Passende Benutzerkonten
          </h2>
        </header>
        <div
          v-if="matchingUsers.length === 0"
          class="px-6 py-5 text-sm text-gray-600"
        >
          Kein Login-Benutzer zur Suche gefunden.
        </div>
        <div
          v-else
          class="divide-y divide-gray-200"
        >
          <div
            v-for="user in matchingUsers"
            :key="user.id"
            class="p-5 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"
          >
            <div>
              <p class="font-medium text-gray-900">
                {{ user.name }}
              </p>
              <p class="text-sm text-gray-600">
                {{ user.email }} · {{ user.active ? 'Aktiv' : 'Nicht freigeschaltet' }}
              </p>
            </div>
            <button
              type="button"
              class="px-4 py-2 border border-primary-600 text-primary-700 hover:bg-primary-50 rounded-lg text-sm font-medium transition-colors"
              @click="searchUserLogs(user.email)"
            >
              Logs dieser Adresse
            </button>
          </div>
        </div>
      </section>

      <section class="bg-white border border-gray-200 rounded-lg shadow-sm overflow-hidden">
        <header class="px-6 py-4 border-b border-gray-200 flex items-center justify-between gap-4">
          <div>
            <h2 class="text-xl font-semibold text-gray-900">
              Reset-Vorgänge
            </h2>
            <p class="text-sm text-gray-600 mt-1">
              {{ attempts.length }} Einträge im gewählten Filter
            </p>
          </div>
          <button
            type="button"
            class="p-2 text-gray-600 hover:text-primary-700 disabled:opacity-40"
            :disabled="loading"
            title="Aktualisieren"
            @click="loadDiagnostics"
          >
            <RefreshCw :size="19" :class="{ 'animate-spin': loading }" />
          </button>
        </header>

        <div
          v-if="!loading && attempts.length === 0"
          class="px-6 py-10 text-center text-gray-600"
        >
          Keine Diagnosevorgänge gefunden.
        </div>
        <div
          v-else
          class="divide-y divide-gray-200"
        >
          <article
            v-for="attempt in attempts"
            :key="attempt.requestId"
            class="px-6 py-5"
          >
            <div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
              <div>
                <div class="flex items-center gap-2">
                  <span
                    class="inline-flex px-2 py-1 text-xs font-medium rounded"
                    :class="attempt.failed ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800'"
                  >
                    {{ attempt.failed ? 'Auffällig' : 'Abgeschlossen' }}
                  </span>
                  <span class="text-sm font-medium text-gray-900">{{ attempt.emailMasked || 'Keine Adresse' }}</span>
                </div>
                <p class="text-xs text-gray-500 mt-2">
                  {{ formatDate(attempt.startedAt) }} · IP {{ attempt.ip || '-' }}
                </p>
              </div>
            </div>
            <ol class="mt-4 space-y-2">
              <li
                v-for="step in attempt.steps"
                :key="step.ts + step.step + step.status"
                class="grid gap-1 text-sm sm:grid-cols-[148px_170px_130px_1fr]"
              >
                <time class="text-gray-500">{{ formatTime(step.ts) }}</time>
                <span class="text-gray-800">{{ stepLabel(step.step) }}</span>
                <span :class="stepStatusClass(step.status)">{{ statusLabel(step.status) }}</span>
                <span class="text-gray-600">{{ reasonLabel(step.reason) || errorLabel(step) }}</span>
              </li>
            </ol>
          </article>
        </div>
      </section>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import { RefreshCw, Search } from 'lucide-vue-next'

const searchTerm = ref('')
const failedOnly = ref(true)
const loading = ref(false)
const errorMessage = ref('')
const matchingUsers = ref([])
const attempts = ref([])
const retentionHours = ref(72)

const stepLabels = {
  request_received: 'Anfrage',
  request_validation: 'Validierung',
  rate_limit: 'Rate Limit',
  user_lookup: 'Benutzersuche',
  temporary_password: 'Temporäres Passwort',
  password_storage: 'Passwortspeicherung',
  session_revocation: 'Sitzungen',
  mail_configuration: 'Mail-Konfiguration',
  mail_send: 'Mail-Versand',
  request_completed: 'Abschluss'
}

const statusLabels = {
  started: 'Gestartet',
  checking: 'Prüfung',
  passed: 'OK',
  found: 'Gefunden',
  not_found: 'Nicht gefunden',
  generated: 'Erzeugt',
  completed: 'Erledigt',
  success: 'Erfolgreich',
  no_account: 'Kein Konto',
  failed: 'Fehlgeschlagen'
}

const reasonLabels = {
  email_missing: 'E-Mail-Adresse fehlt',
  smtp_credentials_missing: 'SMTP-Zugangsdaten fehlen',
  write_failed: 'Passwort konnte nicht gespeichert werden'
}

const formatDate = value => new Date(value).toLocaleString('de-DE')
const formatTime = value => new Date(value).toLocaleTimeString('de-DE')
const stepLabel = step => stepLabels[step] || step
const statusLabel = status => statusLabels[status] || status
const reasonLabel = reason => reasonLabels[reason] || reason || ''
const errorLabel = step => [step.errorCode, step.errorMessage].filter(Boolean).join(': ')
const stepStatusClass = status => (
  ['failed', 'not_found', 'no_account'].includes(status)
    ? 'text-red-700 font-medium'
    : 'text-gray-700'
)

const loadDiagnostics = async () => {
  loading.value = true
  errorMessage.value = ''
  try {
    const response = await $fetch('/api/cms/password-reset-diagnostics', {
      query: {
        email: searchTerm.value.trim() || undefined,
        failedOnly: String(failedOnly.value)
      }
    })
    matchingUsers.value = response.matchingUsers || []
    attempts.value = response.attempts || []
    retentionHours.value = response.retentionHours || 72
  } catch (_error) {
    errorMessage.value = 'Reset-Diagnose konnte nicht geladen werden.'
    matchingUsers.value = []
    attempts.value = []
  } finally {
    loading.value = false
  }
}

const searchUserLogs = async email => {
  searchTerm.value = email
  await loadDiagnostics()
}

onMounted(loadDiagnostics)

definePageMeta({
  middleware: 'auth'
})

useHead({
  title: 'Passwort-Reset-Diagnose - CMS - Harheimer TC'
})
</script>
