<template>
    <div class="space-y-6 max-w-lg">
        <!-- Password change -->
        <form class="p-6 bg-white rounded-2xl border border-zinc-300 space-y-5" @submit.prevent="savePassword">
            <h2 class="text-lg font-black text-zinc-800">Change password</h2>

            <div class="space-y-2">
                <label class="text-sm font-bold text-zinc-800">Current password</label>
                <input
                    v-model="passwordForm.current_password"
                    type="password"
                    :class="passwordErrors.current_password ? 'border-red-400' : 'border-zinc-300'"
                    class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
                />
                <p v-if="passwordErrors.current_password" class="text-xs text-red-600">{{ passwordErrors.current_password[0] }}</p>
            </div>

            <div class="space-y-2">
                <label class="text-sm font-bold text-zinc-800">New password</label>
                <input
                    v-model="passwordForm.password"
                    type="password"
                    :class="passwordErrors.password ? 'border-red-400' : 'border-zinc-300'"
                    class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
                />
                <p v-if="passwordErrors.password" class="text-xs text-red-600">{{ passwordErrors.password[0] }}</p>
            </div>

            <div class="space-y-2">
                <label class="text-sm font-bold text-zinc-800">Confirm new password</label>
                <input
                    v-model="passwordForm.password_confirmation"
                    type="password"
                    :class="passwordErrors.password_confirmation ? 'border-red-400' : 'border-zinc-300'"
                    class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
                />
                <p v-if="passwordErrors.password_confirmation" class="text-xs text-red-600">{{ passwordErrors.password_confirmation[0] }}</p>
            </div>

            <p v-if="passwordNetworkError" class="text-sm text-red-600">{{ passwordNetworkError }}</p>

            <div class="flex items-center gap-4">
                <button
                    type="submit"
                    :disabled="passwordSaving"
                    class="px-8 py-3 bg-accent text-white rounded-xl font-bold hover:bg-accent-content transition-all disabled:opacity-50"
                >
                    {{ passwordSaving ? 'Updating…' : 'Update password' }}
                </button>
                <p v-if="passwordSaved" class="text-sm font-bold text-green-600">Password updated!</p>
            </div>
        </form>

        <!-- Two-factor authentication -->
        <div class="p-6 bg-white rounded-2xl border border-zinc-300 space-y-4">
            <div class="flex items-center justify-between">
                <div>
                    <h2 class="text-lg font-black text-zinc-800">Two-factor authentication</h2>
                    <p class="text-sm text-zinc-500 mt-0.5">
                        {{ twoFactorEnabled ? 'Enabled — your account is extra secure.' : 'Add extra security to your account.' }}
                    </p>
                </div>
                <span
                    class="px-3 py-1 rounded-full text-xs font-black"
                    :class="twoFactorEnabled ? 'bg-green-100 text-green-700' : 'bg-zinc-50 text-zinc-500'"
                >
                    {{ twoFactorEnabled ? 'ON' : 'OFF' }}
                </span>
            </div>

            <!-- 2FA enabling flow -->
            <div v-if="enablingTwoFactor" class="space-y-4 border-t border-zinc-300 pt-4">
                <p class="text-sm font-bold text-zinc-800">Scan this QR code in your authenticator app:</p>

                <div v-if="setupData" class="flex flex-col items-start gap-4">
                    <!-- eslint-disable-next-line vue/no-v-html -->
                    <div v-html="setupData.svg" class="[&_svg]:w-40 [&_svg]:h-40"></div>
                    <div class="space-y-1">
                        <p class="font-mono text-[10px] uppercase tracking-widest text-zinc-500 mb-1 truncate">Or enter setup key manually</p>
                        <code class="text-xs bg-zinc-50 px-3 py-2 rounded-lg font-mono text-zinc-800 break-all block">{{ setupData.secretKey }}</code>
                    </div>
                </div>

                <div v-if="!twoFactorEnabled" class="space-y-2">
                    <label class="text-sm font-bold text-zinc-800">Enter the 6-digit code to confirm</label>
                    <div class="flex gap-3">
                        <input
                            v-model="confirmCode"
                            type="text"
                            maxlength="6"
                            inputmode="numeric"
                            placeholder="000000"
                            :class="confirmError ? 'border-red-400' : 'border-zinc-300'"
                            class="w-36 h-12 px-4 bg-zinc-50 border rounded-xl font-mono text-center text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
                        />
                        <button
                            @click="confirmTwoFactor"
                            :disabled="confirmCode.length !== 6 || confirming"
                            class="px-6 py-3 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent-content transition-all disabled:opacity-50"
                        >
                            {{ confirming ? 'Verifying…' : 'Confirm' }}
                        </button>
                    </div>
                    <p v-if="confirmError" class="text-xs text-red-600">{{ confirmError }}</p>
                </div>

                <p v-if="twoFactorEnabled" class="text-sm font-bold text-green-600">
                    Two-factor authentication is now active.
                </p>

                <button
                    v-if="!twoFactorEnabled"
                    @click="cancelEnable"
                    class="text-sm text-zinc-500 hover:text-zinc-800"
                >
                    Cancel
                </button>
            </div>

            <!-- Recovery codes (when 2FA enabled and not mid-setup) -->
            <div v-if="twoFactorEnabled && !enablingTwoFactor" class="border-t border-zinc-300 pt-4 space-y-3">
                <div class="flex items-center justify-between">
                    <p class="text-sm font-bold text-zinc-800">Recovery codes</p>
                    <button
                        @click="toggleRecoveryCodes"
                        class="text-xs font-bold text-accent hover:underline"
                    >
                        {{ showRecoveryCodes ? 'Hide' : 'Show' }}
                    </button>
                </div>
                <div v-if="showRecoveryCodes" class="space-y-2">
                    <div class="grid grid-cols-2 gap-1 bg-zinc-50 rounded-xl p-4">
                        <code
                            v-for="code in recoveryCodes"
                            :key="code"
                            class="text-xs font-mono text-zinc-800"
                        >{{ code }}</code>
                    </div>
                    <button
                        @click="regenRecoveryCodes"
                        :disabled="regenLoading"
                        class="text-xs font-bold text-zinc-500 hover:text-zinc-800"
                    >
                        {{ regenLoading ? 'Regenerating…' : 'Regenerate codes' }}
                    </button>
                </div>
            </div>

            <!-- Action buttons -->
            <div class="flex gap-3 border-t border-zinc-300 pt-4">
                <button
                    v-if="!twoFactorEnabled && !enablingTwoFactor"
                    @click="enableTwoFactor"
                    :disabled="tfaActionLoading"
                    class="px-6 py-2.5 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent-content transition-colors disabled:opacity-50"
                >
                    {{ tfaActionLoading ? 'Enabling…' : 'Enable 2FA' }}
                </button>
                <button
                    v-if="twoFactorEnabled && !enablingTwoFactor"
                    @click="disableTwoFactor"
                    :disabled="tfaActionLoading"
                    class="px-6 py-2.5 bg-white border border-zinc-300 rounded-xl text-sm font-bold text-zinc-500 hover:border-red-300 hover:text-red-600 transition-colors disabled:opacity-50"
                >
                    {{ tfaActionLoading ? 'Disabling…' : 'Disable 2FA' }}
                </button>
            </div>

            <p v-if="tfaError" class="text-sm text-red-600">{{ tfaError }}</p>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'
