import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest';
import { axios, flushPromises } from 'app/test/vitest/helper';
import { useArrayData } from 'composables/useArrayData';
import { useRouter } from 'vue-router';
import * as vueRouter from 'vue-router';

describe('useArrayData', () => {
    const filter = '{"limit":10,"skip":0}';
    const params = { supplierFk: 2 };
    beforeEach(() => {
        vi.spyOn(useRouter(), 'replace');
        vi.spyOn(useRouter(), 'push');
    });

    afterEach(() => {
        vi.clearAllMocks();
    });

    it('should fetch and repalce url with new params', async () => {
        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] });

        const arrayData = useArrayData('ArrayData', { url: 'mockUrl' });

        arrayData.store.userParams = params;
        arrayData.fetch({});

        await flushPromises();
        const routerReplace = useRouter().replace.mock.calls[0][0];

        expect(axios.get.mock.calls[0][1].params).toEqual({
            filter,
            supplierFk: 2,
        });
        expect(routerReplace.path).toEqual('mockSection/list');
        expect(JSON.parse(routerReplace.query.params)).toEqual(
            expect.objectContaining(params)
        );
    });

    it('Should get data and send new URL without keeping parameters, if there is only one record', async () => {
        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }] });

        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} });

        arrayData.store.userParams = params;
        arrayData.fetch({});

        await flushPromises();
        const routerPush = useRouter().push.mock.calls[0][0];

        expect(axios.get.mock.calls[0][1].params).toEqual({
            filter,
            supplierFk: 2,
        });
        expect(routerPush.path).toEqual('mockName/1');
        expect(routerPush.query).toBeUndefined();
    });

    it('Should get data and send new URL keeping parameters, if you have more than one record', async () => {
        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }, { id: 2 }] });

        vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
            matched: [],
            query: {},
            params: {},
            meta: { moduleName: 'mockName' },
            path: 'mockName/1',
        });
        vi.spyOn(vueRouter, 'useRouter').mockReturnValue({
            push: vi.fn(),
            replace: vi.fn(),
            currentRoute: {
                value: {
                    params: {
                        id: 1,
                    },
                    meta: { moduleName: 'mockName' },
                    matched: [{ path: 'mockName/:id' }],
                },
            },
        });

        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} });

        arrayData.store.userParams = params;
        arrayData.fetch({});

        await flushPromises();
        const routerPush = useRouter().push.mock.calls[0][0];

        expect(axios.get.mock.calls[0][1].params).toEqual({
            filter,
            supplierFk: 2,
        });
        expect(routerPush.path).toEqual('mockName/');
        expect(routerPush.query.params).toBeDefined();
    });
});