// Components
import policyEndorsements from '@/layouts/policy-endorsements/policy-endorsements.vue';

// Supporting Files
import baseMixin from '@/mixins/base-mixin';
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import { createTestingPinia } from '@pinia/testing';
import { useMainStore } from '@/store';
import { getRandomString } from '@/helpers/data-generation';

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

    mountOptions.global.plugins = [createTestingPinia({
        initialState: {
            main: mainInitialState
        }
    })];

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

describe('policyEndorsements.vue', () => {
    describe('Rendering', () => {
        test('Should render site header', () => {
            // Arrange
            const wrapper = shallowMount(policyEndorsements, getMountOptions());

            // Act
            const siteHeader = wrapper.findComponent({ ref: 'siteHeader' });

            // Assert
            expect(siteHeader.exists()).toBe(true);
        });
        test('Should render site subheader', () => {
            // Arrange
            const wrapper = shallowMount(policyEndorsements, getMountOptions());

            // Act
            const siteSubHeader = wrapper.findComponent({ ref: 'siteSubHeader' });

            // Assert
            expect(siteSubHeader.exists()).toBe(true);
        });
        test('Should render schoolProperty buttonQuestion component if policy vehicle has Educator endorsement', () => {
            // Arrange
            const mainInitialState = {
                order: {
                    policy: {
                        endorsements: ['Educator']
                    }
                }
            };
            const { wrapper } = getMountedComponent(mainInitialState);
            const buttonQuestion = wrapper.findComponent({ ref: 'schoolPropertyQuestion' });

            // Assert
            expect(wrapper.vm.educatorEndorsement).toBeTruthy();
            expect(buttonQuestion.exists()).toBe(true);
        });
        test('Should not render schoolProperty buttonQuestion component if policy vehicle does not have Educator endorsement', () => {
            // Arrange
            const mainInitialState = {
                order: {
                    policy: {
                        endorsements: [getRandomString(20, 30)]
                    }
                }
            };
            const { wrapper } = getMountedComponent(mainInitialState);
            const buttonQuestion = wrapper.findComponent({ ref: 'schoolPropertyQuestion' });

            // Assert
            expect(wrapper.vm.educatorEndorsement).toBeFalsy();
            expect(buttonQuestion.exists()).toBe(false);
        });
        test('Should render parkingLot buttonQuestion component if policy vehicle has Parking Guard endorsement', () => {
            // Arrange
            const mainInitialState = {
                order: {
                    policy: {
                        endorsements: ['Parking Guard']
                    }
                }
            };
            const { wrapper } = getMountedComponent(mainInitialState);
            const buttonQuestion = wrapper.findComponent({ ref: 'parkingLotQuestion' });

            // Assert
            expect(wrapper.vm.parkingGuardEndorsement).toBeTruthy();
            expect(buttonQuestion.exists()).toBe(true);
        });
        test('Should not render parkingLot buttonQuestion component if policy vehicle does not have Parking Guard endorsement', () => {
            // Arrange
            const mainInitialState = {
                order: {
                    policy: {
                        endorsements: [getRandomString(20, 30)]
                    }
                }
            };
            const { wrapper } = getMountedComponent(mainInitialState);
            const buttonQuestion = wrapper.findComponent({ ref: 'parkingLotQuestion' });

            // Assert
            expect(wrapper.vm.parkingGuardEndorsement).toBeFalsy();
            expect(buttonQuestion.exists()).toBe(false);
        });
        test('Should render site footer', () => {
            // Arrange
            const wrapper = shallowMount(policyEndorsements, getMountOptions());

            // Act
            const siteFooter = wrapper.findComponent({ ref: 'siteFooter' });

            // Assert
            expect(siteFooter.exists()).toBe(true);
        });
    });
    describe('Navigation', () => {
        test('Back button clicked triggers navigation', () => {
            // Arrange
            const wrapper = shallowMount(policyEndorsements, getMountOptions({
                router: {
                    navigateWithSpinner: jest.fn()
                }
            }));
            wrapper.vm.navigateBack = baseMixin.methods.navigateBack;

            // Act
            wrapper.vm.navigateBack();

            // Assert
            expect(wrapper.vm.$router.navigateWithSpinner).toHaveBeenCalled();
            expect(wrapper.vm.$router.navigateWithSpinner)
                .toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, undefined);
        });
        test('Forward button clicked with valid car id triggers navigation', () => {
            // Arrange
            const wrapper = shallowMount(policyEndorsements, getMountOptions({
                router: {
                    navigate: jest.fn()
                }
            }));

            wrapper.setData({
                hasValidCarId: true
            });

            // Act
            wrapper.vm.forwardButtonAction();
            wrapper.vm.navigateForward();

            // Assert
            expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
            expect(wrapper.vm.$router.navigate)
                .toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD, undefined);
        });
        test('Forward button clicked with invalid car id triggers navigation scenario CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND', () => {
            // Arrange
            const wrapper = shallowMount(policyEndorsements, getMountOptions({
                router: {
                    navigate: jest.fn()
                }
            }));

            wrapper.setData({
                hasValidCarId: false
            });

            // Act
            wrapper.vm.forwardButtonAction();
            wrapper.vm.navigateForward();

            // Assert
            expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
            expect(wrapper.vm.$router.navigate)
                .toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND, undefined);
        });
        test('Forward button clicked saves endorsement question answers', () => {
            // Arrange
            const mountOptions = getMountOptions({
                router: {
                    navigate: jest.fn()
                },
                global: {
                    plugins: [createTestingPinia()]
                }
            });

            const wrapper = shallowMount(policyEndorsements, mountOptions);

            // Act
            wrapper.vm.forwardButtonAction();

            // Assert
            expect(useMainStore().saveEndorsementQuestionAnswers).toHaveBeenCalledWith(wrapper.vm.questionAnswersArray);
        });
    });
});
