<script setup>
import { ref, computed, watch } from 'vue';
import { router, useForm, usePage } from '@inertiajs/vue3';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
import { Button } from '@/Components/ui/button';
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import { Badge } from '@/Components/ui/badge';
import ConfirmsPassword from '@/Components/ConfirmsPassword.vue';
import InputError from '@/Components/InputError.vue';
import { Shield, Key, Copy, RefreshCw, CheckCircle, AlertCircle } from 'lucide-vue-next';

const props = defineProps({
    requiresConfirmation: Boolean,
});

const page = usePage();
const enabling = ref(false);
const confirming = ref(false);
const disabling = ref(false);
const qrCode = ref(null);
const setupKey = ref(null);
const recoveryCodes = ref([]);

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

const twoFactorEnabled = computed(
    () => ! enabling.value && page.props.auth.user?.two_factor_enabled,
);

watch(twoFactorEnabled, () => {
    if (! twoFactorEnabled.value) {
        confirmationForm.reset();
        confirmationForm.clearErrors();
    }
});

const enableTwoFactorAuthentication = () => {
    enabling.value = true;

    router.post(route('two-factor.enable'), {}, {
        preserveScroll: true,
        onSuccess: () => Promise.all([
            showQrCode(),
            showSetupKey(),
            showRecoveryCodes(),
        ]),
        onFinish: () => {
            enabling.value = false;
            confirming.value = props.requiresConfirmation;
        },
    });
};

const showQrCode = () => {
    return axios.get(route('two-factor.qr-code')).then(response => {
        qrCode.value = response.data.svg;
    });
};

const showSetupKey = () => {
    return axios.get(route('two-factor.secret-key')).then(response => {
        setupKey.value = response.data.secretKey;
    });
}

const showRecoveryCodes = () => {
    return axios.get(route('two-factor.recovery-codes')).then(response => {
        recoveryCodes.value = response.data;
    });
};

const confirmTwoFactorAuthentication = () => {
    confirmationForm.post(route('two-factor.confirm'), {
        errorBag: "confirmTwoFactorAuthentication",
        preserveScroll: true,
        preserveState: true,
        onSuccess: () => {
            confirming.value = false;
            qrCode.value = null;
            setupKey.value = null;
        },
    });
};

const regenerateRecoveryCodes = () => {
    axios
        .post(route('two-factor.recovery-codes'))
        .then(() => showRecoveryCodes());
};

const disableTwoFactorAuthentication = () => {
    disabling.value = true;

    router.delete(route('two-factor.disable'), {
        preserveScroll: true,
        onSuccess: () => {
            disabling.value = false;
            confirming.value = false;
        },
    });
};

const copyToClipboard = async (text) => {
    try {
        await navigator.clipboard.writeText(text);
    } catch (err) {
        console.error('Failed to copy:', err);
    }
};
</script>

