<script setup lang="ts">
import { useForm } from '@inertiajs/vue3'
import { computed } from 'vue'
import RecoveryCodesPanel from '@/components/auth/RecoveryCodesPanel.vue'
import { useAuth } from '@/composables/useAuth'
import DashboardLayout from '@/layouts/DashboardLayout.vue'

interface TwoFactorState {
  available: boolean
  enabled: boolean
  pending: boolean
  requiresPassword: boolean
  qrCodeDataUri: string | null
  secretKey: string | null
}

defineOptions({
  layout: DashboardLayout,
})

defineProps<{
  twoFactor: TwoFactorState
}>()

const { config, flash, user } = useAuth()

const enableForm = useForm({ password: '' })
const confirmForm = useForm({ code: '' })
const disableForm = useForm({ password: '', code: '' })
const recoveryForm = useForm({ password: '', code: '', regenerate: false })

const recoveryCodes = computed(() => flash.value.recoveryCodes ?? [])
const twoFactorRequired = computed(() =>
  config.value.features.two_factor && config.value.features.two_factor_required,
)

function enable() {
  enableForm.post('/profile/two-factor', {
    preserveScroll: true,
    onFinish: () => enableForm.reset(),
  })
}

function confirm() {
  confirmForm.post('/profile/two-factor/confirm', {
    preserveScroll: true,
    onFinish: () => confirmForm.reset(),
  })
}

function disable() {
  disableForm.delete('/profile/two-factor', {
    preserveScroll: true,
    onFinish: () => disableForm.reset(),
  })
}

function recoveryCodesAction(regenerate: boolean) {
  recoveryForm.regenerate = regenerate
  recoveryForm.post('/profile/two-factor/recovery-codes', {
    preserveScroll: true,
    onFinish: () => recoveryForm.reset(),
  })
}
</script>

