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

vi.mock('../../resources/js/api/imports', async (importOriginal) => {
    const orig = await importOriginal<typeof import('../../resources/js/api/imports')>();
    return {
        ...orig,
        resolveUnknownStatuses: vi.fn(),
    };
});

const importsApi = await import('../../resources/js/api/imports');
const UnknownStatusesDialog = (await import('../../resources/js/components/import/UnknownStatusesDialog.vue')).default;

// VDialog в JSDOM не рендерит через teleport — стаб делает <slot/> доступным
// для wrapper.text() / find(). Паттерн из EditProjectDialog.spec.ts.
function mountDialog() {
    return mount(UnknownStatusesDialog, {
        props: {
            modelValue: true,
            statuses: [
                { id: 1, status_ru: 'Архив', occurrences: 3 },
                { id: 2, status_ru: 'Спам', occurrences: 1 },
            ],
        },
        global: {
            plugins: [createVuetify()],
            stubs: {
                VDialog: {
                    template: '<div class="dialog-stub" v-if="modelValue"><slot /></div>',
                    props: ['modelValue'],
                },
            },
        },
    });
}

describe('UnknownStatusesDialog', () => {
    beforeEach(() => {
        vi.clearAllMocks();
        vi.mocked(importsApi.resolveUnknownStatuses).mockResolvedValue(undefined);
    });

    it('рендерит строку на каждый неизвестный статус', async () => {
        const wrapper = mountDialog();
        await flushPromises();
        expect(wrapper.text()).toContain('Архив');
        expect(wrapper.text()).toContain('Спам');
        wrapper.unmount();
    });

    it('кнопка сохранения заблокирована пока не выбраны все маппинги', async () => {
        const wrapper = mountDialog();
        await flushPromises();
        const saveBtn = wrapper.find('[data-test="save-mappings"]');
        expect(saveBtn.exists()).toBe(true);
        expect(saveBtn.attributes('disabled')).toBeDefined();
        wrapper.unmount();
    });

    it('сохраняет маппинги и эмитит resolved', async () => {
        const spy = vi.mocked(importsApi.resolveUnknownStatuses);
        const wrapper = mountDialog();
        await flushPromises();

        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const vm = wrapper.vm as any;
        vm.selection['Архив'] = 'lost';
        vm.selection['Спам'] = 'lost';
        await flushPromises();
        await vm.save();
        await flushPromises();

        expect(spy).toHaveBeenCalledWith([
            { status_ru: 'Архив', slug: 'lost' },
            { status_ru: 'Спам', slug: 'lost' },
        ]);
        expect(wrapper.emitted('resolved')).toBeTruthy();
        wrapper.unmount();
    });
});
