<script lang="ts" setup>
import { ref, onMounted, computed } from 'vue'
import QRCode from 'qrcode'

// Enrollment state
const isLoading = ref(true)
const isEnrolled = ref(false)
const enrollmentStep = ref<'status' | 'setup' | 'verify' | 'success' | 'disable'>('status')

// Enrollment data
const secret = ref('')
const provisioningUri = ref('')
const qrCodeDataUrl = ref('')
const recoveryCodes = ref<string[]>([])

// Verification
const verificationCode = ref('')
const isVerifying = ref(false)
const verificationError = ref('')

// Disable
const disableCode = ref('')
const isDisabling = ref(false)
const disableError = ref('')

// Dialog state
const showRecoveryCodesDialog = ref(false)
const recoveryCodesCopied = ref(false)

// API base URL - module routes are prefixed with /m/{module_handle}
const apiBase = '/m/authentication_provider_totp'

// Load initial status
onMounted(async () => {
  await loadStatus()
})

async function loadStatus() {
  isLoading.value = true
  try {
    const response = await fetch(`${apiBase}/totp/status`, {
      credentials: 'include',
    })
    const data = await response.json()
    isEnrolled.value = data.enrolled ?? false
    enrollmentStep.value = isEnrolled.value ? 'status' : 'status'
  } catch (error) {
    console.error('Failed to load TOTP status:', error)
  } finally {
    isLoading.value = false
  }
}

async function startEnrollment() {
  isLoading.value = true
  verificationError.value = ''
  
  try {
    const response = await fetch(`${apiBase}/totp/enroll`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      body: JSON.stringify({}),
    })
    
    const data = await response.json()
    
    if (!response.ok) {
      verificationError.value = data.error || 'Failed to start enrollment'
      return
    }
    
    secret.value = data.secret
    provisioningUri.value = data.provisioning_uri
    recoveryCodes.value = data.recovery_codes || []
    
    // Generate QR code client-side
    if (provisioningUri.value) {
      qrCodeDataUrl.value = await QRCode.toDataURL(provisioningUri.value, {
        width: 256,
        margin: 2,
        color: {
          dark: '#000000',
          light: '#ffffff',
        },
      })
    }
    
    enrollmentStep.value = 'setup'
  } catch (error) {
    console.error('Failed to start enrollment:', error)
    verificationError.value = 'Failed to start enrollment. Please try again.'
  } finally {
    isLoading.value = false
  }
}

async function verifyEnrollment() {
  if (!verificationCode.value || verificationCode.value.length !== 6) {
    verificationError.value = 'Please enter a valid 6-digit code'
    return
  }
  
  isVerifying.value = true
  verificationError.value = ''
  
  try {
    const response = await fetch(`${apiBase}/totp/enroll/verify`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      body: JSON.stringify({ code: verificationCode.value }),
    })
    
    const data = await response.json()
    
    if (!response.ok) {
      verificationError.value = data.error || 'Invalid verification code'
      return
    }
    
    isEnrolled.value = true
    enrollmentStep.value = 'success'
    showRecoveryCodesDialog.value = true
  } catch (error) {
    console.error('Failed to verify enrollment:', error)
    verificationError.value = 'Verification failed. Please try again.'
  } finally {
    isVerifying.value = false
  }
}

async function disableTotp() {
  if (!disableCode.value || disableCode.value.length !== 6) {
    disableError.value = 'Please enter a valid 6-digit code'
    return
  }
  
  isDisabling.value = true
  disableError.value = ''
  
  try {
    const response = await fetch(`${apiBase}/totp/enroll/remove`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'include',
      body: JSON.stringify({ code: disableCode.value }),
    })
    
    const data = await response.json()
    
    if (!response.ok) {
      disableError.value = data.error || 'Invalid verification code'
      return
    }
    
    isEnrolled.value = false
    enrollmentStep.value = 'status'
    disableCode.value = ''
    
    // Reset enrollment data
    secret.value = ''
    provisioningUri.value = ''
    qrCodeDataUrl.value = ''
    recoveryCodes.value = []
    verificationCode.value = ''
  } catch (error) {
    console.error('Failed to disable TOTP:', error)
    disableError.value = 'Failed to disable TOTP. Please try again.'
  } finally {
    isDisabling.value = false
  }
}

function cancelEnrollment() {
  enrollmentStep.value = 'status'
  verificationCode.value = ''
  verificationError.value = ''
}