<template>
  <UDashboardPanel>
    <template #header>
      <UDashboardNavbar title="Profile" />
    </template>

    <template #body>
      <div class="mx-auto w-full max-w-3xl space-y-6">
        <UAlert
          v-if="flash.success"
          color="success"
          icon="i-lucide-check-circle"
          :title="flash.success"
        />
        <UAlert
          v-if="twoFactorRequired && !twoFactor.enabled"
          color="warning"
          icon="i-lucide-shield-alert"
          title="Two-factor authentication is required"
          description="Finish setup before accessing the rest of the application."
        />

        <UCard>
          <div class="flex flex-col gap-5 sm:flex-row sm:items-center">
            <UAvatar :alt="user?.full_name" size="3xl" />
            <div class="min-w-0 flex-1">
              <h1 class="truncate text-xl font-semibold">
                {{ user?.full_name }}
              </h1>
              <p class="text-muted truncate text-sm">
                @{{ user?.username }}
              </p>
              <div class="mt-3 flex flex-wrap items-center gap-2">
                <UBadge color="neutral" variant="subtle" icon="i-lucide-mail">
                  {{ user?.email }}
                </UBadge>
                <UBadge
                  :color="user?.email_verified_at ? 'success' : 'warning'"
                  variant="subtle"
                  :icon="user?.email_verified_at ? 'i-lucide-badge-check' : 'i-lucide-circle-alert'"
                >
                  {{ user?.email_verified_at ? 'Email verified' : 'Email not verified' }}
                </UBadge>
              </div>
            </div>
          </div>
        </UCard>

        <UCard>
          <template #header>
            <div class="flex items-center justify-between gap-4">
              <div>
                <h2 class="font-semibold">
                  Two-factor authentication
                </h2>
                <p class="text-muted mt-1 text-sm">
                  Protect your account with a time-based code from an authenticator app.
                </p>
              </div>
              <UBadge :color="twoFactor.enabled ? 'success' : twoFactor.pending ? 'warning' : 'neutral'">
                {{ twoFactor.enabled ? 'Enabled' : twoFactor.pending ? 'Setup pending' : 'Disabled' }}
              </UBadge>
            </div>
          </template>

          <UAlert
            v-if="!twoFactor.available"
            color="neutral"
            icon="i-lucide-shield-off"
            title="Two-factor authentication is not available"
            description="An administrator can enable this feature through the authentication configuration."
          />

          <form v-else-if="!twoFactor.enabled && !twoFactor.pending" class="space-y-4" @submit.prevent="enable">
            <UAlert
              v-if="!twoFactor.requiresPassword"
              color="info"
              icon="i-lucide-info"
              title="Your social login session will authorize enrollment."
            />
            <UFormField
              v-if="twoFactor.requiresPassword"
              label="Current password"
              name="password"
              :error="enableForm.errors.password"
            >
              <UInput
                v-model="enableForm.password"
                type="password"
                autocomplete="current-password"
                class="w-full"
              />
            </UFormField>
            <UButton type="submit" :loading="enableForm.processing">
              Enable two-factor authentication
            </UButton>
          </form>

          <div v-else-if="twoFactor.pending" class="space-y-6">
            <div class="grid gap-6 md:grid-cols-[auto_1fr]">
              <img
                v-if="twoFactor.qrCodeDataUri"
                :src="twoFactor.qrCodeDataUri"
                alt="Two-factor authenticator QR code"
                class="size-48 rounded-lg border bg-white p-2"
              >
              <div class="space-y-3">
                <h3 class="font-medium">
                  Scan this QR code
                </h3>
                <p class="text-muted text-sm">
                  Scan it with any TOTP-compatible authenticator app, then enter the generated code below.
                </p>
                <div>
                  <p class="text-muted mb-1 text-xs">
                    Manual setup key
                  </p>
                  <code class="block break-all rounded bg-elevated p-2 text-sm">{{ twoFactor.secretKey }}</code>
                </div>
              </div>
            </div>

            <form class="space-y-4" @submit.prevent="confirm">
              <UFormField
                label="Six-digit authentication code"
                name="code"
                :error="confirmForm.errors.code"
              >
                <UInput
                  v-model="confirmForm.code"
                  inputmode="numeric"
                  autocomplete="one-time-code"
                  maxlength="6"
                  placeholder="123456"
                  class="w-full"
                />
              </UFormField>
              <div class="flex flex-wrap gap-3">
                <UButton type="submit" :loading="confirmForm.processing">
                  Confirm setup
                </UButton>
                <UButton
                  type="button"
                  color="neutral"
                  variant="outline"
                  :loading="disableForm.processing"
                  @click="disable"
                >
                  Cancel setup
                </UButton>
              </div>
            </form>
          </div>

          <div v-else class="space-y-6">
            <UAlert
              color="success"
              variant="subtle"
              icon="i-lucide-shield-check"
              title="Your account requires a second factor when signing in."
            />

            <div class="space-y-4 border-t pt-6">
              <div>
                <h3 class="font-medium">
                  Recovery codes
                </h3>
                <p class="text-muted text-sm">
                  Re-authenticate to reveal your codes or replace them with a new set.
                </p>
              </div>
              <UFormField
                v-if="twoFactor.requiresPassword"
                label="Current password"
                name="password"
                :error="recoveryForm.errors.password"
              >
                <UInput
                  v-model="recoveryForm.password"
                  type="password"
                  autocomplete="current-password"
                  class="w-full"
                />
              </UFormField>
              <UFormField
                label="Authentication or recovery code"
                name="code"
                :error="recoveryForm.errors.code"
              >
                <UInput
                  v-model="recoveryForm.code"
                  autocomplete="one-time-code"
                  class="w-full"
                />
              </UFormField>
              <div class="flex flex-wrap gap-3">
                <UButton
                  variant="outline"
                  :loading="recoveryForm.processing && !recoveryForm.regenerate"
                  @click="recoveryCodesAction(false)"
                >
                  Reveal recovery codes
                </UButton>
                <UButton
                  color="warning"
                  variant="outline"
                  :loading="recoveryForm.processing && recoveryForm.regenerate"
                  @click="recoveryCodesAction(true)"
                >
                  Generate new codes
                </UButton>
              </div>
            </div>

            <UAlert
              v-if="twoFactorRequired"
              color="neutral"
              variant="subtle"
              icon="i-lucide-lock-keyhole"
              title="Two-factor authentication is required by your administrator."
              description="It cannot be disabled while the mandatory security policy is active."
            />

            <form v-else class="space-y-4 border-t pt-6" @submit.prevent="disable">
              <div>
                <h3 class="font-medium text-error">
                  Disable two-factor authentication
                </h3>
                <p class="text-muted text-sm">
                  This removes the additional protection from your account.
                </p>
              </div>
              <UFormField
                v-if="twoFactor.requiresPassword"
                label="Current password"
                name="password"
                :error="disableForm.errors.password"
              >
                <UInput
                  v-model="disableForm.password"
                  type="password"
                  autocomplete="current-password"
                  class="w-full"
                />
              </UFormField>
              <UFormField
                label="Authentication or recovery code"
                name="code"
                :error="disableForm.errors.code"
              >
                <UInput
                  v-model="disableForm.code"
                  autocomplete="one-time-code"
                  class="w-full"
                />
              </UFormField>
              <UButton type="submit" color="error" :loading="disableForm.processing">
                Disable two-factor authentication
              </UButton>
            </form>
          </div>
        </UCard>

        <UCard v-if="recoveryCodes.length">
          <template #header>
            <div>
              <h2 class="font-semibold">
                Save your recovery codes
              </h2>
              <p class="text-muted mt-1 text-sm">
                Store these codes somewhere safe. Each code can be used once.
              </p>
            </div>
          </template>
          <RecoveryCodesPanel :codes="recoveryCodes" />
        </UCard>
      </div>
    </template>
  </UDashboardPanel>
</template>
