/* eslint-env jest */
import baseMixin from '@/mixins/base-mixin';
import { mount } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import routerParams from '@/router/router-constants/router-params';
import { useMainStore } from '@/store';
import serviceLocation from '@/layouts/schedule-page/service-location/service-location.vue';

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

    return Promise.resolve(serviceabilityDetails);
};
const mockZipcodeData = (zip) => {
    if (zip === '43235' || zip === '55555') {
        return Promise.resolve({
            containsMilitaryBase: false,
            isValid: true,
            isServiceable: true,
            city: 'Columbus',
            state: 'OH',
            zipCodeCtu: '01820'
        });
    }

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

    return Promise.resolve({
        containsMilitaryBase: false,
        isValid: false,
        isServiceable: false,
        city: null,
        state: null,
        zipCodeCtu: null
    });
};
const mockProviders = () => Promise.resolve([
    {
        address: {
            city: 'COLUMBUS',
            country: 'US',
            state: 'OH',
            streetAddress: '6826 Sawmill Rd',
            streetAddress2: '',
            zipCode: '43235',
            zipCodeCtu: '03357'
        },
        distanceInMiles: 4.136335989015438,
        providerNumber: '003357',
        companyName: 'SAFELITE AUTOGLASS - COLUMBUS, OH',
        phoneNumber: '6142336400',
        isSafeliteShop: true
    },
    {
        address: {
            city: 'Lewis Center',
            country: 'US',
            state: 'OH',
            streetAddress: '1343 Cameron Ave',
            streetAddress2: '',
            zipCode: '43035',
            zipCodeCtu: '03357'
        },
        distanceInMiles: 8.193072412262042,
        providerNumber: '003417',
        companyName: 'SAFELITE AUTOGLASS - LEWIS CENTER, OH',
        phoneNumber: '6147815433',
        isSafeliteShop: true
    }
]);
jest.mock(
    '@/helpers/service-location-helper',
    () => ({
        getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode)),
        getZipCodeData: jest.fn((mockServiceZipCode) => mockZipcodeData(mockServiceZipCode)),
        getMobileZipCodeData: jest.fn((mockServiceZipCode) => mockZipcodeData(mockServiceZipCode))
    })
);

const mockRoute = {
    params: {}
};
const mockRouter = {
    navigate: jest.fn()
};
const mountOptions = {
    global: {
        mixins: [
            {
                computed: {
                    navigationScenarios() {
                        return navigationScenarios;
                    },
                    routerParams() {
                        return routerParams;
                    }
                },
                methods: {
                    getCmsContent: jest.fn(),
                    getFooterInfoBoxHeight: jest.fn(() => 80),
                    getPageNameByQueryString: jest.fn(() => '')
                }
            }
        ],
        mocks: {
            $route: mockRoute,
            $router: mockRouter
        },
        stubs: {
            alert: true,
            textBlock: true,
            appointmentTypeQuestion: true,
            contentGroupModal: true,
            siteFooter: true,
            siteHeader: true,
            siteSubHeader: true,
            shopAddress: true,
            serviceZipQuestion: true
        }
    }
};
function setupMocks({ appointmentType = AppointmentTypeStrings.IN_SHOP }) {
    mountOptions.global.plugins = [createTestingPinia({
        initialState: {
            main: {
                order: {
                    serviceLocation: {
                        appointmentType
                    }
                }
            }
        }
    })];
    useMainStore().getProviders = jest.fn().mockImplementation(() => mockProviders());
    const wrapper = mount(serviceLocation, mountOptions);

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

    return { wrapper };
}

beforeEach(() => {
    jest.clearAllMocks();
});
describe('service-location.vue', () => {
    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({ appointmentType: AppointmentTypeStrings.IN_SHOP });

            const newServiceZipCode = '61606';

            const shopAddressComponent = wrapper.findComponent({
                ref: 'shopAddress'
            });

            // Act
            shopAddressComponent.vm.$emit('zip-updated', newServiceZipCode);

            // Assert
            expect(wrapper.vm.zipCode).toStrictEqual(newServiceZipCode);
        });

        test('displays military zip message when zip is updated', async () => {
            // Arrange
            const { wrapper } = setupMocks({ appointmentType: AppointmentTypeStrings.MOBILE });

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

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

            const newMobileServiceZipCode = '45433';

            // Act
            mobileServiceZipCodeQuestion.vm.$emit('update:modelValue', newMobileServiceZipCode);
            await wrapper.vm.$nextTick();

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