function cancelDisable() {
  enrollmentStep.value = 'status'
  disableCode.value = ''
  disableError.value = ''
}

function showDisableDialog() {
  enrollmentStep.value = 'disable'
}

async function copyRecoveryCodes() {
  const codesText = recoveryCodes.value.join('\n')
  await navigator.clipboard.writeText(codesText)
  recoveryCodesCopied.value = true
  setTimeout(() => {
    recoveryCodesCopied.value = false
  }, 2000)
}

function downloadRecoveryCodes() {
  const codesText = recoveryCodes.value.join('\n')
  const blob = new Blob([codesText], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = 'totp-recovery-codes.txt'
  a.click()
  URL.revokeObjectURL(url)
}

function finishSetup() {
  showRecoveryCodesDialog.value = false
  enrollmentStep.value = 'status'
}

const formattedSecret = computed(() => {
  // Format secret in groups of 4 for easier reading
  return secret.value.match(/.{1,4}/g)?.join(' ') || secret.value
})
</script>

<template>
  <VCol cols="12" md="8" lg="4">
    <VCard>
      <VCardTitle class="d-flex align-center">
        <VIcon start icon="mdi-shield-check" />
        Two-Factor Authentication (TOTP)
      </VCardTitle>
      
      <VCardText>
        <!-- Loading State -->
        <div v-if="isLoading" class="text-center py-8">
          <VProgressCircular indeterminate color="primary" />
          <p class="mt-4 text-body-2">Loading...</p>
        </div>
          
          <!-- Status View (Not Enrolled) -->
          <template v-else-if="enrollmentStep === 'status' && !isEnrolled">
            <VAlert
              type="info"
              variant="tonal"
              class="mb-4"
            >
              <VAlertTitle>Two-factor authentication is not enabled</VAlertTitle>
              <p class="mb-0">
                Add an extra layer of security to your account by enabling two-factor authentication 
                using an authenticator app like Google Authenticator, Authy, or Microsoft Authenticator.
              </p>
            </VAlert>
            
            <VBtn
              color="primary"
              @click="startEnrollment"
            >
              <VIcon start icon="mdi-shield-plus" />
              Enable Two-Factor Authentication
            </VBtn>
          </template>
          
          <!-- Status View (Enrolled) -->
          <template v-else-if="enrollmentStep === 'status' && isEnrolled">
            <VAlert
              type="success"
              variant="tonal"
              class="mb-4"
            >
              <VAlertTitle>Two-factor authentication is enabled</VAlertTitle>
              <p class="mb-0">
                Your account is protected with TOTP two-factor authentication.
              </p>
            </VAlert>
            
            <VBtn
              color="error"
              variant="outlined"
              @click="showDisableDialog"
            >
              <VIcon start icon="mdi-shield-off" />
              Disable Two-Factor Authentication
            </VBtn>
          </template>
          
          <!-- Setup View -->
          <template v-else-if="enrollmentStep === 'setup'">
            <div class="mb-4">
              <h3 class="text-h6 mb-2">Step 1: Scan QR Code</h3>
              <p class="text-body-2 mb-4">
                Scan this QR code with your authenticator app (Google Authenticator, Authy, etc.)
              </p>
              
              <div class="d-flex justify-center mb-4">
                <VCard variant="outlined" class="pa-4">
                  <img
                    v-if="qrCodeDataUrl"
                    :src="qrCodeDataUrl"
                    alt="TOTP QR Code"
                    width="256"
                    height="256"
                  />
                  <VProgressCircular v-else indeterminate color="primary" />
                </VCard>
              </div>
              
              <VExpansionPanels variant="accordion">
                <VExpansionPanel>
                  <VExpansionPanelTitle>
                    <VIcon start icon="mdi-keyboard" />
                    Can't scan? Enter manually
                  </VExpansionPanelTitle>
                  <VExpansionPanelText>
                    <p class="text-body-2 mb-2">Enter this secret key in your authenticator app:</p>
                    <VTextField
                      :model-value="formattedSecret"
                      readonly
                      variant="outlined"
                      density="compact"
                      append-inner-icon="mdi-content-copy"
                      @click:append-inner="navigator.clipboard.writeText(secret)"
                    />
                  </VExpansionPanelText>
                </VExpansionPanel>
              </VExpansionPanels>
            </div>
            
            <VDivider class="my-4" />
            
            <div>
              <h3 class="text-h6 mb-2">Step 2: Verify Setup</h3>
              <p class="text-body-2 mb-4">
                Enter the 6-digit code from your authenticator app to verify the setup.
              </p>
              
              <VTextField
                v-model="verificationCode"
                label="Verification Code"
                placeholder="000000"
                maxlength="6"
                variant="outlined"
                :error-messages="verificationError"
                class="mb-4"
                @keyup.enter="verifyEnrollment"
              />
              
              <div class="d-flex gap-2">
                <VBtn
                  color="primary"
                  :loading="isVerifying"
                  :disabled="verificationCode.length !== 6"
                  @click="verifyEnrollment"
                >
                  <VIcon start icon="mdi-check" />
                  Verify and Enable
                </VBtn>
                <VBtn
                  variant="outlined"
                  @click="cancelEnrollment"
                >
                  Cancel
                </VBtn>
              </div>
            </div>
          </template>
          
          <!-- Success View (after enrollment, before closing dialog) -->
          <template v-else-if="enrollmentStep === 'success'">
            <VAlert
              type="success"
              variant="tonal"
              class="mb-4"
            >
              <VAlertTitle>Two-factor authentication enabled!</VAlertTitle>
              <p class="mb-0">
                Your account is now protected with TOTP two-factor authentication.
              </p>
            </VAlert>
          </template>
          
          <!-- Disable View -->
          <template v-else-if="enrollmentStep === 'disable'">
            <VAlert
              type="warning"
              variant="tonal"
              class="mb-4"
            >
              <VAlertTitle>Disable Two-Factor Authentication</VAlertTitle>
              <p class="mb-0">
                This will remove the extra security layer from your account. 
                Enter your current 6-digit code to confirm.
              </p>
            </VAlert>
            
            <VTextField
              v-model="disableCode"
              label="Current Verification Code"
              placeholder="000000"
              maxlength="6"
              variant="outlined"
              :error-messages="disableError"
              class="mb-4"
              @keyup.enter="disableTotp"
            />
            
            <div class="d-flex gap-2">
              <VBtn
                color="error"
                :loading="isDisabling"
                :disabled="disableCode.length !== 6"
                @click="disableTotp"
              >
                <VIcon start icon="mdi-shield-off" />
                Disable TOTP
              </VBtn>
              <VBtn
                variant="outlined"
                @click="cancelDisable"
              >
                Cancel
              </VBtn>
            </div>
          </template>
        </VCardText>
      </VCard>
      
      <!-- Recovery Codes Dialog -->
      <VDialog
        v-model="showRecoveryCodesDialog"
        max-width="500"
        persistent
      >
        <VCard>
          <VCardTitle class="d-flex align-center">
            <VIcon start icon="mdi-key" color="warning" />
            Save Your Recovery Codes
          </VCardTitle>
          
          <VCardText>
            <VAlert
              type="warning"
              variant="tonal"
              class="mb-4"
            >
              <p class="mb-0">
                <strong>Important:</strong> Save these recovery codes in a safe place. 
                If you lose access to your authenticator app, you can use one of these codes to regain access to your account.
                Each code can only be used once.
              </p>
            </VAlert>
            
            <VCard variant="outlined" class="pa-4 mb-4">
              <div class="d-flex flex-wrap gap-2 justify-center">
                <VChip
                  v-for="(code, index) in recoveryCodes"
                  :key="index"
                  variant="tonal"
                  class="font-weight-medium"
                >
                  {{ code }}
                </VChip>
              </div>
            </VCard>
            
            <div class="d-flex gap-2 justify-center">
              <VBtn
                variant="outlined"
                size="small"
                @click="copyRecoveryCodes"
              >
                <VIcon start :icon="recoveryCodesCopied ? 'mdi-check' : 'mdi-content-copy'" />
                {{ recoveryCodesCopied ? 'Copied!' : 'Copy Codes' }}
              </VBtn>
              <VBtn
                variant="outlined"
                size="small"
                @click="downloadRecoveryCodes"
              >
                <VIcon start icon="mdi-download" />
                Download
              </VBtn>
            </div>
          </VCardText>
          
          <VCardActions class="justify-end pa-4">
            <VBtn
              color="primary"
              @click="finishSetup"
            >
              I've Saved My Codes
            </VBtn>
          </VCardActions>
        </VCard>
      </VDialog>
  </VCol>
</template>
