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

vi.mock('axios');

vi.mock('../../resources/js/api/client', () => ({
    apiClient: {
        get: vi.fn(),
        post: vi.fn().mockResolvedValue({ data: {} }),
        patch: vi.fn().mockResolvedValue({ data: {} }),
    },
    ensureCsrfCookie: vi.fn().mockResolvedValue(undefined),
    extractErrorMessage: vi.fn(() => 'Произошла ошибка.'),
}));

// Косяк 04 / вариант C: управляем реквизитами по-тестово.
vi.mock('../../resources/js/api/requisites', () => ({
    getRequisites: vi.fn(),
    updateRequisites: vi.fn(),
}));

import { getRequisites, updateRequisites } from '../../resources/js/api/requisites';
import NewProjectDialog from '../../resources/js/views/projects/NewProjectDialog.vue';

const factory = () =>
    mount(NewProjectDialog, {
        props: { modelValue: true, mode: 'create' as const },
        global: {
            plugins: [createVuetify()],
            stubs: {
                VDialog: {
                    template: '<div class="dialog-stub" v-if="modelValue"><slot /></div>',
                    props: ['modelValue'],
                },
            },
        },
    });

const lightComplete = {
    subject_type: 'individual',
    contact_name: 'Иван',
    contact_phone: '+79161234567',
    inn: null,
};

beforeEach(() => {
    setActivePinia(createPinia());
    vi.clearAllMocks();
    (updateRequisites as unknown as Mock).mockResolvedValue({});
});

describe('NewProjectDialog — косяк 04 / вариант C: реквизиты первым шагом', () => {
    it('новый клиент без реквизитов видит шаг реквизитов, а не пустую форму проекта', async () => {
        (getRequisites as unknown as Mock).mockResolvedValue(null);
        const w = factory();
        await flushPromises();

        expect(w.find('[data-testid="req-step"]').exists()).toBe(true);
        expect(w.find('[data-testid="req-contact-phone"]').exists()).toBe(true);
        // форма проекта (вкладки источника) на шаге 1 ещё не показана
        expect(w.find('[data-testid="np-lead-banner"]').exists()).toBe(false);
    });

    it('клиент с заполненными реквизитами сразу попадает на форму проекта', async () => {
        (getRequisites as unknown as Mock).mockResolvedValue(lightComplete);
        const w = factory();
        await flushPromises();

        expect(w.find('[data-testid="req-step"]').exists()).toBe(false);
        expect(w.find('[data-testid="np-lead-banner"]').exists()).toBe(true);
    });

    it('сохранение реквизитов переводит на шаг проекта (без ухода со страницы)', async () => {
        (getRequisites as unknown as Mock).mockResolvedValue(null);
        const w = factory();
        await flushPromises();
        expect(w.find('[data-testid="req-step"]').exists()).toBe(true);

        const vm = w.vm as unknown as {
            reqForm: { subject_type: string; contact_name: string; contact_phone: string; inn: string };
            saveRequisites: () => Promise<void>;
        };
        vm.reqForm.subject_type = 'individual';
        vm.reqForm.contact_name = 'Иван Петров';
        vm.reqForm.contact_phone = '+7 916 123 45 67';
        await vm.saveRequisites();
        await flushPromises();

        expect(updateRequisites).toHaveBeenCalledTimes(1);
        expect(w.find('[data-testid="req-step"]').exists()).toBe(false);
        expect(w.find('[data-testid="np-lead-banner"]').exists()).toBe(true);
    });

    it('ошибка валидации реквизитов остаётся на шаге 1 и не теряет форму проекта', async () => {
        (getRequisites as unknown as Mock).mockResolvedValue(null);
        (updateRequisites as unknown as Mock).mockRejectedValue({
            response: { status: 422, data: { errors: { contact_phone: ['Некорректный телефон.'] } } },
        });
        const w = factory();
        await flushPromises();

        const vm = w.vm as unknown as {
            reqForm: { subject_type: string; contact_name: string; contact_phone: string; inn: string };
            saveRequisites: () => Promise<void>;
        };
        vm.reqForm.subject_type = 'individual';
        vm.reqForm.contact_name = 'Иван';
        vm.reqForm.contact_phone = 'мусор';
        await vm.saveRequisites();
        await flushPromises();

        // остались на шаге 1, ошибка показана
        expect(w.find('[data-testid="req-step"]').exists()).toBe(true);
        expect(w.text()).toContain('Некорректный телефон');
    });
});
