// Components
import partQuestions from '@/layouts/part-questions/part-questions.vue';

// Supporting Files
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { useMainStore } from '@/store';
import baseMixin from '@/mixins/base-mixin';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
import { nextTick } from 'vue';

// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({
    settleAllPromises: jest.fn()
}));

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

/** @ignore */
function setupMocks({
    mountOptionsMockData = {
        router: {
            navigate: jest.fn(),
            navigateWithSaving: jest.fn(),
            navigateWithoutSaving: jest.fn()
        },
        actionList: [
            {
                actionName: 'savePartQuestionAnswers',
                data: {}
            },
            {
                actionName: 'getParts',
                data: {}
            }
        ],
        route: {
            query: {
                issPage: 'part-questions'
            }
        },
        data() {
            return {
                computedSwitcher: [
                    {
                        glassLocation: 'Windshield',
                        glassName: 'Single',
                        answerData: {
                            answerResult: 'FW04848',
                            answeredQuestions: []
                        }
                    }
                ]
            };
        },
        questionsData: {
            get() {
                return this.computedSwitcher;
            },
            set(val) {
                this.computedSwitcher = val;
            }
        }
    }
}) {
    useMainStore().getParts = jest.fn(() => ({
        data: {
            glassPieceParts: []
        }
    }));

    const mountOptions = getMountOptions({
        ...mountOptionsMockData,
        mixins: [baseMixin, vehicleQuestionsMixin]
    });
    mountOptions.attachTo = document.body;

    const wrapper = shallowMount(partQuestions, mountOptions);

    return { wrapper };
}

const baseStoreGettersPageData = () => ({
    partsOrQuestions: [
        {
            parts: null,
            partQuestions: [
                {
                    questionSequence: 1,
                    questionText:
                            // eslint-disable-next-line max-len
                            'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
                    answers: [
                        {
                            answerResult: '',
                            answerText: 'Yes',
                            nextQuestionSequence: 2
                        },
                        {
                            answerResult: '',
                            answerText: 'No',
                            nextQuestionSequence: 3
                        }
                    ]
                }
            ],
            glassLocation: 'Windshield',
            glassName: 'Single',
            answerKey: 'Windshield-Single',
            answerData: null
        }
    ]
});
const baseStoreGettersDamage = () => ({
    partsQuestionAnswers: [
        {
            glassLocation: 'Windshield',
            glassName: 'Single',
            result: 'FW04848',
            answeredQuestions: [
                {
                    questionText:
                            // eslint-disable-next-line max-len
                            'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
                    selectedAnswerText: 'Yes',
                    questionNum: 1
                },
                {
                    questionText:
                            // eslint-disable-next-line max-len
                            'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
                    selectedAnswerText: 'Yes',
                    questionNum: 2
                }
            ]
        }
    ]
});

useMainStore().pageData = baseStoreGettersPageData;
useMainStore().damage = baseStoreGettersDamage;

