import { describe, it, expect, vi } from 'vitest';
import { mount, flushPromises } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import { createVuetify } from 'vuetify';
import { createRouter, createMemoryHistory } from 'vue-router';
import LoginView from '../../resources/js/views/auth/LoginView.vue';
import { useAuthStore } from '../../resources/js/stores/auth';

// Smoke-тесты LoginView: монтируется внутри router-context, содержит
// все три ключевых элемента из v8_login.html секция #form-login —
// заголовок, кнопку «Войти», SSO Yandex 360.

const mountLoginView = async () => {
    const pinia = createPinia();
    setActivePinia(pinia);
    const router = createRouter({
        history: createMemoryHistory(),
        routes: [
            { path: '/login', name: 'login', component: LoginView },
            { path: '/register', name: 'register', component: { template: '<div>stub</div>' } },
            { path: '/forgot', name: 'forgot', component: { template: '<div>stub</div>' } },
        ],
    });
    await router.push('/login');
    await router.isReady();
    return mount(LoginView, {
        global: {
            plugins: [pinia, createVuetify(), router],
        },
    });
};

describe('LoginView.vue', () => {
    it('монтируется без ошибок', async () => {
        const wrapper = await mountLoginView();
        expect(wrapper.exists()).toBe(true);
    });

    it('содержит заголовок «Вход в Лидерру»', async () => {
        const wrapper = await mountLoginView();
        expect(wrapper.text()).toContain('Вход в Лидерру');
    });

    it('содержит кнопку «Войти» и Yandex 360 SSO', async () => {
        const wrapper = await mountLoginView();
        expect(wrapper.text()).toContain('Войти');
        expect(wrapper.text()).toContain('Yandex 360');
    });

    it('содержит поля email и пароль с правильным autocomplete', async () => {
        const wrapper = await mountLoginView();
        const emailInput = wrapper.find('input[type="email"]');
        expect(emailInput.exists()).toBe(true);
        expect(emailInput.attributes('autocomplete')).toBe('email');

        const passwordInput = wrapper.find('input[type="password"]');
        expect(passwordInput.exists()).toBe(true);
        expect(passwordInput.attributes('autocomplete')).toBe('current-password');
    });

    it('содержит ссылки на регистрацию и сброс пароля', async () => {
        const wrapper = await mountLoginView();
        const links = wrapper.findAll('a').map((a) => a.text());
        expect(links.some((t) => t.includes('Зарегистрируйтесь'))).toBe(true);
        expect(links.some((t) => t.includes('Забыли пароль'))).toBe(true);
    });

    it('показывает lockout-alert когда auth.lockoutSeconds установлен (rate-limit 429)', async () => {
        const wrapper = await mountLoginView();
        // По умолчанию alert не отображается.
        expect(wrapper.find('[data-testid="lockout-alert"]').exists()).toBe(false);

        const auth = useAuthStore();
        auth.lockoutSeconds = 600; // 10 минут
        await wrapper.vm.$nextTick();

        const alert = wrapper.find('[data-testid="lockout-alert"]');
        expect(alert.exists()).toBe(true);
        // 600 / 60 = 10 мин (округление вверх).
        expect(alert.text()).toContain('10 мин');
        expect(alert.text()).toContain('Слишком много попыток');
    });

    it('косяк 05: при email_not_confirmed уводит на /confirm-email и кладёт email в store', async () => {
        const pinia = createPinia();
        setActivePinia(pinia);
        const router = createRouter({
            history: createMemoryHistory(),
            routes: [
                { path: '/login', name: 'login', component: LoginView },
                { path: '/register', name: 'register', component: { template: '<div>stub</div>' } },
                { path: '/forgot', name: 'forgot', component: { template: '<div>stub</div>' } },
                { path: '/confirm-email', name: 'confirm-email', component: { template: '<div>confirm</div>' } },
            ],
        });
        await router.push('/login');
        await router.isReady();
        const wrapper = mount(LoginView, { global: { plugins: [pinia, createVuetify(), router] } });

        const auth = useAuthStore();
        auth.login = vi.fn().mockRejectedValue({ response: { data: { email_not_confirmed: true } } });

        await wrapper.find('input[type="email"]').setValue('unconfirmed@example.ru');
        await wrapper.find('input[type="password"]').setValue('password12');
        await wrapper.find('form').trigger('submit.prevent');
        await flushPromises();

        expect(router.currentRoute.value.path).toBe('/confirm-email');
        expect(auth.pendingEmail).toBe('unconfirmed@example.ru');
    });

    it('A1: SSO Yandex 360 — кнопка disabled до подключения Б-1', async () => {
        const wrapper = await mountLoginView();
        const ssoBtn = wrapper.findAll('button').find((b) => b.text().includes('Yandex 360'));
        expect(ssoBtn).toBeDefined();
        expect(ssoBtn!.classes()).toContain('v-btn--disabled');
    });

    it('A9: переключатель видимости пароля имеет accessible-name и работает', async () => {
        const wrapper = await mountLoginView();
        const toggle = wrapper.find('[aria-label="Показать пароль"]');
        expect(toggle.exists()).toBe(true);
        expect(toggle.attributes('role')).toBe('button');
        await toggle.trigger('click');
        expect(wrapper.find('[aria-label="Скрыть пароль"]').exists()).toBe(true);

        // keyboard activation (Enter) — toggle back
        await wrapper.find('[aria-label="Скрыть пароль"]').trigger('keydown', { key: 'Enter' });
        expect(wrapper.find('[aria-label="Показать пароль"]').exists()).toBe(true);
    });
});
