import { describe, it, expect, beforeEach, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import { createVuetify } from 'vuetify';

vi.mock('../../resources/js/api/auth', () => ({
    updateProfile: vi.fn(),
}));

vi.mock('../../resources/js/api/client', () => ({
    apiClient: {},
    ensureCsrfCookie: vi.fn(),
    extractValidationErrors: vi.fn(() => null),
    extractErrorMessage: vi.fn((_e, fallback) => fallback ?? 'Произошла ошибка.'),
    extractRateLimitRetry: vi.fn(() => null),
}));

import * as authApi from '../../resources/js/api/auth';
import ProfileTab from '../../resources/js/views/settings/ProfileTab.vue';
import { useAuthStore } from '../../resources/js/stores/auth';
import type { AuthUser } from '../../resources/js/api/auth';

const vuetify = createVuetify();

const mockUser: AuthUser = {
    id: 1,
    email: 'ivan@example.ru',
    first_name: 'Иван',
    last_name: 'Петров',
    phone: '+7 916 000-00-00',
    timezone: 'Europe/Moscow',
    tenant_id: 1,
    totp_enabled: false,
    last_login_at: null,
};

const factory = (user: AuthUser | null = mockUser) => {
    setActivePinia(createPinia());
    const auth = useAuthStore();
    auth.user = user;
    return mount(ProfileTab, { global: { plugins: [vuetify] } });
};

describe('ProfileTab.vue', () => {
    beforeEach(() => {
        vi.clearAllMocks();
    });

    it('подставляет имя/фамилию/телефон/тайм-зону из auth-store', () => {
        const wrapper = factory();
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const vm = wrapper.vm as any;
        expect(vm.firstName).toBe('Иван');
        expect(vm.lastName).toBe('Петров');
        expect(vm.phone).toBe('+7 916 000-00-00');
        expect(vm.timezone).toBe('Europe/Moscow');
    });

    it('save() вызывает updateProfile с payload и показывает успех', async () => {
        (authApi.updateProfile as ReturnType<typeof vi.fn>).mockResolvedValue({
            ...mockUser,
            first_name: 'Пётр',
        });
        const wrapper = factory();
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const vm = wrapper.vm as any;
        vm.firstName = 'Пётр';
        await vm.save();
        expect(authApi.updateProfile).toHaveBeenCalledWith({
            first_name: 'Пётр',
            last_name: 'Петров',
            phone: '+7 916 000-00-00',
            timezone: 'Europe/Moscow',
        });
        expect(vm.saveSuccess).toBe(true);
        expect(vm.saveError).toBe(null);
    });

    it('save() с пустым phone отправляет null', async () => {
        (authApi.updateProfile as ReturnType<typeof vi.fn>).mockResolvedValue(mockUser);
        const wrapper = factory();
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const vm = wrapper.vm as any;
        vm.phone = '   ';
        await vm.save();
        expect(authApi.updateProfile).toHaveBeenCalledWith(expect.objectContaining({ phone: null }));
    });

    it('save() показывает ошибку при reject', async () => {
        (authApi.updateProfile as ReturnType<typeof vi.fn>).mockRejectedValue(new Error('boom'));
        const wrapper = factory();
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const vm = wrapper.vm as any;
        await vm.save();
        expect(vm.saveError).toBe('Не удалось сохранить профиль.');
        expect(vm.saveSuccess).toBe(false);
        expect(vm.saving).toBe(false);
    });

    it('resetForm() возвращает поля к значениям из store', async () => {
        const wrapper = factory();
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const vm = wrapper.vm as any;
        vm.firstName = 'Изменено';
        vm.resetForm();
        expect(vm.firstName).toBe('Иван');
    });
});
