import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest';
import { createWrapper, axios } from 'app/test/vitest/helper';
import TicketAdvance from 'pages/Ticket/TicketAdvance.vue';
import { Notify } from 'quasar';
import { nextTick } from 'vue';

describe('TicketAdvance', () => {
    let wrapper;
    let vm;

    beforeAll(() => {
        vi.spyOn(axios, 'get').mockImplementation(() => ({ data: [] }));
        wrapper = createWrapper(TicketAdvance);
        vm = wrapper.vm;
        vi.spyOn(vm.vnTableRef, 'reload').mockImplementation(() => vi.fn());
        vm.vnTableRef.value = { params: {} };
    });
    beforeEach(() => {
        Notify.create = vi.fn();
    });
    afterEach(() => {
        vi.clearAllMocks();
    });

    describe('requestComponentUpdate()', () => {
        const mockTicket = {
            futureId: 1,
            futureClientFk: 1,
            nickname: 'test',
            futureAddressFk: 1,
            futureAgencyModeFk: 1,
            futureWarehouseFk: 1,
            futureCompanyFk: 1,
            landed: '2023-01-02',
            zoneFk: 1,
        };
        const mockParams = {
            clientFk: 1,
            nickname: 'test',
            agencyModeFk: 1,
            addressFk: 1,
            zoneFk: 1,
            warehouseFk: 1,
            companyFk: 1,
            landed: '2023-01-02',
            shipped: '2023-01-01',
            isDeleted: false,
            isWithoutNegatives: false,
            newTicket: undefined,
            keepPrice: true,
        };
        const queryResult = 'tickets/1/componentUpdate';

        it('should return query and params when ticket has no landed', async () => {
            vm.vnTableRef.params.dateToAdvance = '2023-01-01';
            await nextTick();

            const mockLanded = { landed: '2023-01-02', zoneFk: 1 };
            vi.spyOn(vm, 'getLanded').mockResolvedValue(mockLanded);

            const { query, params } = await vm.requestComponentUpdate(mockTicket, false);

            expect(query).toBe(queryResult);
            expect(params).toEqual(mockParams);
        });

        it('should return query and params when ticket has landed', async () => {
            const { query, params } = await vm.requestComponentUpdate(mockTicket, false);

            expect(query).toBe(queryResult);
            expect(params).toEqual(mockParams);
        });
    });

    describe('moveTicketsAdvance()', () => {
        it('should move tickets and notify success', async () => {
            const tickets = [
                {
                    id: 1,
                    futureId: 2,
                    futureShipped: '2023-01-01',
                    shipped: '2023-01-02',
                    workerFk: 1,
                },
                {
                    id: 2,
                    futureId: 3,
                    futureShipped: '2023-01-01',
                    shipped: '2023-01-02',
                    workerFk: 1,
                },
            ];
            vm.selectedTickets = tickets;
            vi.spyOn(axios, 'post').mockResolvedValue({});
            await vm.moveTicketsAdvance();

            expect(axios.post).toHaveBeenCalledOnce('Tickets/merge', {
                tickets: [
                    {
                        originId: 2,
                        destinationId: 1,
                        originShipped: '2023-01-01',
                        destinationShipped: '2023-01-02',
                        workerFk: 1,
                    },
                    {
                        originId: 3,
                        destinationId: 2,
                        originShipped: '2023-01-01',
                        destinationShipped: '2023-01-02',
                        workerFk: 1,
                    },
                ],
            });
            expect(vm.vnTableRef.reload).toHaveBeenCalled();
            expect(Notify.create).toHaveBeenCalled();
            expect(vm.selectedTickets).toEqual([]);
        });
    });
});