import {
    findMaxChildrenCount,
    getCalculation,
    getClientHighlightColor,
    getClientTexts,
    getConfiguration,
    getSelectedVariantIdentifier,
    getClient,
    getCurrentVisualizationSettings,
    getItem,
    getItemSettings,
    getSelectedAmounts,
    getChildren,
    getUserSelectedCalculation,
    getVisualizationSettings,
    visualizationModeCheck,
    hasMultipleVariantsSelected,
    isSelectedAmountsUpdated,
    getDeepestChildIdentifiers,
    getBulkNames,
    isCalculationAutoResolveEnabled,
    isDesignerProductPreviewMode,
    showItemIdentifier,
    showReceiveOfferForm,
    showCallToAction,
    getCallToAction,
} from '../Selectors';

describe('Reducers/Configurator/Selectors', () => {
    const configurator = {
        configuration: {
            item: {
                identifier: 'demo_hoodie',
                parentItemIdentifier: 'demo_hoodie',
                settings: {
                    visualizationCreator: '2d',
                    visualizationDesigner: '2d',
                },
                title: 'Demo Kaputzenpullover',
                itemGroup: {
                    identifier: 'color',
                    title: 'Farbe',
                    children: [
                        {
                            identifier: 'demo_hoodie_blue_s',
                            title: 'Demo Kaputzenpullover Blau S',
                            children: null,
                            itemGroup: {
                                identifier: 'size',
                                title: 'Größe',
                                children: [
                                    {
                                        identifier: 'demo_hoodie_blue_s',
                                        title: 'Demo Kaputzenpullover Blau S',
                                        children: null,
                                        itemgroupentryIdentifier: 's',
                                        itemgroupentryTitle: 'Größe S',
                                    },
                                    {
                                        identifier: 'demo_hoodie_blue_m',
                                        title: 'Demo Kaputzenpullover Blau M',
                                        children: null,
                                        itemgroupentryIdentifier: 'm',
                                        itemgroupentryTitle: 'Größe M',
                                    },
                                    {
                                        identifier: 'demo_hoodie_blue_l',
                                        title: 'Demo Kaputzenpullover Blau L',
                                        children: null,
                                        itemgroupentryIdentifier: 'l',
                                        itemgroupentryTitle: 'Größe L',
                                    },
                                    {
                                        identifier: 'demo_hoodie_blue_xl',
                                        title: 'Demo Kaputzenpullover Blau XL',
                                        children: null,
                                        itemgroupentryIdentifier: 'xl',
                                        itemgroupentryTitle: 'Größe XL',
                                    },
                                ],
                            },
                            itemgroupentryIdentifier: 'blue',
                            itemgroupentryTitle: 'blau',
                        },
                        {
                            identifier: 'demo_hoodie_green_s',
                            title: 'Demo Kaputzenpullover Grün S',
                            children: null,
                            itemGroup: {
                                identifier: 'size',
                                title: 'Größe',
                                children: [
                                    {
                                        identifier: 'demo_hoodie_green_s',
                                        title: 'Demo Kaputzenpullover Grün S',
                                        children: null,
                                        itemgroupentryIdentifier: 's',
                                        itemgroupentryTitle: 'Größe S',
                                    },
                                    {
                                        identifier: 'demo_hoodie_green_m',
                                        title: 'Demo Kaputzenpullover Grün M',
                                        children: null,
                                        itemgroupentryIdentifier: 'm',
                                        itemgroupentryTitle: 'Größe M',
                                    },
                                    {
                                        identifier: 'demo_hoodie_green_l',
                                        title: 'Demo Kaputzenpullover Grün L',
                                        children: null,
                                        itemgroupentryIdentifier: 'l',
                                        itemgroupentryTitle: 'Größe L',
                                    },
                                    {
                                        identifier: 'demo_hoodie_green_xl',
                                        title: 'Demo Kaputzenpullover Grün XL',
                                        children: null,
                                        itemgroupentryIdentifier: 'xl',
                                        itemgroupentryTitle: 'Größe XL',
                                    },
                                ],
                            },
                            itemgroupentryIdentifier: 'green',
                            itemgroupentryTitle: 'grün',
                        },
                    ],
                },
                itemclassifications: [],
            },
            customdata: {
                selectedAmounts: { demo_hoodie_blue_s: 1, demo_hoodie_green_m: 2 },
            },
        },
        selectedAmountsUpdated: true,
    };
    test('getConfiguration returns the configuration object', () => {
        const configuration = {};
        expect(getConfiguration({ configuration })).toBe(configuration);
    });
    test('getSelectedVariantIdentifier returns the correct identifier', () => {
        expect(getSelectedVariantIdentifier({ selectedVariantIdentifier: 'variantIdentifier' })).toBe(
            'variantIdentifier'
        );
    });
    test('getClient returns the client object', () => {
        const client = {};
        expect(getClient({ client })).toBe(client);
    });
    test('getCalculation returns the calculation object', () => {
        const calculation = {};
        expect(getCalculation({ calculation })).toBe(calculation);
    });
    test('getItem returns the item object', () => {
        const item = {};
        expect(getItem({ configuration: { item } })).toBe(item);
    });
    test('getUserSelectedCalculation returns the user selected calculation object', () => {
        const userSelectedCalculation = {};
        expect(
            getUserSelectedCalculation({ configuration: { customdata: { userSelectedCalculation } } })
        ).toBe(userSelectedCalculation);
    });
    test('getSelectedAmounts returns the selected amounts object', () => {
        const selectedAmounts = {};
        expect(getSelectedAmounts({ configuration: { customdata: { selectedAmounts } } })).toBe(
            selectedAmounts
        );
    });
    test('getBulkNames returns the children objects', () => {
        const bulkNames = { demo_hoddie: ['Lea', 'Martin', 'Luzie'] };
        expect(getBulkNames({ configuration: { customdata: { bulkNames } } })).toBe(bulkNames);
    });
    test('getChildren returns the children objects', () => {
        const children = [{}];
        expect(getChildren({ configuration: { item: { itemGroup: { children } } } })).toBe(children);
    });
    test('findMaxChildrenCount returns the max children length', () => {
        const item = {
            itemGroup: {
                children: [
                    {
                        itemGroup: {
                            children: [{}, {}],
                        },
                    },
                ],
            },
        };
        expect(findMaxChildrenCount(item)).toBe(2);
    });
    test('hasMultipleVariantsSelected returns true if multiple variants selected', () => {
        expect(hasMultipleVariantsSelected(configurator)).toBe(true);
    });
    test('hasMultipleVariantsSelected returns false if only one variant is selected', () => {
        const configurator = {
            configuration: {
                item: {
                    identifier: 'demo_hoodie',
                    parentItemIdentifier: 'demo_hoodie',
                    title: 'Demo Kaputzenpullover',
                    itemGroup: null,
                },
                customdata: {
                    selectedAmounts: { demo_hoodie: 3 },
                },
            },
            selectedAmountsUpdated: true,
        };
        expect(hasMultipleVariantsSelected(configurator)).toBe(false);
    });
    test('hasMultipleVariantsSelected returns false if only one variant is selected with multiple children', () => {
        const configurator = {
            configuration: {
                item: {
                    identifier: 'demo_hoodie',
                    parentItemIdentifier: 'demo_hoodie',
                    title: 'Demo Kaputzenpullover',
                    itemGroup: {
                        identifier: 'color',
                        title: 'Farbe',
                        children: [
                            {
                                identifier: 'demo_hoodie_blue_s',
                                title: 'Demo Kaputzenpullover Blau S',
                                children: null,
                                itemGroup: null,
                                itemgroupentryIdentifier: 'blue',
                                itemgroupentryTitle: 'blau',
                            },
                            {
                                identifier: 'demo_hoodie_green_s',
                                title: 'Demo Kaputzenpullover Grün S',
                                children: null,
                                itemGroup: null,
                                itemgroupentryIdentifier: 'green',
                                itemgroupentryTitle: 'grün',
                            },
                        ],
                    },
                },
                customdata: {
                    selectedAmounts: { demo_hoodie_blue_s: 1 },
                },
            },
            selectedAmountsUpdated: true,
        };
        expect(hasMultipleVariantsSelected(configurator)).toBe(false);
    });
    test('hasMultipleVariantsSelected returns false (and does not fail) if the identifiers does not match', () => {
        const configurator = {
            configuration: {
                item: {
                    identifier: 'demo_hoodie',
                    parentItemIdentifier: 'demo_hoodie',
                    title: 'Demo Kaputzenpullover',
                    itemGroup: null,
                },
                customdata: {
                    selectedAmounts: { demo_hoodie_blue_s: 1, demo_hoodie_green_m: 2 },
                },
            },
            selectedAmountsUpdated: true,
        };
        expect(hasMultipleVariantsSelected(configurator)).toBe(false);
    });
    test('hasMultipleVariantsSelected returns true (and does not fail) if the variant does not have further (level 2) children', () => {
        const configurator = {
            configuration: {
                item: {
                    identifier: 'demo_hoodie',
                    parentItemIdentifier: 'demo_hoodie',
                    title: 'Demo Kaputzenpullover',
                    itemGroup: {
                        identifier: 'color',
                        title: 'Farbe',
                        children: [
                            {
                                identifier: 'demo_hoodie_blue_s',
                                title: 'Demo Kaputzenpullover Blau S',
                                children: null,
                                itemGroup: null,
                                itemgroupentryIdentifier: 'blue',
                                itemgroupentryTitle: 'blau',
                            },
                            {
                                identifier: 'demo_hoodie_green_s',
                                title: 'Demo Kaputzenpullover Grün S',
                                children: null,
                                itemGroup: null,
                                itemgroupentryIdentifier: 'green',
                                itemgroupentryTitle: 'grün',
                            },
                        ],
                    },
                },
                customdata: {
                    selectedAmounts: { demo_hoodie_blue_s: 1, demo_hoodie_green_s: 2 },
                },
            },
            selectedAmountsUpdated: true,
        };
        expect(hasMultipleVariantsSelected(configurator)).toBe(true);
    });
    test('isSelectedAmountsUpdated return correct state value', () => {
        expect(isSelectedAmountsUpdated(configurator)).toEqual(true);
    });
    test('getDeepestChildIdentifiers return correct values', () => {
        expect(getDeepestChildIdentifiers(configurator.configuration.item.itemGroup.children[0])).toEqual({
            l: 'demo_hoodie_blue_l',
            m: 'demo_hoodie_blue_m',
            s: 'demo_hoodie_blue_s',
            xl: 'demo_hoodie_blue_xl',
        });
    });
    test('getItemSettings returns the settings of the configuration item', () => {
        const settings = {
            visualizationCreator: '3d',
            visualizationDesigner: '2d',
        };

        expect(
            getItemSettings({
                configuration: {
                    item: {
                        settings,
                    },
                },
            })
        ).toEqual(settings);
    });
    test(
        'getVisualizationSettings returns an object which contains the visualization names ' +
            'for the creator and designer modules',
        () => {
            const result = {
                creator: '3d',
                designer: '2d',
            };

            expect(
                getVisualizationSettings({
                    configuration: {
                        item: {
                            settings: {
                                visualizationCreator: '3d',
                                visualizationDesigner: '2d',
                            },
                        },
                    },
                })
            ).toEqual(result);
        }
    );
    test(
        'getCurrentVisualizationSettings returns the correct visualization type ' +
            'for the current configuration mode',
        () => {
            const globalState = {
                configurator: {
                    configuration: {
                        item: {
                            settings: {
                                visualizationCreator: '3d',
                                visualizationDesigner: '2d',
                            },
                        },
                    },
                },
                configurationMode: {
                    selectedMode: 'designer',
                },
            };

            expect(getCurrentVisualizationSettings(globalState)).toEqual('2d');
        }
    );
    test('getCurrentVisualizationSettings returns "default" if the related setting is not defined', () => {
        const globalState = {
            configurator: {
                configuration: {
                    item: {
                        settings: {
                            visualizationCreator: null,
                            visualizationDesigner: '2d',
                        },
                    },
                },
            },
            configurationMode: {
                selectedMode: 'creator',
            },
        };

        expect(getCurrentVisualizationSettings(globalState)).toEqual('default');
    });
    test('visualizationModeCheck functions return true only if the queried design mode is active', () => {
        let checkFunctions;

        checkFunctions = visualizationModeCheck({
            configurator: {
                configuration: {
                    item: {
                        settings: {
                            visualizationCreator: '3d',
                            visualizationDesigner: '2d',
                        },
                    },
                },
            },
            configurationMode: {
                selectedMode: 'designer',
            },
        });

        expect(checkFunctions.is2D()).toEqual(true);
        expect(checkFunctions.is3D()).toEqual(false);
        expect(checkFunctions.isDefault()).toEqual(false);

        checkFunctions = visualizationModeCheck({
            configurator: {
                configuration: {
                    item: {
                        settings: {
                            visualizationCreator: '3d',
                            visualizationDesigner: '2d',
                        },
                    },
                },
            },
            configurationMode: {
                selectedMode: 'creator',
            },
        });

        expect(checkFunctions.is2D()).toEqual(false);
        expect(checkFunctions.is3D()).toEqual(true);
        expect(checkFunctions.isDefault()).toEqual(false);

        checkFunctions = visualizationModeCheck({
            configurator: {
                configuration: {
                    item: {
                        settings: {},
                    },
                },
            },
            configurationMode: {
                selectedMode: 'designer',
            },
        });

        expect(checkFunctions.is2D()).toEqual(false);
        expect(checkFunctions.is3D()).toEqual(false);
        expect(checkFunctions.isDefault()).toEqual(true);
    });

    test('getClientHighlightColor returns the correct value', () => {
        expect(
            getClientHighlightColor({
                configurator: {
                    client: {
                        theme: {
                            highlightColor: '#abc',
                        },
                    },
                },
            })
        ).toEqual('#abc');
    });

    test('getClientTexts returns the correct value', () => {
        expect(
            getClientTexts({
                client: {
                    texts: {
                        termsAndConditionsLink: 'fakeLink',
                    },
                },
            })
        ).toEqual({ termsAndConditionsLink: 'fakeLink' });
    });

    test('isCalculationAutoResolveEnabled returns true only if its value is really true (not just truthy)', () => {
        expect(
            isCalculationAutoResolveEnabled({
                calculationAutoResolve: 'skipNext',
            })
        ).toBe(false);
        expect(
            isCalculationAutoResolveEnabled({
                calculationAutoResolve: true,
            })
        ).toBe(true);
    });

    test('isDesignerProductPreviewMode returns true if the given pathname contains /designer-preview-widget', () => {
        expect(isDesignerProductPreviewMode('/designer-preview-widget')).toBe(true);
    });
    test('isDesignerProductPreviewMode returns false if the given pathname does not contain /designer-preview-widget', () => {
        expect(isDesignerProductPreviewMode('/identifier:demo_hoodie')).toBe(false);
    });
    test('showItemIdentifier returns the correct value', () => {
        const globalState = {
            configuration: {
                information: {
                    settings: {
                        show_item_identifier: true,
                    },
                },
            },
        };
        expect(showItemIdentifier(globalState)).toBe(true);
    });
    test('showItemIdentifier returns the default value', () => {
        expect(showItemIdentifier({})).toBe(false);
    });
    test('getCallToAction returns the correct value', () => {
        const globalState = {
            configuration: {
                item: {
                    callToAction: 'hello world',
                },
            },
        };
        expect(getCallToAction(globalState)).toBe('hello world');
    });
    test('getCallToAction returns the default value', () => {
        expect(getCallToAction({})).toBe('addToBasket');
    });
    test('showCallToAction returns the correct value', () => {
        const globalState = {
            configuration: {
                item: {
                    callToAction: 'none',
                },
            },
        };
        expect(showCallToAction(globalState)).toBe(false);
    });
    test('showReceiveOfferForm returns the correct value', () => {
        const globalState = {
            configuration: {
                item: {
                    callToAction: 'requestOffer',
                },
            },
        };
        expect(showReceiveOfferForm(globalState)).toBe(true);
    });
});
