<script setup lang="ts">
import { useAuthStore } from '@/stores/useAuthStore'
import { useChangePassword } from '@/composables/api/useAccount'
import {
  useMfaStatus,
  useTrustedDevices,
  useRevokeDevice,
  useRevokeAllDevices,
  useRegenerateBackupCodes,
  useSetPreferredMethod,
} from '@/composables/api/useMfa'
import MfaTotpSetupDialog from '@/components/settings/MfaTotpSetupDialog.vue'
import MfaEmailSetupDialog from '@/components/settings/MfaEmailSetupDialog.vue'
import MfaDisableDialog from '@/components/settings/MfaDisableDialog.vue'

const authStore = useAuthStore()

// ─── Password Change ───
const passwordForm = ref({
  current_password: '',
  password: '',
  password_confirmation: '',
})
const passwordFieldErrors = ref<Record<string, string>>({})
const passwordSuccess = ref('')
const showCurrentPw = ref(false)
const showNewPw = ref(false)
const showConfirmPw = ref(false)

const changePasswordMutation = useChangePassword()

async function handlePasswordChange() {
  passwordFieldErrors.value = {}
  passwordSuccess.value = ''

  changePasswordMutation.mutate(passwordForm.value, {
    onSuccess: (data) => {
      passwordSuccess.value = data.message
      passwordForm.value = {
        current_password: '',
        password: '',
        password_confirmation: '',
      }
    },
    onError: (err: unknown) => {
      const ax = err as { response?: { data?: { message?: string; errors?: Record<string, string[]> } } }
      if (ax.response?.data?.errors) {
        for (const [key, messages] of Object.entries(ax.response.data.errors)) {
          passwordFieldErrors.value[key] = messages[0]
        }
      }
    },
  })
}

// ─── MFA ───
const { data: mfaStatus, refetch: refetchMfaStatus } = useMfaStatus()
const { data: trustedDevices, refetch: refetchDevices } = useTrustedDevices()
const revokeDeviceMutation = useRevokeDevice()
const revokeAllMutation = useRevokeAllDevices()
const regenerateCodesMutation = useRegenerateBackupCodes()

const setPreferredMethodMutation = useSetPreferredMethod()

const showTotpSetup = ref(false)
const showEmailSetup = ref(false)
const showDisableDialog = ref(false)
const showRegenerateDialog = ref(false)
const regenerateCode = ref('')
const regeneratedCodes = ref<string[]>([])
const regenerateError = ref('')

const isEnabled = computed(() => mfaStatus.value?.enabled ?? false)

const totpConfigured = computed(() => mfaStatus.value?.totp_configured ?? false)
const emailConfigured = computed(() => mfaStatus.value?.email_configured ?? false)
const preferredMethod = computed(() => mfaStatus.value?.method ?? null)

function handleSetPreferred(method: 'totp' | 'email') {
  setPreferredMethodMutation.mutate(method)
}

const backupCodesRemaining = computed(() => mfaStatus.value?.backup_codes_remaining ?? 0)
const backupCodesColor = computed(() => {
  if (backupCodesRemaining.value > 5) return 'success'
  if (backupCodesRemaining.value >= 3) return 'warning'
  return 'error'
})

function onSetupCompleted() {
  // Refetch MFA status so the method cards update (enabled, method, backup codes)
  refetchMfaStatus()
  // Immediately clear the enforcement flag so the router guard unblocks navigation
  authStore.mfaSetupRequired = false
  // Refresh the full /auth/me response into the store so the flag stays
  // correct on subsequent navigations (without needing a full page reload)
  authStore.refreshUser()
}

function onDisabled() {
  refetchMfaStatus()
  refetchDevices()
}

async function handleRevokeDevice(id: string) {
  await revokeDeviceMutation.mutateAsync(id)
  refetchDevices()
}

async function handleRevokeAllDevices() {
  await revokeAllMutation.mutateAsync()
  refetchDevices()
}

async function handleRegenerateBackupCodes() {
  regenerateError.value = ''
  try {
    const data = await regenerateCodesMutation.mutateAsync({ code: regenerateCode.value })

    regeneratedCodes.value = data.backup_codes
    refetchMfaStatus()
  }
  catch (err: unknown) {
    const ax = err as { response?: { data?: { message?: string } } }

    regenerateError.value = ax.response?.data?.message ?? 'Kon codes niet genereren.'
    regenerateCode.value = ''
  }
}

function copyRegeneratedCodes() {
  navigator.clipboard.writeText(regeneratedCodes.value.join('\n'))
}
</script>

