// Components
import licensePlateLookup from '@/layouts/license-plate-lookup/license-plate-lookup.vue';

// Supporting Files
import baseMixin from '@/mixins/base-mixin';
import settleAllPromises from '@/helpers/layout-helper.js';
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { useMainStore } from '@/store';
import navigationScenarios from '@/router/router-constants/navigation-scenarios';

jest.mock('@/helpers/damage-helper', () => ({
    isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
    getDamageString: jest.fn()
}));

// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => jest.fn());

// Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({
    fetchCmsContentForPage: jest.fn()
}));

/** @ignore */
function setupMocks({
    lookupVinByPlateResponse,
    partsOrQuestions = [],
    carId = 'C0000',
    vinLookupResponseError = null,
    route = null
}) {
    useMainStore().lookupVinByPlate = jest.fn().mockImplementation(() => Promise.resolve({
        data: lookupVinByPlateResponse || {
            vin: 'TEST_VIN',
            vehicle: {
                carId: 'CARID',
                canSafeliteService: true
            }
        },
        error: vinLookupResponseError
    }));

    useMainStore().getPartsOrQuestions = jest.fn().mockImplementation(() => Promise.resolve({
        data: {
            partsOrQuestions
        }
    }));

    const wrapper = shallowMount(
        licensePlateLookup,
        getMountOptions({
            route: route || undefined,
            router: {
                navigate: jest.fn()
            },
            mainStore: {
                order: {
                    vehicle: {
                        carId,
                        registration: {
                            licensePlate: 'TESTPLATE',
                            zipCode: '12345'
                        }
                    }
                }
            }

        })
    );

    settleAllPromises.mockImplementation(() => Promise.resolve({}));

    wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
    wrapper.vm.setCmsContent = jest.fn();
    wrapper.vm.$router.navigateWithSpinner = jest.fn();
    wrapper.vm.navigateBack = baseMixin.methods.navigateBack;
    wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
    wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
    wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();

    return { wrapper };
}

