<script setup lang="ts">
/**
 * ChangePasswordCard — смена пароля (UI-аудит 21.06.2026, Security).
 *
 * Реальные данные: дата последней смены — GET /api/account/security;
 * смена — POST /api/account/change-password (текущий + новый + подтверждение).
 * Заменяет прежнюю статичную заглушку (захардкоженная дата + мёртвая кнопка).
 */
import { onMounted, ref } from 'vue';
import { changePassword, getAccountSecurity } from '../../../api/account';
import axios from 'axios';

const lastChangeAt = ref<string | null>(null);
const dialogOpen = ref(false);
const currentPassword = ref('');
const newPassword = ref('');
const confirmPassword = ref('');
const saving = ref(false);
const errorMessage = ref<string | null>(null);
const toastOpen = ref(false);
const showCurrent = ref(false);
const showNew = ref(false);

function formatDate(iso: string | null): string {
    if (!iso) return 'не менялся';
    const d = new Date(iso);
    return d.toLocaleDateString('ru-RU', { day: '2-digit', month: '2-digit', year: 'numeric' });
}

async function loadSecurity(): Promise<void> {
    try {
        const data = await getAccountSecurity();
        lastChangeAt.value = data.last_password_change_at;
    } catch {
        lastChangeAt.value = null;
    }
}

function openDialog(): void {
    currentPassword.value = '';
    newPassword.value = '';
    confirmPassword.value = '';
    errorMessage.value = null;
    dialogOpen.value = true;
}

async function submit(): Promise<void> {
    if (saving.value) return;
    saving.value = true;
    errorMessage.value = null;
    try {
        lastChangeAt.value = await changePassword({
            current_password: currentPassword.value,
            password: newPassword.value,
            password_confirmation: confirmPassword.value,
        });
        dialogOpen.value = false;
        toastOpen.value = true;
    } catch (err) {
        if (axios.isAxiosError(err) && err.response?.status === 422) {
            const errors = (err.response.data as { errors?: Record<string, string[]> })?.errors ?? {};
            errorMessage.value =
                errors.current_password?.[0] ?? errors.password?.[0] ?? 'Проверьте введённые данные.';
        } else {
            errorMessage.value = 'Не удалось сменить пароль. Попробуйте позже.';
        }
    } finally {
        saving.value = false;
    }
}

onMounted(loadSecurity);
</script>

<template>
    <v-card variant="outlined" class="pa-4 mb-4">
        <h3 class="text-subtitle-2 mb-3">Пароль</h3>
        <p class="text-body-2 text-medium-emphasis mb-3">
            Последняя смена: {{ formatDate(lastChangeAt) }}
        </p>
        <v-btn
            variant="outlined"
            size="small"
            prepend-icon="mdi-lock-reset"
            data-testid="change-password-open"
            @click="openDialog"
        >
            Сменить пароль
        </v-btn>

        <v-dialog v-model="dialogOpen" max-width="440">
            <v-card class="pa-2">
                <v-card-title class="text-subtitle-1">Смена пароля</v-card-title>
                <v-card-text>
                    <v-alert
                        v-if="errorMessage"
                        type="error"
                        variant="tonal"
                        density="compact"
                        class="mb-3"
                        data-testid="change-password-error"
                    >
                        {{ errorMessage }}
                    </v-alert>
                    <v-text-field
                        v-model="currentPassword"
                        :type="showCurrent ? 'text' : 'password'"
                        label="Текущий пароль"
                        variant="outlined"
                        density="comfortable"
                        autocomplete="current-password"
                        :append-inner-icon="showCurrent ? 'mdi-eye-off' : 'mdi-eye'"
                        data-testid="change-password-current"
                        class="mb-2"
                        @click:append-inner="showCurrent = !showCurrent"
                    />
                    <v-text-field
                        v-model="newPassword"
                        :type="showNew ? 'text' : 'password'"
                        label="Новый пароль"
                        variant="outlined"
                        density="comfortable"
                        autocomplete="new-password"
                        persistent-hint
                        hint="Не короче 10 символов"
                        :append-inner-icon="showNew ? 'mdi-eye-off' : 'mdi-eye'"
                        data-testid="change-password-new"
                        class="mb-2"
                        @click:append-inner="showNew = !showNew"
                    />
                    <v-text-field
                        v-model="confirmPassword"
                        :type="showNew ? 'text' : 'password'"
                        label="Повторите новый пароль"
                        variant="outlined"
                        density="comfortable"
                        autocomplete="new-password"
                        data-testid="change-password-confirm"
                    />
                </v-card-text>
                <v-card-actions class="px-4 pb-3">
                    <v-spacer />
                    <v-btn variant="text" :disabled="saving" @click="dialogOpen = false">Отмена</v-btn>
                    <v-btn
                        color="primary"
                        variant="flat"
                        :loading="saving"
                        data-testid="change-password-submit"
                        @click="submit"
                    >
                        Сменить
                    </v-btn>
                </v-card-actions>
            </v-card>
        </v-dialog>

        <v-snackbar v-model="toastOpen" :timeout="3000" location="bottom right" data-testid="change-password-toast">
            Пароль изменён.
        </v-snackbar>
    </v-card>
</template>
