import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createPinia, setActivePinia } from 'pinia';
import { useLeadStatusesStore } from '../../resources/js/stores/leadStatuses';
import { LEAD_STATUSES } from '../../resources/js/composables/leadStatuses';

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

const api = await import('../../resources/js/api/leadStatuses');

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

describe('useLeadStatusesStore', () => {
    it('initial state — snapshot из LEAD_STATUSES', () => {
        const store = useLeadStatusesStore();
        expect(store.statuses).toHaveLength(LEAD_STATUSES.length);
        expect(store.loaded).toBe(false);
        expect(store.fetchError).toBe(false);
    });

    it('findBySlug возвращает статус из snapshot до load (won)', () => {
        const store = useLeadStatusesStore();
        const found = store.findBySlug('won');
        expect(found).not.toBeNull();
        expect(found!.nameRu).toBe('Сделка');
    });

    it('findBySlug возвращает null для неизвестного slug', () => {
        const store = useLeadStatusesStore();
        expect(store.findBySlug('not_a_real_slug')).toBeNull();
    });

    it('load() success — replace на API-данные + loaded=true', async () => {
        vi.mocked(api.listLeadStatuses).mockResolvedValueOnce([
            {
                slug: 'custom',
                name_ru: 'Кастомный',
                is_system: false,
                sort_order: 100,
                color_hex: '#ABCDEF',
                description: null,
            },
        ]);

        const store = useLeadStatusesStore();
        await store.load();

        expect(store.loaded).toBe(true);
        expect(store.statuses).toHaveLength(1);
        expect(store.statuses[0].slug).toBe('custom');
        expect(store.statuses[0].nameRu).toBe('Кастомный');
        expect(store.findBySlug('custom')!.colorHex).toBe('#ABCDEF');
    });

    it('load() reject — fetchError=true + snapshot остаётся', async () => {
        vi.mocked(api.listLeadStatuses).mockRejectedValueOnce(new Error('500'));

        const store = useLeadStatusesStore();
        await store.load();

        expect(store.fetchError).toBe(true);
        expect(store.loaded).toBe(false);
        expect(store.statuses).toHaveLength(LEAD_STATUSES.length);
    });

    it('load() идемпотентен — повторный вызов не делает второй request', async () => {
        vi.mocked(api.listLeadStatuses).mockResolvedValue([
            {
                slug: 'x',
                name_ru: 'X',
                is_system: false,
                sort_order: 1,
                color_hex: '#000000',
                description: null,
            },
        ]);

        const store = useLeadStatusesStore();
        await store.load();
        await store.load();

        expect(api.listLeadStatuses).toHaveBeenCalledTimes(1);
    });

    it('load(force=true) делает повторный fetch', async () => {
        vi.mocked(api.listLeadStatuses).mockResolvedValue([
            {
                slug: 'x',
                name_ru: 'X',
                is_system: false,
                sort_order: 1,
                color_hex: '#000000',
                description: null,
            },
        ]);

        const store = useLeadStatusesStore();
        await store.load();
        await store.load(true);

        expect(api.listLeadStatuses).toHaveBeenCalledTimes(2);
    });
});