import { useAuth } from '../../../composables/useAuth.js'

const { user, updatePassword } = useAuth()

// Separate axios instance for Fortify web routes (base URL is / not /api)
const web = axios.create({
    baseURL: '/',
    withCredentials: true,
    withXSRFToken: true,
    headers: {
        Accept: 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
    },
})

// Password form
const passwordForm = ref({ current_password: '', password: '', password_confirmation: '' })
const passwordErrors = ref({})
const passwordNetworkError = ref('')
const passwordSaving = ref(false)
const passwordSaved = ref(false)

async function savePassword() {
    passwordSaving.value = true
    passwordSaved.value = false
    passwordErrors.value = {}
    passwordNetworkError.value = ''
    try {
        await updatePassword(passwordForm.value)
        passwordForm.value = { current_password: '', password: '', password_confirmation: '' }
        passwordSaved.value = true
        setTimeout(() => { passwordSaved.value = false }, 3000)
    } catch (err) {
        if (err.response?.status === 422) {
            passwordErrors.value = err.response.data.errors ?? {}
        } else {
            passwordNetworkError.value = 'Something went wrong. Please try again.'
        }
    } finally {
        passwordSaving.value = false
    }
}

// 2FA
const twoFactorEnabled = ref(false)
const enablingTwoFactor = ref(false)
const setupData = ref(null)
const confirmCode = ref('')
const confirmError = ref('')
const confirming = ref(false)
const showRecoveryCodes = ref(false)
const recoveryCodes = ref([])
const regenLoading = ref(false)
const tfaActionLoading = ref(false)
const tfaError = ref('')

