<script lang="ts" setup>
import { ref } from 'vue'
import { useForm, usePage, router } from '@inertiajs/vue3'
import AccountLayout from '@/Layouts/AccountLayout.vue'
import type { SharedPageProps } from '@/types'

defineOptions({ layout: AccountLayout })

const page = usePage<SharedPageProps>()
const enabling = ref(false)
const confirming = ref(false)
const disabling = ref(false)
const qrCode = ref('')
const recoveryCodes = ref<string[]>([])

const confirmationForm = useForm({
  code: '',
})

const enableTwoFactor = (): void => {
  enabling.value = true
  router.post('/user/two-factor-authentication', {}, {
    preserveScroll: true,
    onSuccess: () => {
      confirming.value = true
      showQrCode()
      showRecoveryCodes()
    },
    onFinish: () => {
      enabling.value = false
    },
  })
}

const showQrCode = (): void => {
  fetch('/user/two-factor-qr-code')
    .then(r => r.json())
    .then(data => { qrCode.value = data.svg })
}

const showRecoveryCodes = (): void => {
  fetch('/user/two-factor-recovery-codes')
    .then(r => r.json())
    .then(data => { recoveryCodes.value = data })
}

const confirmTwoFactor = (): void => {
  confirmationForm.post('/user/confirmed-two-factor-authentication', {
    preserveScroll: true,
    onSuccess: () => {
      confirming.value = false
    },
  })
}

const disableTwoFactor = (): void => {
  disabling.value = true
  router.delete('/user/two-factor-authentication', {
    preserveScroll: true,
    onSuccess: () => {
      qrCode.value = ''
      recoveryCodes.value = []
    },
    onFinish: () => {
      disabling.value = false
    },
  })
}
</script>

<template>
  <div style="max-width: 600px;">
    <div class="text-h6 mb-4">Two-Factor Authentication</div>
    <div class="text-body-2 text-medium-emphasis mb-6">
      Add an extra layer of security to your account using a TOTP authenticator app.
    </div>

    <div v-if="!page.props.auth?.user?.two_factor_enabled">
      <VBtn
        :loading="enabling"
        :disabled="enabling"
        @click="enableTwoFactor"
      >
        Enable Two-Factor Authentication
      </VBtn>
    </div>

    <VCard v-if="confirming" class="mt-6">
      <VCardText>
        <div class="text-body-2 text-medium-emphasis mb-4">
          Scan this QR code with your authenticator app, then enter the code below to confirm.
        </div>

        <!-- eslint-disable-next-line vue/no-v-html -->
        <div v-if="qrCode" v-html="qrCode" class="mb-4" />

        <VForm @submit.prevent="confirmTwoFactor" style="max-width: 300px;">
          <VTextField
            v-model="confirmationForm.code"
            label="Confirmation Code"
            type="text"
            inputmode="numeric"
            placeholder="000000"
            :error-messages="confirmationForm.errors.code ? [confirmationForm.errors.code] : []"
            class="mb-4"
          />

          <VBtn
            type="submit"
            :loading="confirmationForm.processing"
            :disabled="confirmationForm.processing"
          >
            Confirm
          </VBtn>
        </VForm>
      </VCardText>
    </VCard>

    <VCard v-if="recoveryCodes.length > 0 && !confirming" class="mt-6">
      <VCardText>
        <div class="text-subtitle-2 font-weight-bold mb-2">Recovery Codes</div>
        <div class="text-body-2 text-medium-emphasis mb-3">
          Store these codes in a safe place. They can be used to access your account if you lose your authenticator device.
        </div>
        <VSheet rounded color="surface-variant" class="pa-4 font-weight-medium" style="font-family: monospace;">
          <div v-for="code in recoveryCodes" :key="code">{{ code }}</div>
        </VSheet>
      </VCardText>
    </VCard>

    <VCard v-if="page.props.auth?.user?.two_factor_enabled && !confirming" class="mt-6">
      <VCardText>
        <VAlert type="success" variant="tonal" class="mb-4">
          Two-factor authentication is enabled.
        </VAlert>

        <VBtn
          color="error"
          :loading="disabling"
          :disabled="disabling"
          @click="disableTwoFactor"
        >
          Disable Two-Factor Authentication
        </VBtn>
      </VCardText>
    </VCard>
  </div>
</template>