<template>
  <!-- Enforcement notice -->
  <VAlert
    v-if="mfaStatus?.is_required && !isEnabled"
    type="warning"
    variant="tonal"
    class="mb-6"
  >
    Je organisatie vereist tweestapsverificatie. Stel het nu in om het platform te kunnen gebruiken.
  </VAlert>

  <!-- Card 1: Wachtwoord wijzigen -->
  <VCard class="mb-6">
    <VCardItem>
      <VCardTitle>Wachtwoord wijzigen</VCardTitle>
    </VCardItem>
    <VForm @submit.prevent="handlePasswordChange">
      <VCardText class="pt-0">
        <VAlert
          v-if="passwordSuccess"
          type="success"
          variant="tonal"
          density="compact"
          class="mb-4"
        >
          {{ passwordSuccess }}
        </VAlert>

        <VRow>
          <VCol cols="12">
            <AppTextField
              v-model="passwordForm.current_password"
              label="Huidig wachtwoord"
              :type="showCurrentPw ? 'text' : 'password'"
              :append-inner-icon="showCurrentPw ? 'tabler-eye-off' : 'tabler-eye'"
              :error-messages="passwordFieldErrors.current_password"
              placeholder="············"
              @click:append-inner="showCurrentPw = !showCurrentPw"
            />
          </VCol>
          <VCol
            cols="12"
            md="6"
          >
            <AppTextField
              v-model="passwordForm.password"
              label="Nieuw wachtwoord"
              :type="showNewPw ? 'text' : 'password'"
              :append-inner-icon="showNewPw ? 'tabler-eye-off' : 'tabler-eye'"
              :error-messages="passwordFieldErrors.password"
              placeholder="············"
              @click:append-inner="showNewPw = !showNewPw"
            />
          </VCol>
          <VCol
            cols="12"
            md="6"
          >
            <AppTextField
              v-model="passwordForm.password_confirmation"
              label="Bevestig nieuw wachtwoord"
              :type="showConfirmPw ? 'text' : 'password'"
              :append-inner-icon="showConfirmPw ? 'tabler-eye-off' : 'tabler-eye'"
              :error-messages="passwordFieldErrors.password_confirmation"
              placeholder="············"
              @click:append-inner="showConfirmPw = !showConfirmPw"
            />
          </VCol>
        </VRow>
      </VCardText>

      <VCardText>
        <h6 class="text-h6 text-medium-emphasis mb-4">
          Wachtwoordvereisten:
        </h6>
        <VList class="card-list">
          <VListItem>
            <template #prepend>
              <VIcon
                size="10"
                icon="tabler-circle-filled"
              />
            </template>
            <span class="text-medium-emphasis">Minimaal 8 tekens</span>
          </VListItem>
          <VListItem>
            <template #prepend>
              <VIcon
                size="10"
                icon="tabler-circle-filled"
              />
            </template>
            <span class="text-medium-emphasis">Minimaal 1 hoofdletter en 1 kleine letter</span>
          </VListItem>
          <VListItem>
            <template #prepend>
              <VIcon
                size="10"
                icon="tabler-circle-filled"
              />
            </template>
            <span class="text-medium-emphasis">Minimaal 1 cijfer</span>
          </VListItem>
        </VList>
      </VCardText>

      <VCardText>
        <VBtn
          type="submit"
          :loading="changePasswordMutation.isPending.value"
        >
          Wachtwoord wijzigen
        </VBtn>
      </VCardText>
    </VForm>
  </VCard>

  <!-- Card 2: Tweestapsverificatie -->
  <VCard class="mb-6">
    <VCardItem>
      <VCardTitle>Tweestapsverificatie</VCardTitle>
    </VCardItem>
    <VCardText>
      <!-- MFA method cards -->
      <VRow>
        <!-- TOTP card -->
        <VCol
          cols="12"
          sm="6"
        >
          <VCard
            variant="outlined"
            :class="['mfa-method-card h-100', { 'mfa-method-card--primary': totpConfigured && preferredMethod === 'totp' }]"
          >
            <VCardText>
              <VAvatar
                color="primary"
                variant="tonal"
                size="44"
                rounded
                class="mb-3"
              >
                <VIcon
                  icon="tabler-device-mobile"
                  size="26"
                />
              </VAvatar>

              <h6 class="text-h6 mb-1">
                Authenticator app
              </h6>
              <p class="text-body-2 text-medium-emphasis mb-3">
                Gebruik een authenticator app zoals Google Authenticator of 1Password
              </p>

              <VChip
                :color="totpConfigured ? 'success' : 'default'"
                variant="tonal"
                size="small"
                :prepend-icon="totpConfigured ? 'tabler-check' : undefined"
              >
                {{ totpConfigured ? 'Geconfigureerd' : 'Niet ingesteld' }}
              </VChip>
            </VCardText>

            <VCardActions class="px-4 pb-4 pt-0">
              <template v-if="totpConfigured">
                <VChip
                  v-if="preferredMethod === 'totp'"
                  color="primary"
                  variant="tonal"
                  size="small"
                  prepend-icon="tabler-check"
                >
                  Primaire methode
                </VChip>
                <VBtn
                  v-else
                  variant="tonal"
                  size="small"
                  :loading="setPreferredMethodMutation.isPending.value"
                  @click="handleSetPreferred('totp')"
                >
                  Als primair instellen
                </VBtn>

                <VSpacer />

                <VBtn
                  variant="text"
                  size="small"
                  @click="showTotpSetup = true"
                >
                  Opnieuw instellen
                </VBtn>
              </template>

              <VBtn
                v-else
                variant="tonal"
                size="small"
                @click="showTotpSetup = true"
              >
                Instellen
              </VBtn>
            </VCardActions>
          </VCard>
        </VCol>

        <!-- Email card -->
        <VCol
          cols="12"
          sm="6"
        >
          <VCard
            variant="outlined"
            :class="['mfa-method-card h-100', { 'mfa-method-card--primary': emailConfigured && preferredMethod === 'email' }]"
          >
            <VCardText>
              <VAvatar
                color="primary"
                variant="tonal"
                size="44"
                rounded
                class="mb-3"
              >
                <VIcon
                  icon="tabler-mail"
                  size="26"
                />
              </VAvatar>

              <h6 class="text-h6 mb-1">
                E-mailcode
              </h6>
              <p class="text-body-2 text-medium-emphasis mb-3">
                Ontvang een 6-cijferige code op {{ authStore.user?.email }}
              </p>

              <VChip
                :color="emailConfigured ? 'success' : 'default'"
                variant="tonal"
                size="small"
                :prepend-icon="emailConfigured ? 'tabler-check' : undefined"
              >
                {{ emailConfigured ? 'Geconfigureerd' : 'Niet ingesteld' }}
              </VChip>
            </VCardText>

            <VCardActions class="px-4 pb-4 pt-0">
              <template v-if="emailConfigured">
                <VChip
                  v-if="preferredMethod === 'email'"
                  color="primary"
                  variant="tonal"
                  size="small"
                  prepend-icon="tabler-check"
                >
                  Primaire methode
                </VChip>
                <VBtn
                  v-else
                  variant="tonal"
                  size="small"
                  :loading="setPreferredMethodMutation.isPending.value"
                  @click="handleSetPreferred('email')"
                >
                  Als primair instellen
                </VBtn>

                <VSpacer />

                <VBtn
                  variant="text"
                  size="small"
                  @click="showEmailSetup = true"
                >
                  Opnieuw instellen
                </VBtn>
              </template>

              <VBtn
                v-else
                variant="tonal"
                size="small"
                @click="showEmailSetup = true"
              >
                Instellen
              </VBtn>
            </VCardActions>
          </VCard>
        </VCol>
      </VRow>

      <!-- Backup codes -->
      <VCard
        v-if="isEnabled"
        variant="outlined"
        class="mt-4"
      >
        <VCardText>
          <div class="d-flex align-center justify-space-between">
            <div>
              <div class="d-flex align-center gap-2 mb-1">
                <VIcon
                  icon="tabler-key"
                  size="20"
                  class="text-medium-emphasis"
                />
                <span class="text-body-1 font-weight-medium">Backup codes</span>
              </div>
              <span class="text-body-2 text-medium-emphasis">
                {{ backupCodesRemaining }} van 10 resterend
              </span>
            </div>
            <VBtn
              variant="tonal"
              size="small"
              prepend-icon="tabler-refresh"
              @click="showRegenerateDialog = true; regeneratedCodes = []; regenerateCode = ''; regenerateError = ''"
            >
              Nieuwe codes
            </VBtn>
          </div>
          <VProgressLinear
            :model-value="backupCodesRemaining * 10"
            :color="backupCodesColor"
            class="mt-3"
            rounded
            height="6"
          />
        </VCardText>
      </VCard>

      <!-- Disable MFA -->
      <div
        v-if="isEnabled"
        class="mt-6"
      >
        <VBtn
          variant="text"
          color="error"
          size="small"
          prepend-icon="tabler-shield-off"
          @click="showDisableDialog = true"
        >
          Tweestapsverificatie uitschakelen
        </VBtn>
      </div>
    </VCardText>
  </VCard>

  <!-- Card 3: Vertrouwde apparaten -->
  <VCard
    v-if="isEnabled"
    class="mb-6"
  >
    <VCardItem>
      <template #default>
        <VCardTitle>Vertrouwde apparaten</VCardTitle>
      </template>
      <template #append>
        <VBtn
          v-if="trustedDevices && trustedDevices.length > 1"
          variant="tonal"
          size="small"
          color="error"
          :loading="revokeAllMutation.isPending.value"
          @click="handleRevokeAllDevices"
        >
          Alles intrekken
        </VBtn>
      </template>
    </VCardItem>
    <VCardText>
      <template v-if="trustedDevices && trustedDevices.length > 0">
        <VList>
          <VListItem
            v-for="device in trustedDevices"
            :key="device.id"
            class="px-0"
          >
            <template #prepend>
              <VIcon
                icon="tabler-device-desktop"
                size="24"
                class="me-3"
              />
            </template>
            <VListItemTitle>{{ device.device_name ?? 'Onbekend apparaat' }}</VListItemTitle>
            <VListItemSubtitle>
              IP: {{ device.ip_address }}
              <span v-if="device.last_used_at">
                &middot; Laatst gebruikt: {{ new Date(device.last_used_at).toLocaleDateString('nl-NL') }}
              </span>
            </VListItemSubtitle>

            <template #append>
              <VBtn
                variant="text"
                size="small"
                color="error"
                icon="tabler-trash"
                :loading="revokeDeviceMutation.isPending.value"
                @click="handleRevokeDevice(device.id)"
              />
            </template>
          </VListItem>
        </VList>
      </template>

      <p
        v-else
        class="text-body-2 text-medium-emphasis"
      >
        Geen vertrouwde apparaten. Wanneer je inlogt met MFA kun je ervoor kiezen een apparaat te onthouden.
      </p>
    </VCardText>
  </VCard>

  <!-- Setup dialogs -->
  <MfaTotpSetupDialog
    v-model="showTotpSetup"
    @completed="onSetupCompleted"
  />

  <MfaEmailSetupDialog
    v-model="showEmailSetup"
    :user-email="authStore.user?.email ?? ''"
    @completed="onSetupCompleted"
  />

  <MfaDisableDialog
    v-model="showDisableDialog"
    :current-method="mfaStatus?.method ?? null"
    @disabled="onDisabled"
  />

  <!-- Regenerate backup codes dialog -->
  <VDialog
    v-model="showRegenerateDialog"
    max-width="460"
  >
    <VCard>
      <VCardTitle class="pt-4">
        Nieuwe backup codes genereren
      </VCardTitle>

      <VCardText v-if="regeneratedCodes.length === 0">
        <VAlert
          type="info"
          variant="tonal"
          class="mb-4"
        >
          Dit vervangt al je huidige backup codes. Oude codes werken niet meer.
        </VAlert>

        <VAlert
          v-if="regenerateError"
          type="error"
          variant="tonal"
          class="mb-4"
          density="comfortable"
        >
          {{ regenerateError }}
        </VAlert>

        <p class="text-body-2 mb-2">
          Voer je authenticator code in ter bevestiging
        </p>
        <AppTextField
          v-model="regenerateCode"
          placeholder="123456"
          autofocus
        />
      </VCardText>

      <VCardText v-else>
        <VAlert
          type="success"
          variant="tonal"
          class="mb-4"
        >
          Nieuwe backup codes gegenereerd. Bewaar ze veilig.
        </VAlert>

        <div class="d-flex flex-wrap gap-2 mb-4">
          <VChip
            v-for="code in regeneratedCodes"
            :key="code"
            variant="tonal"
            label
            class="font-weight-bold"
            style="font-family: monospace;"
          >
            {{ code }}
          </VChip>
        </div>

        <VBtn
          variant="tonal"
          size="small"
          prepend-icon="tabler-copy"
          @click="copyRegeneratedCodes"
        >
          Kopieer
        </VBtn>
      </VCardText>

      <VCardActions>
        <VSpacer />
        <VBtn
          variant="tonal"
          @click="showRegenerateDialog = false"
        >
          {{ regeneratedCodes.length > 0 ? 'Sluiten' : 'Annuleren' }}
        </VBtn>
        <VBtn
          v-if="regeneratedCodes.length === 0"
          color="primary"
          :loading="regenerateCodesMutation.isPending.value"
          :disabled="!regenerateCode"
          @click="handleRegenerateBackupCodes"
        >
          Genereren
        </VBtn>
      </VCardActions>
    </VCard>
  </VDialog>
</template>

<style lang="scss">
.card-list {
  --v-card-list-gap: 8px;
}
</style>

<style lang="scss" scoped>
.mfa-method-card--primary {
  border-color: rgb(var(--v-theme-primary));
  border-width: 2px;
}
</style>
