import u from 'updeep';
import { mapValues } from 'lodash';

export function buildUpreducer(initial, mutations, subduxes = {}) {
    const subReducers =
        Object.keys(subduxes).length > 0
            ? mapValues(subduxes, ({ upreducer }) => upreducer)
            : null;

    return (action) => (state) => {
        if (!action?.type)
            throw new Error('upreducer called with a bad action');

        let newState = state ?? initial;

        if (subReducers) {
            if (subduxes['*']) {
                newState = u.updateIn(
                    '*',
                    subduxes['*'].upreducer(action),
                    newState
                );
            } else {
                const update = mapValues(subReducers, (upReducer) =>
                    upReducer(action)
                );

                newState = u(update, newState);
            }
        }

        const a = mutations[action.type] || mutations['+'];

        if (!a) return newState;

        return a(action.payload, action)(newState);
    };
}
