import configurationModeReducer from '../Reducer';
import { RECEIVE_CONFIGURATION } from '../../Configurator/Actions';
import { SELECT_CONFIGURATION_MODE } from '../Actions';
import { setConf } from '../../../configuration';

describe('Reducers/ConfigurationMode.configurationModeReducer', () => {
    describe(
        'stores the first available mode in selectedMode and all available modes in availableModes ' +
            'on the RECEIVE_CONFIGURATION action',
        () => {
            test('with creator only', () => {
                const configuration = {
                    item: {
                        configurationModes: [
                            {
                                identifier: 'designer',
                                itemStatus: {
                                    item_available: false,
                                },
                            },
                            {
                                identifier: 'creator',
                                itemStatus: {
                                    item_available: true,
                                },
                            },
                        ],
                    },
                };
                const configurationModeState = configurationModeReducer(
                    {},
                    {
                        type: RECEIVE_CONFIGURATION,
                        data: configuration,
                    }
                );
                expect(configurationModeState.selectedMode).toBe('creator');
                expect(configurationModeState.availableModes).toEqual({ creator: true });
            });
            test('with both creator and designer', () => {
                const configuration = {
                    item: {
                        configurationModes: [
                            {
                                identifier: 'designer',
                                itemStatus: {
                                    item_available: true,
                                },
                            },
                            {
                                identifier: 'creator',
                                itemStatus: {
                                    item_available: true,
                                },
                            },
                        ],
                    },
                };
                const configurationModeState = configurationModeReducer(
                    {},
                    {
                        type: RECEIVE_CONFIGURATION,
                        data: configuration,
                    }
                );
                expect(configurationModeState.selectedMode).toBe('designer');
                expect(configurationModeState.availableModes).toEqual({ creator: true, designer: true });
            });
            test('with no available mode', () => {
                const configuration = {
                    item: {
                        configurationModes: [
                            {
                                identifier: 'designer',
                                itemStatus: {
                                    item_available: false,
                                },
                            },
                            {
                                identifier: 'creator',
                                itemStatus: {
                                    item_available: false,
                                },
                            },
                        ],
                    },
                };
                const configurationModeState = configurationModeReducer(
                    {},
                    {
                        type: RECEIVE_CONFIGURATION,
                        data: configuration,
                    }
                );
                expect(configurationModeState.selectedMode).toBeNull();
                expect(configurationModeState.availableModes).toEqual({});
            });
        }
    );

    describe('sets the selectedMode on SELECT_CONFIGURATION_MODE action if possible', () => {
        test('with available and valid mode', () => {
            const configuration = {
                item: {
                    configurationModes: [
                        {
                            identifier: 'designer',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                        {
                            identifier: 'creator',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                    ],
                },
            };
            const initialState = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configuration,
                }
            );
            expect(initialState.selectedMode).toBe('designer');
            const stateAfterModeChange = configurationModeReducer(initialState, {
                type: SELECT_CONFIGURATION_MODE,
                mode: 'creator',
            });
            expect(stateAfterModeChange.selectedMode).toBe('creator');
        });
        test('with not available mode', () => {
            const configuration = {
                item: {
                    configurationModes: [
                        {
                            identifier: 'designer',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                        {
                            identifier: 'creator',
                            itemStatus: {
                                item_available: false,
                            },
                        },
                    ],
                },
            };
            const initialState = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configuration,
                }
            );
            expect(initialState.selectedMode).toBe('designer');
            const stateAfterModeChange = configurationModeReducer(initialState, {
                type: SELECT_CONFIGURATION_MODE,
                mode: 'creator',
            });
            expect(stateAfterModeChange.selectedMode).toBe('designer');
        });
        test('with not valid mode', () => {
            const stateAfterModeChange = configurationModeReducer(
                { selectedMode: 'designer', availableModes: {} },
                {
                    type: SELECT_CONFIGURATION_MODE,
                    mode: 'non_valid_mode',
                }
            );
            expect(stateAfterModeChange.selectedMode).toBe('designer');
        });
    });

    describe('RECEIVE_CONFIGURATION action sets license', () => {
        test('licenses are set on RECEIVE_CONFIGURATION action', () => {
            const configuration = {
                license: 'designer+creator',
            };
            const state = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configuration,
                }
            );
            expect(state.licenses).toStrictEqual(['designer', 'creator']);
        });
    });

    describe('RECEIVE_CONFIGURATION action sets selectedMode based on applicationConfiguration', () => {
        test('creator is set when adminMode is defaultOptions', () => {
            setConf('adminMode', 'defaultoptions');
            const configuration = {
                item: {
                    configurationModes: [
                        {
                            identifier: 'designer',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                        {
                            identifier: 'creator',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                    ],
                },
            };
            const state = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configuration,
                }
            );
            expect(state.selectedMode).toStrictEqual('creator');
        });
        test('designer is set when adminMode dont have defaultOptions', () => {
            setConf('adminMode', '');
            const configuration = {
                item: {
                    configurationModes: [
                        {
                            identifier: 'designer',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                        {
                            identifier: 'creator',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                    ],
                },
            };
            const state = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configuration,
                }
            );
            expect(state.selectedMode).toStrictEqual('designer');
        });

        test('the `configurationMode` value sets the preselected mode correctly if available', () => {
            setConf('adminMode', 'quickView');
            setConf('configurationMode', 'designer');
            const configuration = {
                item: {
                    configurationModes: [
                        {
                            identifier: 'creator',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                        {
                            identifier: 'designer',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                    ],
                },
            };
            const state = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configuration,
                }
            );
            expect(state.selectedMode).toStrictEqual('designer');

            setConf('configurationMode', 'creator');
            const state2 = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configuration,
                }
            );
            expect(state2.selectedMode).toStrictEqual('creator');

            // ignore the preselected configuration mode if it is not available
            setConf('configurationMode', 'creator');
            const configurationWithDesignerModeOnly = {
                item: {
                    configurationModes: [
                        {
                            identifier: 'designer',
                            itemStatus: {
                                item_available: true,
                            },
                        },
                    ],
                },
            };
            const state3 = configurationModeReducer(
                {},
                {
                    type: RECEIVE_CONFIGURATION,
                    data: configurationWithDesignerModeOnly,
                }
            );
            expect(state3.selectedMode).toStrictEqual('designer');
        });
    });
});