describe('partQuestions.vue...', () => {
    describe('method arePagePrerequisitesValid...', () => {
        test('Should return true for valid page requisites if pageData exists', () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.arePagePrerequisitesValid();

            // Assert
            expect(result).toBe(true);

            wrapper.unmount();
        });

        test('Should return false for valid page requisites if partsOrQuestions in pageData is missing', () => {
            // Arrange
            const { wrapper } = setupMocks({});
            useMainStore().pageData = jest.fn(() => undefined);

            // Act
            const result = wrapper.vm.arePagePrerequisitesValid();

            // Assert
            expect(result).toBeFalsy();

            wrapper.unmount();
        });

        test('Should be at least one item in partsOrQuestions', () => {
            // Arrange
            useMainStore().pageData = jest.fn(() => ({
                partsOrQuestions: []
            }));
            useMainStore().damage = baseStoreGettersDamage;

            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.arePagePrerequisitesValid();

            // Assert
            expect(result).toBeFalsy();

            wrapper.unmount();
        });
    });

    describe('watch on selectedAnswers should be set up...', () => {
        test('Should trigger handleAnswerUpdates if watched data changes', async () => {
            // Arrange
            useMainStore().pageData = baseStoreGettersPageData;
            useMainStore().damage = baseStoreGettersDamage;

            const { wrapper } = setupMocks({});
            const spy = jest.spyOn(wrapper.vm, 'handleAnswerUpdates');

            // Act
            wrapper.setData({
                selectedAnswers: {
                    'Windshield-Single': {
                        answerResult: 'FW04848',
                        answeredQuestions: [
                            {
                                questionText: 'One?',
                                selectedAnswerText: 'Yes',
                                questionNum: 1
                            },
                            {
                                questionText: 'Two?',
                                selectedAnswerText: 'Yes',
                                questionNum: 2
                            }
                        ],
                        index: 0
                    }
                }
            });

            await nextTick();

            wrapper.setData({
                selectedAnswers: {
                    'Windshield-Single': {
                        answerResult: 'NEW-ANSWER',
                        answeredQuestions: [
                            {
                                questionText: 'One?',
                                selectedAnswerText: 'Yes',
                                questionNum: 1
                            },
                            {
                                questionText: 'Two?',
                                selectedAnswerText: 'Yes',
                                questionNum: 2
                            }
                        ],
                        index: 0
                    }
                }
            });

            // Assert
            expect(spy).toHaveBeenCalled();

            wrapper.unmount();
        });
    });

    describe('forwardButtonAction', () => {
        test('Should clear out answerData', async () => {
            // Arrange
            const { wrapper } = setupMocks({});

            await wrapper.setData({
                questionsData: [
                    {
                        glassLocation: 'fbfWindshield',
                        glassName: 'fbfSingle',
                        answerData: {
                            answerResult: 'FW04848',
                            answeredQuestions: []
                        }
                    }
                ]
            });

            wrapper.vm.getParts = jest.fn(() => ({
                data: {
                    glassPieceParts: []
                }
            }));

            // Act
            wrapper.vm.forwardButtonAction();

            await nextTick();

            // Assert
            expect(wrapper.vm.questionsData[0].answerData).toEqual({});

            wrapper.unmount();
        });

        // TODO: Add () to toHaveBeenCalled and ensure test passes.
        test.skip('Should save to pinia store', async () => {
            // Arrange
            const { wrapper } = setupMocks({});

            wrapper.vm.questionsData = [
                {
                    glassLocation: 'Windshield',
                    glassName: 'Single',
                    answerData: {
                        answerResult: 'FW04848',
                        answeredQuestions: []
                    }
                }
            ];

            useMainStore().getParts = jest.fn(() => ({
                data: {
                    glassPieceParts: []
                }
            }));

            // Act
            wrapper.vm.forwardButtonAction();

            await nextTick();

            // Assert
            expect(wrapper.vm.savePartQuestionAnswers).toHaveBeenCalled;
            wrapper.unmount();
        });

        // TODO: Add () to toHaveBeenCalled and ensure test passes.
        test.skip('Should call GET_PARTS API', async () => {
            // Arrange
            const { wrapper } = setupMocks({});

            wrapper.vm.questionsData = [
                {
                    glassLocation: 'Windshield',
                    glassName: 'Single',
                    answerData: {
                        answerResult: 'FW04848',
                        answeredQuestions: []
                    }
                }
            ];
            useMainStore().getParts = jest.fn(() => ({
                data: {
                    glassPieceParts: []
                }
            }));

            // Act
            wrapper.vm.forwardButtonAction();

            await nextTick();

            // Assert
            expect(wrapper.vm.getParts).toHaveBeenCalled;

            wrapper.unmount();
        });

        test('Should trigger navigateForward', async () => {
            // Arrange
            const { wrapper } = setupMocks({});

            wrapper.vm.questionsData = [
                {
                    glassLocation: 'Windshield',
                    glassName: 'Single',
                    answerData: {
                        answerResult: 'FW04848',
                        answeredQuestions: []
                    }
                }
            ];
            useMainStore().getParts = jest.fn(() => ({
                data: {
                    glassPieceParts: []
                }
            }));
            wrapper.vm.navigateForward = jest.fn();

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

            // Assert
            expect(wrapper.vm.navigateForward).toHaveBeenCalled();

            wrapper.unmount();
        });
    });
});
