import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question.vue';
import { useMainStore } from '@/store';

const featureListData = {
    colorAnswersProp: [
        {
            ColorAnswerText: 'Green Tint',
            FeatureAnswers: [
                { FeatureAnswerText: 'heated glass, solar, 1 hole', PartNumber: 'DB12209GTYN' }
            ]
        },
        {
            ColorAnswerText: 'Gray Tint Privacy',
            FeatureAnswers: [
                { FeatureAnswerText: 'heated glass, solar, 1 hole', PartNumber: 'DB12209YPYN' }
            ]
        }
    ],
    glassLocationProp: 'Rear',
    glassNameProp: 'Stationary',
    modelValueProp: {}
};

/** @ignore */
function setupMocks({ glassNameProp, glassLocationProp, colorAnswersProp, modelValueProp, pageData }) {
    const mountOptions = getMountOptions({
        route: {
            query: {
                issPage: 'vehicle-parts'
            }
        }
    });

    mountOptions.propsData = {
        glassName: glassNameProp,
        glassLocation: glassLocationProp,
        colorAnswers: colorAnswersProp,
        modelValue: modelValueProp

    };

    const wrapper = shallowMount(glassPartQuestion, mountOptions);

    // Mock store
    const partsOrQuestions = pageData ?? { partsOrQuestions: [{ glassName: 'Stationary', glassLocation: 'Rear', parts: [] }] };
    useMainStore().pageData = jest.fn();
    useMainStore().pageData.mockReturnValue(partsOrQuestions);
    document.querySelector = jest.fn().mockReturnValue({ clicked: false, click: jest.fn() });
    return { wrapper };
}