onMounted(async () => {
    twoFactorEnabled.value = !!user.value?.two_factor_confirmed_at
    // Ensure CSRF cookie is fresh for Fortify web routes
    await axios.get('/sanctum/csrf-cookie', { withCredentials: true })
})

async function enableTwoFactor() {
    tfaActionLoading.value = true
    tfaError.value = ''
    try {
        await web.post('/user/two-factor-authentication')
        const [qrRes, keyRes] = await Promise.all([
            web.get('/user/two-factor-qr-code'),
            web.get('/user/two-factor-secret-key'),
        ])
        setupData.value = { svg: qrRes.data.svg, secretKey: keyRes.data.secretKey }
        enablingTwoFactor.value = true
    } catch {
        tfaError.value = 'Failed to enable 2FA. Please try again.'
    } finally {
        tfaActionLoading.value = false
    }
}

async function confirmTwoFactor() {
    confirming.value = true
    confirmError.value = ''
    try {
        await web.post('/user/confirmed-two-factor-authentication', { code: confirmCode.value })
        twoFactorEnabled.value = true
        confirmCode.value = ''
        await loadRecoveryCodes()
    } catch (err) {
        confirmError.value = err.response?.data?.errors?.code?.[0] ?? 'Invalid code. Please try again.'
        confirmCode.value = ''
    } finally {
        confirming.value = false
    }
}

async function disableTwoFactor() {
    tfaActionLoading.value = true
    tfaError.value = ''
    try {
        await web.delete('/user/two-factor-authentication')
        twoFactorEnabled.value = false
        showRecoveryCodes.value = false
        recoveryCodes.value = []
    } catch {
        tfaError.value = 'Failed to disable 2FA. Please try again.'
    } finally {
        tfaActionLoading.value = false
    }
}

function cancelEnable() {
    enablingTwoFactor.value = false
    setupData.value = null
    confirmCode.value = ''
    confirmError.value = ''
}

async function loadRecoveryCodes() {
    try {
        const response = await web.get('/user/two-factor-recovery-codes')
        recoveryCodes.value = response.data
    } catch {
        // Non-fatal
    }
}

async function toggleRecoveryCodes() {
    if (!showRecoveryCodes.value && recoveryCodes.value.length === 0) {
        await loadRecoveryCodes()
    }
    showRecoveryCodes.value = !showRecoveryCodes.value
}

async function regenRecoveryCodes() {
    regenLoading.value = true
    try {
        await web.post('/user/two-factor-recovery-codes')
        await loadRecoveryCodes()
    } catch {
        // Silently fail
    } finally {
        regenLoading.value = false
    }
}
</script>
