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

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

defineProps<{
  twoFactor: TwoFactorState
}>()

const { flash } = useAuth()
const enableForm = useForm({ password: '' })
const confirmForm = useForm({ code: '' })
const logoutForm = useForm({})
const recoveryCodes = computed(() => flash.value.recoveryCodes ?? [])
const manualKeyCopied = ref(false)

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

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

function logout() {
  logoutForm.post('/logout')
}

async function copyManualKey(secretKey: string | null) {
  if (!secretKey)
    return

  await navigator.clipboard.writeText(secretKey)
  manualKeyCopied.value = true

  window.setTimeout(() => {
    manualKeyCopied.value = false
  }, 2000)
}
</script>

<template>
  <AuthLayout>
    <div class="space-y-6">
      <div class="space-y-2 text-center">
        <span class="mx-auto flex size-12 items-center justify-center rounded-full bg-primary/10">
          <UIcon
            :name="twoFactor.enabled ? 'i-lucide-shield-check' : 'i-lucide-shield-keyhole'"
            class="size-6 text-primary"
          />
        </span>
        <h1 class="text-xl font-semibold">
          {{ twoFactor.enabled ? 'Setup complete' : 'Secure your account' }}
        </h1>
        <p class="text-muted text-sm">
          {{ twoFactor.enabled
            ? 'Two-factor authentication is ready. Save your recovery codes before continuing.'
            : 'Two-factor authentication is required before you can continue.' }}
        </p>
      </div>

      <UAlert
        v-if="flash.error"
        color="error"
        icon="i-lucide-alert-circle"
        :title="flash.error"
      />

      <div v-if="twoFactor.enabled" class="space-y-5">
        <UAlert
          color="success"
          variant="subtle"
          icon="i-lucide-check-circle"
          title="Your authenticator has been verified."
        />

        <div>
          <p class="mb-3 text-sm font-medium">
            Recovery codes
          </p>
          <RecoveryCodesPanel :codes="recoveryCodes" />
          <p class="mt-3 text-xs text-muted">
            Store these somewhere safe. Each recovery code can only be used once.
          </p>
        </div>

        <UButton to="/two-factor-setup/complete" block trailing-icon="i-lucide-arrow-right">
          Continue
        </UButton>
      </div>

      <form
        v-else-if="!twoFactor.pending"
        class="space-y-4"
        @submit.prevent="enable"
      >
        <p class="text-sm text-muted">
          Start by confirming your identity. You will then connect an authenticator app.
        </p>

        <UFormField
          v-if="twoFactor.requiresPassword"
          label="Current password"
          name="password"
          :error="enableForm.errors.password"
        >
          <UInput
            v-model="enableForm.password"
            type="password"
            autocomplete="current-password"
            autofocus
            class="w-full"
          />
        </UFormField>

        <UAlert
          v-else
          color="info"
          variant="subtle"
          icon="i-lucide-info"
          title="Your social login has confirmed your identity."
        />

        <UButton type="submit" block :loading="enableForm.processing">
          Set up authenticator
        </UButton>
      </form>

      <div v-else class="space-y-5">
        <div class="space-y-3 text-center">
          <img
            v-if="twoFactor.qrCodeDataUri"
            :src="twoFactor.qrCodeDataUri"
            alt="Two-factor authenticator QR code"
            class="mx-auto size-48 rounded-lg border bg-white p-2"
          >
          <div>
            <h2 class="font-medium">
              Scan the QR code
            </h2>
            <p class="mt-1 text-sm text-muted">
              Use any TOTP-compatible authenticator app.
            </p>
          </div>
        </div>

        <div>
          <p class="mb-1 text-xs text-muted">
            Manual setup key
          </p>
          <div class="flex items-center gap-2 rounded-lg bg-elevated p-2">
            <code class="min-w-0 flex-1 break-all px-1 text-sm">
              {{ twoFactor.secretKey }}
            </code>
            <UButton
              type="button"
              variant="ghost"
              size="sm"
              :icon="manualKeyCopied ? 'i-lucide-check' : 'i-lucide-copy'"
              :color="manualKeyCopied ? 'success' : 'neutral'"
              :aria-label="manualKeyCopied ? 'Manual setup key copied' : 'Copy manual setup key'"
              @click="copyManualKey(twoFactor.secretKey)"
            >
              {{ manualKeyCopied ? 'Copied' : 'Copy' }}
            </UButton>
          </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"
              autofocus
              class="w-full"
              :ui="{ base: 'text-center tracking-[0.35em]' }"
            />
          </UFormField>
          <UButton type="submit" block :loading="confirmForm.processing">
            Verify authenticator
          </UButton>
        </form>
      </div>

      <div v-if="!twoFactor.enabled" class="border-t pt-4">
        <UButton
          type="button"
          color="neutral"
          variant="outline"
          icon="i-lucide-log-out"
          block
          :loading="logoutForm.processing"
          @click="logout"
        >
          Sign out and finish later
        </UButton>
      </div>
    </div>
  </AuthLayout>
</template>