describe('license-plate-lookup.vue', () => {
    describe('page level alerts', () => {
        test('If license plate matches a different vehicle, display MatchedDifferentVehicleAlert', async () => {
            // Arrange
            const mockRegistrationLicensePlate = {
                licensePlate: 'UTN990'
            };

            const { wrapper } = setupMocks({});

            useMainStore().order.vehicle.carId = 'TESTCARID';

            await wrapper.setData({
                licensePlate: mockRegistrationLicensePlate
            });

            // Act
            await wrapper.vm.forwardButtonAction();

            // Assert
            expect(wrapper.findComponent({ ref: 'alertMatchedDifferentVehicle' }).isVisible()).toBe(true);
        });

        test('If license plate matches two identical YMM vehicles, display alertMatchedTwoIdenticalYMMVehicle', async () => {
            // Arrange
            const mockRegistrationLicensePlate = {
                licensePlate: 'UTN990'
            };

            const { wrapper } = setupMocks({});

            useMainStore().order.vehicle.carId = 'TESTCARID';

            await wrapper.setData({
                licensePlate: mockRegistrationLicensePlate,
                isTwoIdenticalYMMVehicleFound: true
            });

            // Act
            await wrapper.vm.forwardButtonAction();

            // Assert
            expect(wrapper.findComponent({ ref: 'alertMatchedTwoIdenticalYMMVehicle' }).isVisible()).toBe(true);
        });

        test('If no vehicles found, display VinNotFound alert', async () => {
            // Arrange
            const mockRegistrationLicensePlate = {
                licensePlate: 'TEST1234'
            };

            const { wrapper } = setupMocks({
                vinLookupResponseError: 'vin not found error'
            });

            useMainStore().order.vehicle.carId = 'TESTCARID';

            await wrapper.setData({
                licensePlate: mockRegistrationLicensePlate
            });

            wrapper.vm.navigateForward = jest.fn();

            // Act
            await wrapper.vm.forwardButtonAction();

            // Assert
            expect(wrapper.findComponent({ ref: 'alertVinNotFound' }).isVisible()).toBe(true);
        });
        test('non-serviceable big truck found, display NoServiceAlert', async () => {
            // Arrange
            const mockRegistrationLicensePlate = {
                licensePlate: 'BIGTRUCKTEST'
            };

            const { wrapper } = setupMocks({
                lookupVinByPlateResponse: {
                    vin: 'BIGTRUCKVIN',
                    vehicle: {
                        carId: 'BIGTRUCKTESTCARID',
                        isBigTruck: true,
                        canSafeliteService: false
                    }
                }
            });

            useMainStore().order.vehicle.carId = 'BIGTRUCKTESTCARID';

            await wrapper.setData({
                licensePlate: mockRegistrationLicensePlate
            });

            wrapper.vm.navigateForward = jest.fn();

            // Act
            await wrapper.vm.forwardButtonAction();

            // Assert
            expect(wrapper.findComponent({ ref: 'alertNoService' }).isVisible()).toBe(true);
        });
        test('serviceable big truck found, do not display NoServiceAlert', async () => {
            // Arrange
            const mockRegistrationLicensePlate = {
                licensePlate: 'BIGTRUCKTEST2'
            };

            const { wrapper } = setupMocks({
                lookupVinByPlateResponse: {
                    vin: 'BIGTRUCKVIN2',
                    vehicle: {
                        carId: 'BIGTRUCKTESTCARID2',
                        isBigTruck: true,
                        canSafeliteService: true
                    }
                }
            });

            useMainStore().order.vehicle.carId = 'BIGTRUCKTESTCARID2';

            await wrapper.setData({
                licensePlate: mockRegistrationLicensePlate
            });

            wrapper.vm.navigateForward = jest.fn();

            // Act
            await wrapper.vm.forwardButtonAction();

            // Assert
            expect(wrapper.findComponent({ ref: 'alertNoService' }).exists()).toBe(false);
        });
    });

    describe('navigation', () => {
        test('Clicking back button navigates back', async () => {
            // Arrange
            const { wrapper } = setupMocks({
                mountOptionsMockData: {
                    router: {
                        navigate: jest.fn()
                    }
                }
            });
            // Act
            licensePlateLookup.beforeRouteEnter.call(
                wrapper.vm,
                { query: { issPage: 'license-plate-lookup' } },
                undefined,
                (c) => c(wrapper.vm)
            );
            await wrapper.vm.navigateBack();

            // Assert
            expect(wrapper.vm.$router.navigateWithSpinner).toHaveBeenCalled();
        });

        test('License plate found and matches entered vehicle => navigateForwardWithSingleCarMatch', async () => {
            // Arrange
            const vehicleFound = {
                carId: 'C0000'
            };

            const { wrapper } = setupMocks({});
            wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();

            useMainStore().order.vehicle.carId = 'C0000';

            // Act
            wrapper.vm.navigateForward(vehicleFound);

            // Assert
            expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
        });

        // eslint-disable-next-line max-len, function-paren-newline
        test('if a different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page',
            async () => {
            // Arrange
                const mockRegistrationLicensePlate = {
                    licensePlate: 'TEST1234'
                };

                const { wrapper } = setupMocks({});

                await wrapper.setData({
                    licensePlate: mockRegistrationLicensePlate,
                    isCarIdDifferent: true,
                    isSelectedGlassAvailableForVehicle: false
                });

                useMainStore().order.vehicle.carId = 'CARID';

                const carsFound = [
                    {
                        vin: 'TEST_VIN2',
                        vehicle: {
                            carId: 'C0000'
                        }
                    }
                ];

                // Act
                await wrapper.vm.navigateForward(carsFound);

                // Assert
                expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
                    navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
                    undefined,
                    {},
                    { displayVehicleChangeAlert: true }
                );
            }
        );
    });

    describe('miscellaneous', () => {
        test('Vehicle make set, arePagePrerequisitesValid should be true', () => {
            // Arrange
            const { wrapper } = setupMocks({});
            useMainStore().order.vehicle.carId = 'CR00000395';

            // Act
            licensePlateLookup.beforeRouteEnter.call(
                wrapper.vm,
                { query: { issPage: 'license-plate-lookup' } },
                undefined,
                (c) => c(wrapper.vm)
            );

            const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();

            // Assert
            expect(arePagePrerequisitesValid).toBe(true);
        });
    });
});
