import baseMixin from '@/mixins/base-mixin';
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import serviceLocation from '@/layouts/service-location/service-location.vue';

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

/** @ignore */
function setupMocks() {
    const wrapper = shallowMount(
        serviceLocation,
        getMountOptions({
            router: {
                navigate: jest.fn()
            }
        })
    );

    wrapper.vm.$router.navigateWithSpinner = jest.fn();
    wrapper.vm.navigateBack = baseMixin.methods.navigateBack;

    return { wrapper };
}

const mockGetServiceabilityDetails = () => {
    const serviceabilityDetails = {
        isGlassServiceableInshop: true,
        isRecalibrationServiceableInshop: true,
        isGlassServiceableMobile: true,
        isRecalibrationServiceableMobile: true
    };

    return Promise.resolve(serviceabilityDetails);
};

jest.mock(
    '@/helpers/service-location-helper',
    () => ({
        getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode))
    })
);

const mockMixin = {
    methods: {
        getCmsContent: jest.fn((widgetName, cmsFieldName) => {
            // linkWidgetName is not defined.  This whole spec file needs review.
            if (widgetName === linkWidgetName) {
                return mockLinkCmsContent[cmsFieldName];
            }

            if (widgetName === modalWidgetName) {
                return mockModalCmsContent[cmsFieldName];
            }

            return null;
        }),

        getZipCodeData: jest.fn((zip) => {
            if (zip === '43235' || zip === '55555') {
                return Promise.resolve({
                    containsMilitaryBase: false,
                    isValid: true,
                    state: 'OH',
                    zipCodeCtu: '01820'
                });
            }

            if (zip === '45433') {
                return Promise.resolve({
                    containsMilitaryBase: true,
                    isValid: true,
                    state: 'OH'
                });
            }

            return Promise.resolve({
                containsMilitaryBase: false,
                isValid: false,
                state: null,
                zipCodeCtu: null
            });
        }),

        onSubmit: jest.fn(),
        onInvalidSubmit: jest.fn()
    }
};

describe('navigation', () => {
    test('if the back button is clicked, navigate back', async () => {
        // Arrange
        const { wrapper } = setupMocks({
        });

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

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

describe('updating service zip', () => {
    test('updates the page model after changing the service zip code', () => {
        // Arrange
        const { wrapper } = setupMocks({
            mixins: [mockMixin]
        });

        const newServiceZipCodeQuestion = {
            zipCode: '61606',
            state: 'IL'
        };

        const serviceZipCodeComponent = wrapper.findComponent({
            ref: 'serviceZipCodeQuestion'
        });

        // Act
        serviceZipCodeComponent.vm.$emit('update:modelValue', newServiceZipCodeQuestion);

        // Assert
        expect(wrapper.vm.serviceZipCodeQuestion).toStrictEqual(newServiceZipCodeQuestion);
    });

    test('displays military zip message when zip is updated', () => {
        // Arrange
        const { wrapper } = setupMocks({});

        const mobileLocationQuestionsComponent = wrapper.findComponent({
            ref: 'mobileLocationQuestions'
        });
        mobileLocationQuestionsComponent.resetComponent = jest.fn();

        const serviceZipCodeComponent = wrapper.findComponent({
            ref: 'serviceZipCodeQuestion'
        });
        serviceZipCodeComponent.resetMobileFeePart = jest.fn();

        expect(wrapper.vm.zipContainsMilitaryBase).toBe(false);

        // TODO: Use or remove
        const newServiceZipCodeQuestion = {
            zipCode: '45433',
            state: 'OH'
        };

        // Act
        serviceZipCodeComponent.vm.$emit('updated-contains-military-base', true);

        // Assert
        expect(wrapper.vm.zipContainsMilitaryBase).toBe(true);
    });
});
