// Components
import addressQuestions from '@/iss-components/address-questions/address-questions.vue';

// Supporting Files
import { mount, shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';

let autocompleteElement;

/** @ignore */
function setupMocks({
    mountOptions,
    props,
    isShallowMount = true,
    querySelectorFunction,
    geocoderResult = ['1234 Test Street']
}) {
    const resultingMountOptions = getMountOptions({
        ...mountOptions,
        router: {
            navigate: jest.fn()
        },
        loadScript: jest.fn().mockResolvedValue()
    });

    window.google = {
        maps: {
            event: {
                addListener: jest
                    .fn()
                    .mockImplementation((element, eventName, callbackFunction) => {
                        /** @ignore */
                        function interceptedCallbackFunction(e) {
                            callbackFunction(e.detail);
                        }
                        // selectedPlace = "Woogly";
                        element.addEventListener(eventName, interceptedCallbackFunction);
                    }),
                removeListener: jest.fn(),
                clearInstanceListeners: jest.fn()
            },
            places: {
                Autocomplete: jest.fn().mockImplementation((el) => el)
            }
        }
    };

    if (props) resultingMountOptions.propsData = props;

    const wrapper = isShallowMount
        ? shallowMount(addressQuestions, resultingMountOptions)
        : mount(addressQuestions, resultingMountOptions);

    document.querySelector = jest.fn().mockImplementation((query) => {
        let result = null;
        if (query === '.pac-container') result = document.createElement('div');
        else if (querySelectorFunction) {
            result = querySelectorFunction(query);
        }

        return result ?? null;
    });

    return { wrapper };
}

describe('address-questions.vue', () => {
    beforeEach(() => {
        // Create the `addressField1` element (autocomplete's input)
        autocompleteElement = document.createElement('input');
        autocompleteElement.getPlace = jest.fn();
        document.getElementById = jest.fn().mockReturnValue(autocompleteElement);
    });

    describe('initial state', () => {
        test('Should hide(exists but not visible) addressQuestions sub-components (textbox-questions and dropdown-questions)', async () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const streetAddress = wrapper.findComponent({ ref: 'autocomplete' });
            const city = wrapper.findComponent({ ref: 'city' });
            const state = wrapper.findComponent({ ref: 'state' });
            const zipCode = wrapper.findComponent({ ref: 'zipCode' });
            const streetAddress2 = wrapper.findComponent({ ref: 'streetAddress2' });

            // Assert
            expect(streetAddress.exists()).toBe(true);
            expect(city.exists()).toBe(true);
            expect(city.isVisible(false));
            expect(state.exists()).toBe(true);
            expect(state.isVisible(false));
            expect(zipCode.exists()).toBe(true);
            expect(zipCode.isVisible(false));
            expect(streetAddress2.exists()).toBe(false);
        });

        test('full street address is passed in => address fields are displayed', async () => {
            // Arrange/Act
            const { wrapper } = setupMocks({
                props: {
                    modelValue: {
                        streetAddress: '12345 Test Road',
                        city: 'Tests',
                        state: 'OH',
                        zipCode: '12312'
                    },
                    includeStreetAddress2: true
                }
            });

            await wrapper.vm.$nextTick();

            // Assert
            const cityField = wrapper.findComponent({ ref: 'city' });
            const stateField = wrapper.findComponent({ ref: 'state' });
            const zipField = wrapper.findComponent({ ref: 'zipCode' });
            const streetAddress2 = wrapper.findComponent({ ref: 'streetAddress2' });

            expect(cityField.exists()).toBeTruthy();
            expect(cityField.isVisible()).toBeTruthy();
            expect(stateField.exists()).toBeTruthy();
            expect(cityField.isVisible()).toBeTruthy();
            expect(zipField.exists()).toBeTruthy();
            expect(cityField.isVisible()).toBeTruthy();
            expect(streetAddress2.isVisible()).toBeTruthy();
        });

        test('address2 is hidden if includeStreetAddress2 is false', async () => {
            // Arrange/Act
            const { wrapper } = setupMocks({
                props: {
                    modelValue: {
                        streetAddress: '12345 Test Road',
                        city: 'Tests',
                        state: 'OH',
                        zipCode: '12312'
                    },
                    includeStreetAddress2: false
                }
            });

            await wrapper.vm.$nextTick();

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