import { actionTypes as designViewActionTypes } from './Actions';
import find from 'lodash/find';
import get from 'lodash/get';
import * as configuratorActionTypes from '../Configurator/Actions';
import { compareDesignAreasBySize } from './Transformers';
import { getConfigurationModes } from '../ConfigurationMode/Selectors';

const orderDesignAreasBySize = designAreas => designAreas && [...designAreas].sort(compareDesignAreasBySize);

const prepareDesignViews = designViews =>
    designViews.map(designView => ({
        ...designView,
        designAreas: orderDesignAreasBySize(designView.designAreas),
    }));

const initialState = {
    designViews: [],
    selectedDesignView: {},
    autogeneratedDesignViews: [],
    viewThumbnailImages: [],
};

export default function designViewReducer(state = initialState, action = {}) {
    switch (action.type) {
        case designViewActionTypes.SELECT_DESIGN_VIEW: {
            const { designViewIdentifier } = action;
            const designView = find(state.designViews, { identifier: designViewIdentifier });
            return {
                ...state,
                selectedDesignView: designView,
            };
        }
        case configuratorActionTypes.RECEIVE_DESIGNER_DATA: {
            const { autogeneratedDesignViews } = state;

            const {
                data: { designViews },
            } = action;

            if (!designViews || !designViews.length) {
                // if there are no design views defined, use the autogenerated ones as fallback
                // use-case: missing visual maintenance setup for layer type visualization (designer only)
                if (autogeneratedDesignViews.length) {
                    return {
                        ...state,
                        designViews: autogeneratedDesignViews,
                    };
                }
                return state;
            }

            if (autogeneratedDesignViews.length) {
                // if the design views are already defined by the viewImages they need to be merged
                const updatedDesignViews = autogeneratedDesignViews.map(designView => ({
                    ...designViews.find(({ identifier }) => designView.identifier === identifier),
                    ...designView,
                }));
                return {
                    ...state,
                    designViews: prepareDesignViews(updatedDesignViews),
                    selectedDesignView: {},
                };
            }
            return {
                ...state,
                designViews: prepareDesignViews(designViews),
                selectedDesignView: {},
            };
        }
        case configuratorActionTypes.RECEIVE_CONFIGURATION: {
            const viewImages = get(action, 'data.visualizationData.viewImages');
            const viewIdentifiers = viewImages && Object.keys(viewImages);
            if (viewIdentifiers && viewIdentifiers.length) {
                const viewThumbnailImages = get(action, 'data.visualizationData.viewThumbImages');
                const autogeneratedDesignViews = viewIdentifiers.map(identifier => ({
                    identifier,
                }));
                // if designer mode is enabled, the design views are loaded in a separate action
                // so it's not stored directly as designViews
                if (getConfigurationModes(get(action, 'data.item')).designer) {
                    return {
                        ...state,
                        designViews: [],
                        selectedDesignView: {},
                        autogeneratedDesignViews,
                        viewThumbnailImages,
                    };
                }
                // otherwise designViews are not expected from other actions
                // so the autogenerated ones should be used as fallback
                const selectedDesignView = autogeneratedDesignViews[0];
                return {
                    ...state,
                    designViews: autogeneratedDesignViews,
                    selectedDesignView,
                    autogeneratedDesignViews,
                    viewThumbnailImages,
                };
            }
            // receiving a new configuration should always reset the design view state to not mix them up
            return {
                ...state,
                designViews: [],
                selectedDesignView: {},
                autogeneratedDesignViews: [],
                viewThumbnailImages: [],
            };
        }
    }
    return state;
}