<template>
    <Card>
        <CardHeader>
            <div class="flex items-center gap-2">
                <Shield class="h-5 w-5 text-muted-foreground" />
                <CardTitle>Two Factor Authentication</CardTitle>
            </div>
            <CardDescription>
                Add additional security to your account using two factor authentication.
            </CardDescription>
        </CardHeader>

        <CardContent class="space-y-6">
            <!-- Status Header -->
            <div class="flex items-start gap-3">
                <div class="flex-1">
                    <h3 v-if="twoFactorEnabled && ! confirming" class="text-lg font-semibold flex items-center gap-2">
                        <CheckCircle class="h-5 w-5 text-green-600" />
                        Two factor authentication is enabled
                    </h3>
                    <h3 v-else-if="twoFactorEnabled && confirming" class="text-lg font-semibold flex items-center gap-2">
                        <AlertCircle class="h-5 w-5 text-amber-600" />
                        Finish enabling two factor authentication
                    </h3>
                    <h3 v-else class="text-lg font-semibold flex items-center gap-2">
                        <Shield class="h-5 w-5 text-muted-foreground" />
                        Two factor authentication is disabled
                    </h3>
                    <p class="mt-2 text-sm text-muted-foreground">
                        When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone's Google Authenticator application.
                    </p>
                </div>
            </div>

            <!-- QR Code & Setup -->
            <div v-if="twoFactorEnabled" class="space-y-6">
                <div v-if="qrCode" class="space-y-4">
                    <div class="rounded-lg border bg-muted/50 p-4">
                        <p v-if="confirming" class="text-sm font-medium mb-4">
                            To finish enabling two factor authentication, scan the following QR code using your phone's authenticator application or enter the setup key and provide the generated OTP code.
                        </p>
                        <p v-else class="text-sm text-muted-foreground mb-4">
                            Two factor authentication is now enabled. Scan the following QR code using your phone's authenticator application or enter the setup key.
                        </p>

                        <!-- QR Code -->
                        <div class="flex justify-center p-4 bg-white rounded-lg" v-html="qrCode" />

                        <!-- Setup Key -->
                        <div v-if="setupKey" class="mt-4 p-3 bg-background rounded-lg border">
                            <div class="flex items-center justify-between gap-2">
                                <div class="flex-1">
                                    <Label class="text-xs text-muted-foreground">Setup Key</Label>
                                    <p class="font-mono text-sm font-semibold mt-1" v-html="setupKey"></p>
                                </div>
                                <Button
                                    type="button"
                                    variant="ghost"
                                    size="sm"
                                    @click="copyToClipboard(setupKey)"
                                >
                                    <Copy class="h-4 w-4" />
                                </Button>
                            </div>
                        </div>
                    </div>

                    <!-- Confirmation Code Input -->
                    <div v-if="confirming" class="space-y-2">
                        <Label for="code">Confirmation Code</Label>
                        <Input
                            id="code"
                            v-model="confirmationForm.code"
                            type="text"
                            name="code"
                            inputmode="numeric"
                            autofocus
                            autocomplete="one-time-code"
                            placeholder="Enter 6-digit code"
                            class="max-w-xs"
                            @keyup.enter="confirmTwoFactorAuthentication"
                        />
                        <InputError :message="confirmationForm.errors.code" class="mt-2" />
                    </div>
                </div>

                <!-- Recovery Codes -->
                <div v-if="recoveryCodes.length > 0 && ! confirming" class="space-y-4">
                    <div class="rounded-lg border border-amber-200 bg-amber-50 p-4 dark:border-amber-800 dark:bg-amber-950">
                        <div class="flex items-start gap-2">
                            <Key class="h-5 w-5 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5" />
                            <p class="text-sm font-medium text-amber-900 dark:text-amber-100">
                                Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.
                            </p>
                        </div>
                    </div>

                    <div class="rounded-lg border bg-muted p-4">
                        <div class="grid grid-cols-2 gap-2 font-mono text-sm">
                            <div v-for="code in recoveryCodes" :key="code" class="flex items-center justify-between p-2 bg-background rounded border">
                                <span>{{ code }}</span>
                                <Button
                                    type="button"
                                    variant="ghost"
                                    size="sm"
                                    class="h-6 w-6 p-0"
                                    @click="copyToClipboard(code)"
                                >
                                    <Copy class="h-3 w-3" />
                                </Button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Action Buttons -->
            <div class="flex flex-wrap gap-2">
                <!-- Enable -->
                <div v-if="! twoFactorEnabled">
                    <ConfirmsPassword @confirmed="enableTwoFactorAuthentication">
                        <Button type="button" :disabled="enabling">
                            <Shield class="h-4 w-4 mr-2" />
                            Enable
                        </Button>
                    </ConfirmsPassword>
                </div>

                <!-- Confirm -->
                <template v-else>
                    <ConfirmsPassword @confirmed="confirmTwoFactorAuthentication">
                        <Button
                            v-if="confirming"
                            type="button"
                            :disabled="enabling"
                        >
                            <CheckCircle class="h-4 w-4 mr-2" />
                            Confirm
                        </Button>
                    </ConfirmsPassword>

                    <!-- Regenerate Recovery Codes -->
                    <ConfirmsPassword @confirmed="regenerateRecoveryCodes">
                        <Button
                            v-if="recoveryCodes.length > 0 && ! confirming"
                            type="button"
                            variant="outline"
                        >
                            <RefreshCw class="h-4 w-4 mr-2" />
                            Regenerate Recovery Codes
                        </Button>
                    </ConfirmsPassword>

                    <!-- Show Recovery Codes -->
                    <ConfirmsPassword @confirmed="showRecoveryCodes">
                        <Button
                            v-if="recoveryCodes.length === 0 && ! confirming"
                            type="button"
                            variant="outline"
                        >
                            <Key class="h-4 w-4 mr-2" />
                            Show Recovery Codes
                        </Button>
                    </ConfirmsPassword>

                    <!-- Cancel/Disable -->
                    <ConfirmsPassword @confirmed="disableTwoFactorAuthentication">
                        <Button
                            v-if="confirming"
                            type="button"
                            variant="outline"
                            :disabled="disabling"
                        >
                            Cancel
                        </Button>
                    </ConfirmsPassword>

                    <ConfirmsPassword @confirmed="disableTwoFactorAuthentication">
                        <Button
                            v-if="! confirming"
                            type="button"
                            variant="destructive"
                            :disabled="disabling"
                        >
                            Disable
                        </Button>
                    </ConfirmsPassword>
                </template>
            </div>
        </CardContent>
    </Card>
</template>