describe('glass-part-question.vue', () => {
    test('Part data passed in, should map data for ButtonQuestion (radio type)', async () => {
        // Arrange
        const { wrapper } = setupMocks(featureListData);

        // Act
        await wrapper.vm.$nextTick();

        window.console.log(wrapper.vm.featureListData['Green Tint'][0].Text);
        // Assert
        expect(Object.keys(wrapper.vm.featureListData).length).toBe(2);
        expect(wrapper.vm.featureListData['Green Tint'][0].Text).toBe('heated glass, solar, 1 hole');
        expect(wrapper.vm.featureListData['Green Tint'][0].Name).toBe('DB12209GTYN');
        expect(wrapper.vm.featureListData['Gray Tint Privacy'][0].Text).toBe('heated glass, solar, 1 hole');
        expect(wrapper.vm.featureListData['Gray Tint Privacy'][0].Name).toBe('DB12209YPYN');
    });

    test('Tint mapper, should get tint image by glassLocation and tintColor', async () => {
        // Arrange

        const { wrapper } = setupMocks(featureListData);

        // Act
        await wrapper.vm.$nextTick();
        const tintSourceImage = wrapper.vm.getTintSourceImage('Rear', 'Green Tint');

        // Assert
        expect(tintSourceImage).toBe('Glass-NoShade-GreenTint.svg');
    });

    test('Tint mapper, should return empty string if no tint map found', async () => {
        // Arrange

        const { wrapper } = setupMocks(featureListData);

        // Act
        await wrapper.vm.$nextTick();
        const tintSourceImage = wrapper.vm.getTintSourceImage('Rear', 'Crazy Rainbow Tint');

        // Assert
        expect(tintSourceImage).toBe('');
    });

    test('Should emit updateModelValue, and have correct attributes', async () => {
        // Arrange
        featureListData.pageData = {
            partsOrQuestions: [
                {
                    glassName: 'Stationary',
                    glassLocation: 'Rear',
                    parts: [{ partNumber: 'DB12209GTYN', color: 'Green Tint' }]
                }
            ]
        };

        const { wrapper } = setupMocks(featureListData);

        // Act
        await wrapper.vm.$nextTick();
        const listCard = await wrapper.findComponent({
            name: 'buttonQuestion'
        });
        await wrapper.setData({ selectedTint: 'Green Tint' });
        // to trigger the computed setter
        wrapper.vm.selectedPartNumber = 'DB12209GTYN';

        // Assert
        expect(wrapper.emitted()['update:modelValue'][0]).toEqual([
            { partNumber: 'DB12209GTYN', color: 'Green Tint' }
        ]);
        expect(listCard.attributes('groupname')).toBe('Rear-Stationary');
        expect(listCard.attributes('validationrules')).toBe('Rear-Stationary-tint-required');
    });

    test('default is selected if only one option', async () => {
        // Arrange
        featureListData.pageData = {
            partsOrQuestions: [
                {
                    glassName: 'Stationary',
                    glassLocation: 'Rear',
                    parts: [{ partNumber: 'DB12209GTYN', color: 'Green Tint' }]
                }
            ]
        };
        const { wrapper } = setupMocks(featureListData);

        // Act
        await wrapper.vm.$nextTick();
        await wrapper.setData({ selectedTint: 'Green Tint' });
        // take emitted value, pass down as modelValue
        // yes, yes, it's not ideal
        await wrapper.setProps({ modelValue: wrapper.emitted()['update:modelValue'][0][0] });
        await wrapper.vm.$nextTick();

        // Assert
        expect(wrapper.vm.selectedPartNumber).toBe('DB12209GTYN');
    });

    const partsForSelectedTintTestCases = [
        [
            'Rear',
            'Stationary',
            'Green Tint',
            [
                { partNumber: 'Glass1', color: 'Green Tint' },
                { partNumber: 'Glass3', color: 'Green Tint' },
                { partNumber: 'Glass4', color: 'Green Tint' },
                { partNumber: 'Glass6', color: 'Green Tint' }
            ]
        ],
        [
            'Rear',
            'Stationary',
            'Blue Tint',
            [
                { partNumber: 'Glass2', color: 'Blue Tint' },
                { partNumber: 'Glass5', color: 'Blue Tint' }
            ]
        ],
        ['Rear', 'Stationary', 'Red Tint', [{ partNumber: 'Glass7', color: 'Red Tint' }]],
        [
            'Windshield',
            'Single',
            'Green Tint',
            [
                { partNumber: 'Windshield1', color: 'Green Tint' },
                { partNumber: 'Windshield2', color: 'Green Tint' }
            ]
        ],
        ['Windshield', 'Single', 'Blue Tint', []],
        ['Driver', 'Quarter', 'Green Tint', []]
    ];

    test.each(partsForSelectedTintTestCases)(
        'partsForSelectedTint returns correct parts',
        async (glassLocation, glassName, selectedTint, expectedResults) => {
            // Arrange
            const pageData = { partsOrQuestions: [
                {
                    glassName: 'Stationary',
                    glassLocation: 'Rear',
                    parts: [
                        { partNumber: 'Glass1', color: 'Green Tint' },
                        { partNumber: 'Glass2', color: 'Blue Tint' },
                        { partNumber: 'Glass3', color: 'Green Tint' },
                        { partNumber: 'Glass4', color: 'Green Tint' },
                        { partNumber: 'Glass5', color: 'Blue Tint' },
                        { partNumber: 'Glass6', color: 'Green Tint' },
                        { partNumber: 'Glass7', color: 'Red Tint' }
                    ]
                },
                {
                    glassName: 'Single',
                    glassLocation: 'Windshield',
                    parts: [
                        { partNumber: 'Windshield1', color: 'Green Tint' },
                        { partNumber: 'Windshield2', color: 'Green Tint' }
                    ]
                }
            ] };
            const { wrapper } = setupMocks({
                glassLocationProp: glassLocation,
                glassNameProp: glassName,
                colorAnswersProp: [],
                pageData
            });

            // Act
            await wrapper.setData({ selectedTint });

            // Assert
            expect(expectedResults).toEqual(wrapper.vm.partsForSelectedTint);
        }
    );
});
