// Components
import { shallowMount } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import contactDetailsDrawer from '@/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue';

// Supporting Files
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { useMainStore } from '@/store';

function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRunAfterInitializingStore = () => {}) {
    const mountOptions = getMountOptions({
        router: {
            navigate: jest.fn()
        }
    });

    const testingPinia = createTestingPinia({
        initialState: {
            main: mainInitialState
        }
    });
    useMainStore(testingPinia);
    methodToRunAfterInitializingStore();

    mountOptions.global.plugins = [testingPinia];
    mountOptions.data = () => (initialData);

    const wrapper = shallowMount(contactDetailsDrawer, mountOptions);
    return { wrapper };
}

describe('contact-details-drawer', () => {
    test('snapshot matches returns the initial data', () => {
        // Arrange
        const firstName = 'Frederick';
        const lastName = 'Taylor';
        const emailAddress = 'fred.tay@gmail.com';
        const servicePhone = '606-009-2943';
        const mainInitialState = {
            order: {
                contactInfo: {
                    firstName,
                    lastName,
                    emailAddress,
                    servicePhone
                }
            }
        };
        const { wrapper } = getMountedComponent(mainInitialState);

        // Assert
        expect(wrapper.vm.$data).toMatchSnapshot();
    });
    test('renders modal', () => {
        // Arrange
        const wrapper = shallowMount(contactDetailsDrawer, getMountOptions());

        // Act
        const modal = wrapper.findComponent({ ref: 'contact-details-modal' });

        // Assert
        expect(modal.exists()).toBeTruthy();
        expect(modal.classes()).toContain('contact-details-drawer');
    });
    describe('method', () => {
        describe('saveContactDetails', () => {
            test.each([
                ['Sarah', 'Jones', 's.jones@gmail.com', '724-996-0909', '12345'],
                [null, 'Jones', 's.jones@gmail.com', '724-996-0909', '12345'],
                ['Sarah', null, 's.jones@gmail.com', '724-996-0909', '12345'],
                ['Sarah', 'Jones', null, '724-996-0909', '12345'],
                ['Sarah', 'Jones', 's.jones@gmail.com', null, '12345'],
                ['Sarah', 'Jones', 's.jones@gmail.com', '724-996-0909', null],

            ])(
                'when first name data "%p", last name "%p", email "%p", phone number "%p", and extension "%p", updateContactInfo called with expected',
                (firstName, lastName, emailAddress, phoneNumber, extension) => {
                    // Arrange
                    const mainInitialState = {
                        order: {
                            contactInfo: {
                                firstName: 'Frederick',
                                lastName: 'Taylor',
                                emailAddress: 'fred.tay@gmail.com',
                                servicePhone: '606-009-2943',
                                extension: '11111'
                            }
                        }
                    };
                    const initialData = {
                        firstName, lastName, emailAddress, phoneNumber, extension
                    };
                    const { wrapper } = getMountedComponent(mainInitialState, initialData);

                    // Act
                    wrapper.vm.saveContactDetails();

                    // Assert
                    expect(wrapper.emitted()['update-contact-details']).toBeTruthy();
                    expect(useMainStore().updateContactInfo).toBeCalledTimes(1);
                    expect(useMainStore().updateContactInfo).toBeCalledWith({ firstName, lastName, emailAddress });
                    expect(useMainStore().updatePhoneNumbers).toBeCalledTimes(1);
                    expect(useMainStore().updatePhoneNumbers).toBeCalledWith({ home: phoneNumber, service: phoneNumber, extension: extension });
                }
            );
        });
        test('resetFormValues sets data to expected values', () => {
            // Arrange
            const firstName = 'John';
            const lastName = 'Doe';
            const emailAddress = 'test@example.com';
            const phoneNumber = '123-456-1234';
            const mainInitialState = {
                order: {
                    contactInfo: {
                        firstName,
                        lastName,
                        emailAddress,
                        phoneNumber
                    }
                }
            };
            const initialData = {
                firstName: 'some name',
                lastName: 'some end name',
                emailAddress: 'email@what.com',
                phoneNumber: '888'
            };
            const { wrapper } = getMountedComponent(mainInitialState, initialData);

            // Act
            wrapper.vm.resetFormValues();

            // Assert
            expect(wrapper.vm.firstName).toBe(firstName);
        });
    });
});
