import { axios, createWrapper } from 'app/test/vitest/helper';
import WagonTypeCreate from 'pages/Wagon/Type/WagonTypeCreate.vue';
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';

describe('WagonTypeCreate', () => {
    let vmCreate, vmEdit;
    const entityId = 1;

    beforeAll(() => {
        vmEdit = createWrapper(WagonTypeCreate, {propsData: {
                id: entityId,
            }}).vm;
        vmCreate = createWrapper(WagonTypeCreate).vm;
        vmEdit.wagonConfig = vmCreate.wagonConfig = {maxTrays: 2 ,minHeightBetweenTrays: 50, maxWagonHeight: 200 };
        vmEdit.wagonTypeColors = vmCreate.wagonTypeColors = [{id: 1, color:'white', rgb:'#000000'}];
    });

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

    describe('addTray()', () => {
        it('should throw message if there are uncomplete trays', async () => {
            vi.spyOn(vmEdit.quasar, 'notify');
            vmEdit.wagon = [{
                id: 1,
                position: null,
                color: vmEdit.wagonTypeColors[0]
            }];

            await vmEdit.addTray();

            expect(vmEdit.quasar.notify).toHaveBeenCalledWith(
                expect.objectContaining({
                    type: 'warning',
                })
            );
        });

        it('should create a new tray if the limit has not been reached', async () => {
            vmEdit.wagon = [{
                id: 1,
                position: 0,
                color: vmEdit.wagonTypeColors[0]
            }];

            await vmEdit.addTray();
            expect(vmEdit.wagon.length).toEqual(2);
        });

        it('should throw message if there are uncomplete trays', async () => {
            vi.spyOn(vmEdit.quasar, 'notify');
            vmEdit.wagon = [{
                id: 1,
                position: 0,
                color: vmEdit.wagonTypeColors[0]
            },{
                id: 2,
                position: 50,
                color: vmEdit.wagonTypeColors[0]
            }];

            await vmEdit.addTray();

            expect(vmEdit.quasar.notify).toHaveBeenCalledWith(
                expect.objectContaining({
                    type: 'warning',
                })
            );
        });
    });

    describe('deleteTray() reorderIds()', () => {
        it('should delete a tray and reorder the ids', async () => {
            const trayToDelete = {
                id: 1,
                position: 0,
                color: vmEdit.wagonTypeColors[0]
            };
            const trayMaintained = {
                id: 2,
                position: 50,
                color: vmEdit.wagonTypeColors[0]
            };
            vmEdit.wagon = [trayToDelete,trayMaintained];

            await vmEdit.deleteTray(trayToDelete);

            expect(vmEdit.wagon.length).toEqual(1);
            expect(vmEdit.wagon[0].id).toEqual(0);
            expect(vmEdit.wagon[0].position).toEqual(50);

        });
    });

    describe('onSubmit()', () => {
        it('should make a patch to editWagonType if have id', async () => {
            vi.spyOn(axios, 'patch').mockResolvedValue({ data: true });
            const wagon = {
                id: entityId,
                name: "Mock name",
                divisible: true,
                trays: [{
                    id: 1,
                    position: 0,
                    color: vmEdit.wagonTypeColors[0]
                }]
            }
            vmEdit.name = wagon.name;
            vmEdit.divisible = wagon.divisible;
            vmEdit.wagon = wagon.trays;

            await vmEdit.onSubmit();

            expect(axios.patch).toHaveBeenCalledWith(
                `WagonTypes/editWagonType`, wagon
            );
        });

        it('should make a patch to createtWagonType if not have id', async () => {
            vi.spyOn(axios, 'patch').mockResolvedValue({ data: true });
            const wagon = {
                name: "Mock name",
                divisible: true,
                trays: [{
                    id: 1,
                    position: 0,
                    color: vmCreate.wagonTypeColors[0]
                }]
            }
            vmCreate.name = wagon.name;
            vmCreate.divisible = wagon.divisible;
            vmCreate.wagon = wagon.trays;

            await vmCreate.onSubmit();

            expect(axios.patch).toHaveBeenCalledWith(
                `WagonTypes/createWagonType`, wagon
            );
        });
    });

    describe('onReset()', () => {
        it('should reset if have id', async () => {
            vmEdit.name = 'Changed name';
            vmEdit.divisible = false;
            vmEdit.wagon = [];
            vmEdit.originalData = {
                name: 'Original name',
                divisible: true,
                trays: [{
                    id: 1,
                    position: 0,
                    color: vmEdit.wagonTypeColors[0]
                },{
                    id: 2,
                    position: 50,
                    color: vmEdit.wagonTypeColors[0]
                }]
            };

            vmEdit.onReset();

            expect(vmEdit.name).toEqual(vmEdit.originalData.name);
            expect(vmEdit.divisible).toEqual(vmEdit.originalData.divisible);
            expect(vmEdit.wagon).toEqual(vmEdit.originalData.trays);
        });

        it('should reset if not have id', async () => {
            vmCreate.name = 'Changed name';
            vmCreate.divisible = false;
            vmCreate.wagon = [];

            vmCreate.onReset();

            expect(vmCreate.name).toEqual(null);
            expect(vmCreate.divisible).toEqual(false);
            expect(vmCreate.wagon.length).toEqual(1);
        });
    });

    describe('onPositionBlur()', () => {
        it('should set position null if position is negative', async () => {
            const negativeTray = {
                id: 1,
                position: -1,
                color: vmCreate.wagonTypeColors[0]
            };

            vmCreate.onPositionBlur(negativeTray);

            expect(negativeTray.position).toEqual(null);
        });

        it('should set position and reorder array', async () => {
            const trays = [{
                id: 0,
                position: 100,
                color: vmCreate.wagonTypeColors[0]
            },{
                id: 1,
                position: 0,
                color: vmCreate.wagonTypeColors[0]
            }];
            const newTray = {
                id: 2,
                position: 50,
                color: vmCreate.wagonTypeColors[0]
            };
            trays.push(newTray);
            vmCreate.wagon = trays;

            vmCreate.onPositionBlur(newTray);

            expect(vmCreate.wagon[0].position).toEqual(100);
            expect(vmCreate.wagon[1].position).toEqual(50);
            expect(vmCreate.wagon[2].position).toEqual(0);
        });

        it('should throw message if not have min height between trays and should set new adequate positions', async () => {
            vi.spyOn(vmCreate.quasar, 'notify');
            const trays = [{
                id: 0,
                position: 0,
                color: vmCreate.wagonTypeColors[0]
            }];
            const newTray = {
                id: 1,
                position: 20,
                color: vmCreate.wagonTypeColors[0]
            };
            trays.push(newTray);
            vmCreate.wagon = trays;

            vmCreate.onPositionBlur(newTray);

            expect(vmCreate.wagon[0].position).toEqual(50);
            expect(vmCreate.wagon[1].position).toEqual(0);
            expect(vmCreate.quasar.notify).toHaveBeenCalledWith(
                expect.objectContaining({
                    type: 'warning',
                })
            );
        });

        it('should throw message if max height has been exceed', async () => {
            vi.spyOn(vmCreate.quasar, 'notify');
            const trays = [{
                id: 0,
                position: 0,
                color: vmCreate.wagonTypeColors[0]
            }];
            const newTray = {
                id: 1,
                position: 210,
                color: vmCreate.wagonTypeColors[0]
            };
            trays.push(newTray);
            vmCreate.wagon = trays;

            vmCreate.onPositionBlur(newTray);

            expect(vmCreate.wagon.length).toEqual(1);
            expect(vmCreate.quasar.notify).toHaveBeenCalledWith(
                expect.objectContaining({
                    type: 'warning',
                })
            );
        });
    });
});
