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

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

// Косяк 04 / вариант C: реквизиты light-complete → диалог сразу на шаге проекта.
vi.mock('../../resources/js/api/requisites', () => ({
    getRequisites: vi.fn().mockResolvedValue({
        subject_type: 'individual',
        contact_name: 'Иван',
        contact_phone: '+79161234567',
        inn: null,
    }),
    updateRequisites: vi.fn().mockResolvedValue({}),
}));

import { apiClient } from '../../resources/js/api/client';
import NewProjectDialog from '../../resources/js/views/projects/NewProjectDialog.vue';

// VDialog teleport-стаб (как в NewProjectDialog.spec.ts): рендерит слот инлайн.
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'],
                },
            },
        },
    });

beforeEach(() => {
    setActivePinia(createPinia());
    vi.clearAllMocks();
});

describe('NewProjectDialog — required region gate + «Вся РФ» (Plan 4 Task 4)', () => {
    it('blocks submit when no region chosen and shows error', async () => {
        const w = factory();
        await flushPromises();

        await w.find('[data-testid="submit-btn"]').trigger('click');
        await flushPromises();

        expect(apiClient.post).not.toHaveBeenCalled();
        expect(w.text()).toContain('Выберите регион');
    });

    it('косяк 03: «Вся РФ» одной галочкой подтверждает и сабмитит regions=[]', async () => {
        const w = factory();
        await flushPromises();

        (w.vm as unknown as { chooseVsyaRf: () => void }).chooseVsyaRf();
        await w.vm.$nextTick();
        // Одношаговое подтверждение: галочка сразу подтверждает, без отдельной кнопки.
        expect((w.vm as unknown as { vsyaRfConfirmed: boolean }).vsyaRfConfirmed).toBe(true);
        expect(w.text()).toContain('по всей России');

        const vm = w.vm as unknown as { form: { name: string; signal_identifier: string } };
        vm.form.name = 'Проект';
        vm.form.signal_identifier = 'okna-konkurent.ru';

        await w.find('[data-testid="submit-btn"]').trigger('click');
        await flushPromises();

        expect(apiClient.post).toHaveBeenCalledTimes(1);
        const payload = (apiClient.post as unknown as { mock: { calls: unknown[][] } }).mock.calls[0][1] as {
            regions: number[];
        };
        expect(payload.regions).toEqual([]);
    });

    it('косяк 03: галочка «Вся РФ» сразу снимает зависшую ошибку регионов', async () => {
        const w = factory();
        await flushPromises();

        // сабмит с пустыми регионами → ошибка «Выберите регион…»
        await w.find('[data-testid="submit-btn"]').trigger('click');
        await flushPromises();
        expect(w.text()).toContain('Выберите регион');

        // ставим «Вся РФ» → ошибка исчезает сразу, без отдельного подтверждения
        (w.vm as unknown as { chooseVsyaRf: () => void }).chooseVsyaRf();
        await w.vm.$nextTick();
        expect(w.text()).not.toContain('Выберите регион');
    });

    it('region autocomplete has closable-chips so a single region can be removed', async () => {
        const w = factory();
        await flushPromises();

        const ac = w.findComponent('[data-testid="regions-autocomplete"]');
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        expect((ac as VueWrapper<any>).props('closableChips')).toBe(true);
    });

    it('picking subjects after «Вся РФ» clears the confirmation (mutual exclusion)', async () => {
        const w = factory();
        await flushPromises();

        const vm = w.vm as unknown as {
            chooseVsyaRf: () => void;
            confirmVsyaRf: () => void;
            onRegionsChange: (codes: number[]) => void;
            vsyaRfConfirmed: boolean;
            form: { name: string; signal_identifier: string };
        };
        vm.chooseVsyaRf();
        vm.confirmVsyaRf();
        await w.vm.$nextTick();
        expect(vm.vsyaRfConfirmed).toBe(true);

        vm.onRegionsChange([77]);
        await w.vm.$nextTick();
        expect(vm.vsyaRfConfirmed).toBe(false);

        vm.form.name = 'Проект';
        vm.form.signal_identifier = 'okna-konkurent.ru';

        await w.find('[data-testid="submit-btn"]').trigger('click');
        await flushPromises();

        const payload = (apiClient.post as unknown as { mock: { calls: unknown[][] } }).mock.calls[0][1] as {
            regions: number[];
        };
        expect(payload.regions).toEqual([77]);
    });
});
