<script setup lang="ts">
/**
 * TwoFactorCard — управление 2FA: включить (3-step wizard) / отключить.
 * Sprint 4 Phase B/2 — split SecurityTab (audit O-refactor-04 хвост).
 *
 * 2FA flow по ТЗ §1.6/Прил. Г.4.2 (TOTP 6 цифр, recovery 8 шт.):
 *   - Включить → POST /api/2fa/init → QR + secret → user сканирует →
 *     ввод 6-значного кода → POST /api/2fa/confirm → показ 8 recovery-codes один раз.
 *   - Отключить → modal с password → POST /api/2fa/disable.
 *
 * Регенерация recovery-codes вынесена в RecoveryCodesCard.vue.
 */
import * as authApi from '../../../api/auth';
import { useAuthStore } from '../../../stores/auth';
import { computed, ref } from 'vue';

const auth = useAuthStore();
const has2fa = computed(() => auth.user?.totp_enabled ?? false);

// === Setup wizard (3 шага: init → confirm → show codes) ===
const setupOpen = ref(false);
const setupStep = ref<'init' | 'confirm' | 'codes'>('init');
const setupSecret = ref('');
const setupQrUrl = ref('');
const setupCode = ref('');
const setupRecoveryCodes = ref<string[]>([]);
const setupError = ref('');
const setupBusy = ref(false);

async function openSetup(): Promise<void> {
    setupOpen.value = true;
    setupStep.value = 'init';
    setupError.value = '';
    setupCode.value = '';
    setupRecoveryCodes.value = [];
    setupBusy.value = true;
    try {
        const r = await authApi.twoFactorInit();
        setupSecret.value = r.secret;
        setupQrUrl.value = r.qr_url;
        setupStep.value = 'confirm';
    } catch (error: unknown) {
        setupError.value = error instanceof Error ? error.message : 'Ошибка инициализации.';
    } finally {
        setupBusy.value = false;
    }
}

async function confirmSetup(): Promise<void> {
    setupError.value = '';
    setupBusy.value = true;
    try {
        const r = await authApi.twoFactorConfirm(setupCode.value);
        setupRecoveryCodes.value = r.recovery_codes;
        setupStep.value = 'codes';
        if (auth.user) auth.user = { ...auth.user, totp_enabled: true };
    } catch {
        setupError.value = 'Неверный код. Проверьте время на устройстве.';
    } finally {
        setupBusy.value = false;
    }
}

function closeSetup(): void {
    setupOpen.value = false;
    setupSecret.value = '';
    setupQrUrl.value = '';
    setupCode.value = '';
}

// === Disable dialog ===
const disableOpen = ref(false);
const disablePassword = ref('');
const disableError = ref('');

async function confirmDisable(): Promise<void> {
    disableError.value = '';
    try {
        await authApi.twoFactorDisable(disablePassword.value);
        if (auth.user) auth.user = { ...auth.user, totp_enabled: false };
        disableOpen.value = false;
        disablePassword.value = '';
    } catch {
        disableError.value = 'Неверный пароль.';
    }
}
</script>

<template>
    <v-card variant="outlined" class="pa-4 mb-4" data-testid="2fa-card">
        <div class="d-flex justify-space-between align-center mb-3">
            <h3 class="text-subtitle-2 ma-0">Двухфакторная авторизация (2FA)</h3>
            <v-chip v-if="has2fa" color="success" size="small" variant="tonal">включена</v-chip>
            <v-chip v-else color="warning" size="small" variant="tonal">выключена</v-chip>
        </div>
        <p class="text-body-2 text-medium-emphasis mb-3">
            <template v-if="has2fa">
                Используется TOTP (Google Authenticator / Yandex Key). 8 одноразовых резервных кодов сохранены в
                безопасном месте.
            </template>
            <template v-else>
                Защитите аккаунт двухфакторной авторизацией. Поддерживаются Google Authenticator, Yandex Key, 1Password
                и другие TOTP-приложения.
            </template>
        </p>
        <div class="d-flex ga-2 flex-wrap">
            <v-btn
                v-if="!has2fa"
                color="primary"
                variant="flat"
                size="small"
                prepend-icon="mdi-shield-key"
                data-testid="enable-2fa-btn"
                @click="openSetup"
            >
                Включить 2FA
            </v-btn>
            <v-btn
                v-else
                variant="outlined"
                size="small"
                color="error"
                prepend-icon="mdi-shield-off"
                data-testid="disable-2fa-btn"
                @click="disableOpen = true"
            >
                Отключить 2FA
            </v-btn>
        </div>

        <!-- 2FA SETUP WIZARD -->
        <v-dialog v-model="setupOpen" :max-width="480" data-testid="setup-dialog">
            <v-card>
                <v-card-title>Включение 2FA</v-card-title>
                <v-card-text>
                    <template v-if="setupStep === 'init'">
                        <v-progress-circular indeterminate />
                    </template>
                    <template v-else-if="setupStep === 'confirm'">
                        <p class="mb-3">
                            Отсканируйте QR-код в приложении-аутентификаторе (Google Authenticator, Yandex Key) и
                            введите 6-значный код, который оно покажет.
                        </p>
                        <p class="text-caption text-medium-emphasis mb-3">
                            Если QR не сканируется, введите secret вручную:
                            <strong class="font-mono">{{ setupSecret }}</strong>
                        </p>
                        <v-text-field
                            v-model="setupCode"
                            label="6-значный код"
                            inputmode="numeric"
                            maxlength="6"
                            :error-messages="setupError ? [setupError] : []"
                            density="comfortable"
                        />
                    </template>
                    <template v-else-if="setupStep === 'codes'">
                        <v-alert type="warning" variant="tonal" class="mb-3">
                            Сохраните 8 резервных кодов сейчас — они показываются один раз!
                        </v-alert>
                        <div class="codes-grid">
                            <div v-for="(c, i) in setupRecoveryCodes" :key="i" class="code-item font-mono">
                                {{ c }}
                            </div>
                        </div>
                    </template>
                </v-card-text>
                <v-card-actions>
                    <v-spacer />
                    <v-btn v-if="setupStep === 'confirm'" :loading="setupBusy" color="primary" @click="confirmSetup">
                        Подтвердить
                    </v-btn>
                    <v-btn v-if="setupStep === 'codes'" color="primary" @click="closeSetup">Готово</v-btn>
                    <v-btn v-if="setupStep !== 'codes'" variant="text" @click="closeSetup">Отмена</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>

        <!-- DISABLE DIALOG -->
        <v-dialog v-model="disableOpen" :max-width="420" data-testid="disable-dialog">
            <v-card>
                <v-card-title>Отключить 2FA</v-card-title>
                <v-card-text>
                    <p class="mb-3">Введите пароль, чтобы подтвердить отключение двухфакторной авторизации.</p>
                    <v-text-field
                        v-model="disablePassword"
                        label="Пароль"
                        type="password"
                        autocomplete="current-password"
                        :error-messages="disableError ? [disableError] : []"
                        density="comfortable"
                    />
                </v-card-text>
                <v-card-actions>
                    <v-spacer />
                    <v-btn color="error" @click="confirmDisable">Отключить</v-btn>
                    <v-btn variant="text" @click="disableOpen = false">Отмена</v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>
    </v-card>
</template>

<style scoped>
.codes-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
}
.code-item {
    background: #f6f3ec;
    padding: 8px 12px;
    border-radius: 6px;
    text-align: center;
    font-size: 14px;
    letter-spacing: 0.06em;
}
</style>
