import get from 'lodash/get';
import find from 'lodash/find';

import * as configuratorActionTypes from '../Configurator/Actions';
import { actionTypes as designAreaActionTypes } from './Actions';
import { processConfigurationModes, recalculateDesignAreas } from './Transformers';
import { getSelectedDesignProductionMethodForDesignArea } from './Selectors';
import { visualizationModeCheck } from '../Configurator/Selectors';

const initialState = {
    filteredDesignAreas: [],
    selectedDesignArea: {},
    previousEditedDesignArea: {},
    initialCanvasPosition: [],
    showHighlight: true,
};

export function designAreaReducer(state, action = {}) {
    switch (action.type) {
        case configuratorActionTypes.RECEIVE_DESIGNER_DATA: {
            const { data, globalState } = action;
            const nextState = {
                ...state,
                ...processConfigurationModes(data),
            };
            return recalculateDesignAreas(
                nextState,
                getDesignProductionMethodMap(globalState, nextState.filteredDesignAreas),
                visualizationModeCheck(globalState)
            );
        }
        case designAreaActionTypes.SELECT_DESIGN_AREA: {
            const { designAreaIdentifier } = action;
            const designArea = find(state.filteredDesignAreas, { identifier: designAreaIdentifier });
            if (!designArea) {
                return state;
            }
            return {
                ...state,
                selectedDesignArea: designArea,
                showHighlight: false,
            };
        }
        case designAreaActionTypes.SET_PREVIOUS_EDITED_DESIGN_AREA: {
            const { designAreaIdentifier } = action;
            const designArea = find(state.filteredDesignAreas, { identifier: designAreaIdentifier });
            return {
                ...state,
                previousEditedDesignArea: designArea,
            };
        }
        case designAreaActionTypes.CLEAR_DESIGN_AREA_SELECTION: {
            return {
                ...state,
                selectedDesignArea: {},
                lastSelectedDesignAreaIdentifier: get(state, 'selectedDesignArea.identifier', ''),
                showHighlight: true,
            };
        }
        case designAreaActionTypes.TOGGLE_HIGHLIGHT: {
            const { showHighlight } = action;
            return {
                ...state,
                showHighlight: showHighlight,
            };
        }
        case designAreaActionTypes.RECALCULATE_DESIGN_AREA: {
            const { globalState } = action;
            return recalculateDesignAreas(
                state,
                getDesignProductionMethodMap(globalState, state.filteredDesignAreas),
                visualizationModeCheck(globalState)
            );
        }
    }
    return state;
}

function getDesignProductionMethodMap(globalState, designAreas) {
    return designAreas.reduce(
        (designProductionMethodMap, designArea) => ({
            ...designProductionMethodMap,
            [designArea.identifier]: getSelectedDesignProductionMethodForDesignArea(globalState, designArea),
        }),
        {}
    );
}

export function configurationChangeReducer(state, action = {}) {
    switch (action.type) {
        case configuratorActionTypes.RECEIVE_CONFIGURATION: {
            return {
                ...state,
                // clean up data if a new configuration comes (it fetches its own designer data anyway)
                // this also triggers the removal of current canvases leading to a fresh init of the new ones
                filteredDesignAreas: [],
                selectedDesignArea: {},
                previousEditedDesignArea: {},
                initialCanvasPosition: [],
            };
        }
        default:
            return state;
    }
}

export default function combinedDesignAreaReducer(state = initialState, action = {}) {
    return [designAreaReducer, configurationChangeReducer].reduce(function(state, reducerFn) {
        return reducerFn(state, action);
    }, state);
}
