import addressVehicles from '@/layouts/address-vehicles/address-vehicles.vue';
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 { fetchCmsContentForPage } from '@/helpers/cms-content-helper';

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

// Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({
    fetchCmsContentForPage: jest.fn(),
    doesCopyContainRouterLink: jest.fn(),
    splitCopyOnCMSPlaceHolder: jest.fn().mockImplementation(() => 'test'),
    getRouterLinkRouteFromCopy: jest.fn(),
    getRouterLinkDisplayTextFromCopy: jest.fn(),
    splitCMSCopyOnParagraphTag: jest.fn()
}));

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

function setupMocks({
    route = null,
    lookupVehicleByVinResponse
}) {
    useMainStore().applicationUser = {
        pageData: {
            'address-vehicles':
                [
                    {
                        vehicle: {
                            carId: 'CR00069309',
                            category: 'SUV',
                            imageUrl:
                                'https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg',
                            imageVifColor: 'white',
                            imageVifNumber: '13769',
                            make: 'Hyundai',
                            model: 'Santa Fe',
                            style: '4 door utility',
                            year: 2020
                        },
                        vin: '5NMS3CADXLH233004'
                    }
                ]
        }
    };

    useMainStore().lookupVehicleByVin = jest.fn().mockImplementation(() => Promise.resolve({
        data: lookupVehicleByVinResponse || {
            vehicle: {
                carId: 'CARID'
            }
        }
    }));

    const mountOptions = getMountOptions({
        route: route || undefined,
        router: {
            navigate: jest.fn()
        },
        mainStore: {
            order: {
                vehicle: {
                    carId: 'CR00069309',
                    category: 'SUV',
                    imageUrl:
                        'https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg',
                    imageVifColor: 'white',
                    imageVifNumber: '13769',
                    make: 'Hyundai',
                    model: 'Santa Fe',
                    style: '4 door utility',
                    year: 2020
                },
                vin: '5NMS3CADXLH233004'
            }
        }
    });

    const apiResponses = {
        cmsContent: {}
    };

    settleAllPromises.mockImplementation(() => apiResponses);
    fetchCmsContentForPage.mockImplementation(() => Promise.resolve());

    // Mock props
    const mockMixin = {
        methods: {
            getCmsContent: jest.fn((contentName) => {
                if (contentName === 'FoundMultipleVehicles') {
                    return 'FoundMultipleVehiclesTestReturn';
                }
                if (contentName === 'ProvideVinAlert') {
                    return 'ProvideVinAlertTestReturn';
                }
                return null;
            })
        },
        computed: {
            dynamicStrings() {
                return { ROUTER_LINK: 'routerLink:' };
            }
        }
    };

    mountOptions.mixins = [mockMixin];

    const wrapper = shallowMount(addressVehicles, mountOptions);

    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();

    return { wrapper };
}

describe('address-vehicles.vue', () => {
    test('Should navigate to CLICKED_BACK if backButtonAction is run', async () => {
        // Arrange
        const { wrapper } = setupMocks({});

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

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

    test('navigateForward should be called if forwardButtonAction is run', async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        const lookupVinResponse = {
            data: {
                carId: '456'
            }
        };

        wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
        wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse));
        wrapper.vm.$router.navigate = jest.fn();
        wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});
        wrapper.vm.navigateForward = jest.fn().mockImplementation(() => {});

        // Act
        await wrapper.setData({
            selectedVehicleVin: '5NMS3CADXLH233004'
        });

        await wrapper.vm.forwardButtonAction();
        wrapper.vm.$nextTick();

        // Assert
        expect(wrapper.vm.navigateForward).toHaveBeenCalled();
    });

    // TODO: Add () to toReturn and ensure test passes.
    test.skip('Should return out of forwardButtonAction is lookupVin returns an error', async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();

        const lookupVinResponse = {
            error: 'there is an error'
        };

        wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
        wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
        wrapper.vm.$router.navigate = jest.fn();
        wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});

        // Act
        await wrapper.setData({
            selectedVehicleVin: '5NMS3CADXLH233004'
        });

        await wrapper.vm.forwardButtonAction();
        wrapper.vm.$nextTick();

        // Assert
        expect(wrapper.vm.forwardButtonAction).toReturn;
    });

    // eslint-disable-next-line max-len
    test(
        'Should navigate to CLICKED_FORWARD scenario if carId is different and selected glass not available for vehicle on navigateForward',
        async () => {
        // Arrange
            const { wrapper } = setupMocks({});
            wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
            wrapper.vm.$router.navigate = jest.fn();

            // Act
            await wrapper.setData({
                selectedVehicleVin: '5NMS3CADXLH233004',
                isSelectedGlassAvailableForVehicle: false,
                isCarIdDifferent: true
            });
            await wrapper.vm.navigateForward();

            // Assert
            expect(wrapper.vm.$router.navigate).toBeCalledTimes(1);
        }
    );

    test('carId is not different on navigateForward (car was found) => Should handle navigating forward with car match', async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
        wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();

        // Act
        await wrapper.setData({
            isCarIdDifferent: false
        });
        await wrapper.vm.navigateForward();

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

    test('Should return true for valid page requisites if carId exists', async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        useMainStore().order.vehicle.carId = 'CR00000395';

        // Act
        addressVehicles.beforeRouteEnter.call(
            wrapper.vm,
            { query: { issPage: 'address-vehicles' } },
            undefined,
            (c) => c(wrapper.vm)
        );

        const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();

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

    test('selected vehicle is a non-serviceable big truck, display no service alert', async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        useMainStore().order.vehicle.carId = 'BIGTRUCKCARID';
        useMainStore().applicationUser = {
            pageData: {
                'address-vehicles':
                    [
                        {
                            vehicle: {
                                carId: 'BIGTRUCKCARID',
                                make: 'Isuzu',
                                model: 'Reach',
                                style: 'Step Van',
                                year: 2016,
                                isBigTruck: true,
                                canSafeliteService: false
                            },
                            vin: 'BIGTRUCKVIN'
                        }
                    ]
            }
        };

        await wrapper.setData({
            selectedVehicleVin: 'BIGTRUCKVIN',
            previouslyEnteredCarId: 'BIGTRUCKCARID'
        });

        wrapper.vm.selectedVehicle = {
            vin: 'BIGTRUCKVIN',
            vehicle: {
                carId: 'BIGTRUCKCARID',
                isBigTruck: true,
                canSafeliteService: false
            }
        };

        // Act
        await wrapper.vm.$nextTick();

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

    test('selected vehicle is a serviceable big truck, do not display no service alert', async () => {
        // Arrange
        const { wrapper } = setupMocks({});
        useMainStore().order.vehicle.carId = 'BIGTRUCKCARID2';
        useMainStore().applicationUser = {
            pageData: {
                'address-vehicles':
                    [
                        {
                            vehicle: {
                                carId: 'BIGTRUCKCARID2',
                                make: 'Mack',
                                model: 'Terrapro',
                                style: 'Cabover',
                                year: 2024,
                                isBigTruck: true,
                                canSafeliteService: true
                            },
                            vin: 'BIGTRUCKVIN2'
                        }
                    ]
            }
        };

        await wrapper.setData({
            selectedVehicleVin: 'BIGTRUCKVIN2',
            previouslyEnteredCarId: 'BIGTRUCKCARID2'
        });

        wrapper.vm.selectedVehicle = {
            vin: 'BIGTRUCKVIN2',
            vehicle: {
                carId: 'BIGTRUCKCARID2',
                isBigTruck: true,
                canSafeliteService: true
            }
        };

        // Act
        await wrapper.vm.$nextTick();

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