import designViewReducer from '../Reducer';
import {
    RECEIVE_CONFIGURATION,
    RECEIVE_DESIGNER_DATA,
    receiveDesignerData,
} from '../../Configurator/Actions';
import { response, simpleState } from '../__mocks__/designerViewData';
import { selectDesignView } from '../Actions';

describe('Reducers/DesignView.designViewReducer', () => {
    test('returns the correct initial state', () => {
        const initialState = designViewReducer();
        expect(initialState).toEqual({
            designViews: [],
            selectedDesignView: {},
            autogeneratedDesignViews: [],
            viewThumbnailImages: [],
        });
    });
    test('returns the correct state for RECEIVE_DESIGNER_DATA action', () => {
        const initialState = designViewReducer();

        const action = receiveDesignerData(response)(
            v => v /* mock dispatch */,
            () => null /* mock getState */
        );

        const state = designViewReducer(initialState, action);

        // the design view has the correct values from the response
        // and does not select any of the views initially
        expect(state).toEqual({
            ...initialState,
            designViews: response.designViews,
            selectedDesignView: {},
        });
    });
    test('returns the correct state for SELECT_DESIGN_VIEW action', () => {
        const initialState = designViewReducer(simpleState);
        const identifier = simpleState.designViews[0].identifier;
        const action = selectDesignView(identifier);
        const state = designViewReducer(initialState, action);
        expect(state.selectedDesignView.identifier).toBe(identifier);
    });
    test('clears the selectedDesignView for RECEIVE_CONFIGURATION action', () => {
        const initialState = designViewReducer(simpleState);
        const identifier = simpleState.designViews[0].identifier;
        const selectDesignViewAction = selectDesignView(identifier);
        const stateWithSelectedDesignView = designViewReducer(initialState, selectDesignViewAction);
        // check if the selectedDesignView is not empty first
        expect(stateWithSelectedDesignView.selectedDesignView.identifier).toBe(identifier);
        const action = { type: RECEIVE_CONFIGURATION };
        const state = designViewReducer(stateWithSelectedDesignView, action);
        expect(state.selectedDesignView).toEqual({});
    });
    test(
        'creates the designViews list and sets the selectedDesignView if visualizationData is available ' +
            'in the configuration (2D layering visualization)',
        () => {
            const initialState = designViewReducer();
            const receiveConfigurationAction = {
                type: RECEIVE_CONFIGURATION,
                data: {
                    visualizationData: {
                        viewImages: {
                            front: ['/path/to/image/front/1', '/path/to/image/front/2'],
                            side: ['/path/to/image/side/1', '/path/to/image/side/2'],
                        },
                    },
                },
            };
            const state = designViewReducer(initialState, receiveConfigurationAction);
            expect(state.designViews).toEqual([
                {
                    identifier: 'front',
                },
                {
                    identifier: 'side',
                },
            ]);
            expect(state.selectedDesignView).toEqual({
                identifier: 'front',
            });
        }
    );

    test('orders designAreas by size of all designViews when receiving designer data', () => {
        const initialState = designViewReducer();
        const receiveDesignerDataAction = {
            type: RECEIVE_DESIGNER_DATA,
            data: {
                designViews: [
                    {
                        designAreas: [
                            {
                                identifier: 'smallerArea',
                                baseShape: { width: 1, height: 1 },
                            },
                            {
                                identifier: 'largerArea',
                                baseShape: { width: 2, height: 1 },
                            },
                        ],
                    },
                ],
            },
        };

        const state = designViewReducer(initialState, receiveDesignerDataAction);

        expect(state.designViews[0].designAreas[0].identifier).toBe('largerArea');
        expect(state.designViews[0].designAreas[1].identifier).toBe('smallerArea');
    });

    test('RECEIVE_DESIGNER_DATA action returns the merged designViews if the configuration already added some (viewImages)', () => {
        const initialState = designViewReducer();

        const receiveConfigurationAction = {
            type: RECEIVE_CONFIGURATION,
            data: {
                visualizationData: {
                    viewImages: {
                        front_view: ['/path/to/image/front_view/1', '/path/to/image/front_view/2'],
                        top_view: ['/path/to/image/top_view/1', '/path/to/image/top_view/2'],
                    },
                },
            },
        };
        const stateWithDesignViews = designViewReducer(initialState, receiveConfigurationAction);

        const action = receiveDesignerData(response)(
            v => v /* mock dispatch */,
            () => null /* mock getState */
        );

        const state = designViewReducer(stateWithDesignViews, action);

        // the design views contain only the ones with viewImages (the rest cannot be visualized),
        // in this case front_view and top_view
        expect(state.designViews.length).toBe(2);
        expect(state.designViews[0].identifier).toBe('front_view');
        expect(state.designViews[1].identifier).toBe('top_view');
    });
});
