// Components
import capabilityQuestions from '@/layouts/capability-questions/capability-questions.vue';

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

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

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

const baseStoreGettersPageData = () => ({
    partsOrQuestions: [
        {
            parts: [
                {
                    childPartQuestions: []
                }
            ],
            capabilityQuestions: [
                {
                    questionSequence: 1,
                    questionText:
                            // eslint-disable-next-line max-len
                            'Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?',
                    answers: [
                        {
                            answerResult1: 'DYNAMIC',
                            answerResult2: '1',
                            answerText: 'Yes',
                            nextQuestionSequence: null,
                            answerResult: 'DYNAMIC'
                        },
                        {
                            answerResult1: 'Unknown',
                            answerResult2: '0',
                            answerText: 'No',
                            nextQuestionSequence: null,
                            answerResult: 'Unknown'
                        }
                    ]
                }
            ],
            partQuestions: [],
            questions: [],
            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?',
                    selectedAnswer: '1|nextQuestion|3|Yes',
                    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?',
                    selectedAnswer: '2|nextQuestion|3|Yes',
                    selectedAnswerText: 'Yes',
                    questionNum: 2
                }
            ]
        }
    ]
});
useMainStore().pageData = baseStoreGettersPageData;
useMainStore().damage = baseStoreGettersDamage;

function setupMocks({
    mountOptionsMockData = {
        router: {
            navigate: jest.fn()
        },
        actionList: [
            {
                actionName: 'saveCapabilityQuestionAnswers',
                data: {}
            },
            {
                actionName: 'getPartsOrQuestions',
                data: {}
            }
        ],
        route: {
            query: {
                issPage: 'capability-questions'
            }
        },
        data() {
            return {
                computedSwitcher: [
                    {
                        glassLocation: 'Windshield',
                        glassName: 'Single',
                        answerData: {
                            answerResult: 'FW04848',
                            answeredQuestions: []
                        }
                    }
                ]
            };
        },
        questionsData: {
            get() {
                return this.computedSwitcher;
            },
            set(val) {
                this.computedSwitcher = val;
            }
        }
    }
}) {
    useMainStore().getPartsOrQuestions = jest.fn(() => ({
        data: {
            partsOrQuestions: []
        }
    }));
    const mountOptions = getMountOptions({
        ...mountOptionsMockData,
        mixins: [baseMixin, vehicleQuestionsMixin]
    });
    mountOptions.attachTo = document.body;

    const wrapper = shallowMount(capabilityQuestions, mountOptions);

    return { wrapper };
}

describe('capabilityQuestions.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:
                                    // 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?',
                                selectedAnswer: '1|nextQuestion|3|Yes',
                                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?',
                                selectedAnswer: '2|nextQuestion|3|Yes',
                                selectedAnswerText: 'Yes',
                                questionNum: 2
                            }
                        ],
                        index: 0
                    }
                }
            });

            await nextTick();

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

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

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

            wrapper.vm.questionsData = [
                {
                    glassLocation: 'Windshield',
                    glassName: 'Single',
                    answerData: {
                        answerResult: 'FW04848',
                        answeredQuestions: []
                    },
                    questions: [],
                    parts: [
                        {
                            childPartQuestions: [{}]
                        }
                    ]
                }
            ];
            wrapper.vm.dispatchStoreAction = jest.fn(() => ({
                data: []
            }));

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

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

            wrapper.unmount();
        });

        test('Should save to pinia store', async () => {
            // Arrange
            const { wrapper } = setupMocks({});

            wrapper.vm.questionsData = [
                {
                    glassLocation: 'Windshield',
                    glassName: 'Single',
                    answerData: {
                        answerResult: 'FW04848',
                        answeredQuestions: []
                    },
                    questions: [],
                    parts: [
                        {
                            childPartQuestions: []
                        }
                    ]
                }
            ];
            useMainStore().getPartsOrQuestions = jest.fn(() => ({
                data: {
                    partsOrQuestions: []
                }
            }));
            const saveCapabilityQuestionAnswersSpy = jest.spyOn(useMainStore(), 'saveCapabilityQuestionAnswers');

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

            // Assert
            expect(saveCapabilityQuestionAnswersSpy).toHaveBeenCalled();
            wrapper.unmount();
        });

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

            wrapper.vm.questionsData = [
                {
                    glassLocation: 'Windshield',
                    glassName: 'Single',
                    answerData: {
                        answerResult: 'FW04848',
                        answeredQuestions: []
                    },
                    questions: [],
                    parts: [
                        {
                            childPartQuestions: []
                        }
                    ]
                }
            ];
            useMainStore().getPartsOrQuestions = jest.fn(() => ({
                data: {
                    partsOrQuestions: []
                }
            }));
            const updatePartFromCapabilityQuestionAnswerSpy = jest.spyOn(useMainStore(), 'updatePartFromCapabilityQuestionAnswer');
            updatePartFromCapabilityQuestionAnswerSpy.mockClear();

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

            // Assert
            expect(updatePartFromCapabilityQuestionAnswerSpy).toHaveBeenCalledTimes(1);
            wrapper.unmount();
        });

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

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

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

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

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