const React = require('react');
const isEqual = require('lodash.isequal');

const readyResourceForRequest = (resources, request) => {
    return resources.reduce((result, resource) => {
        if (resource.content.type === 'Ready' && isEqual(resource.request, request)) {
            return resource;
        }

        return result;
    }, null);
};

const reducer = (state, action) => {
    switch (action.type) {
        case 'resources-changed': {
            if (state.selected.resource === null ||
                !state.selected.byUser ||
                readyResourceForRequest(action.resources, state.selected.resource.request) === null) {
                const selectedResource = action.resources.reduce((result, resource) => {
                    if (resource.content.type === 'Ready') {
                        return resource;
                    }

                    return result;
                }, null);
                return {
                    ...state,
                    resourceRef: action.resourceRef,
                    resources: action.resources,
                    selected: {
                        resource: selectedResource,
                        byUser: false
                    }
                };
            }

            return {
                ...state,
                resourceRef: action.resourceRef,
                resources: action.resources
            };
        }
        case 'resource-selected': {
            const selectedResource = readyResourceForRequest(state.resources, action.request);
            if (selectedResource !== null) {
                return {
                    ...state,
                    selected: {
                        resource: selectedResource,
                        byUser: true
                    }
                };
            }

            return state;
        }
        default: {
            return state;
        }
    }
};

const initializer = ([resourceRef, resources]) => {
    const initialState = {
        resourceRef: null,
        resources: [],
        selected: {
            resource: null,
            byUser: false
        }
    };
    const initAction = {
        type: 'resources-changed',
        resourceRef,
        resources
    };

    return reducer(initialState, initAction);
};

const useSelectableResource = (resourceRef, resources) => {
    const [state, dispatch] = React.useReducer(
        reducer,
        [resourceRef, resources],
        initializer
    );
    const selectResource = React.useCallback((request) => {
        dispatch({ type: 'resource-selected', request });
    }, []);
    React.useEffect(() => {
        dispatch({ type: 'resources-changed', resourceRef, resources });
    }, [resourceRef, resources]);
    return [state.resourceRef, state.resources, state.selected.resource, selectResource];
};

module.exports = useSelectableResource;
