import { get, pick, without } from 'lodash';
import createReducer from 'bitbucket/internal/bbui/utils/create-reducer';
import { CLEAR_REPOSITORIES, LOAD_REPOSITORIES_SUCCESS } from '../actions';

export default createReducer({}, {
    /**
     * Handles successful load of a page of repositories. It sets or updates the list of repository ids for a particular
     * RepositoryType (the repositories themselves are stored by the repositories reducer), as well the paging
     * information for the last loaded page, optionally the query and a callback to load more pages (which is used by
     * search)
     *
     * @param {Object} state
     * @param {Object} action
     * @param {RepositoryType} action.meta.repoType - type of repositories that were loaded
     * @param {string?} action.meta.query - the search query if this was a search
     * @param {Function?} action.meta.loadMoreCallback - for a search, the callback to get the next page of results
     * @param {Object} action.payload - a page of repositories
     * @returns {Object}
     */
    [LOAD_REPOSITORIES_SUCCESS](state, action) {
        const repoType = action.meta.repoType;
        let repositories;
        const newRepositories = action.payload.values.map(repo => repo.id);

        // if there's a query, and it's different, then REPLACE the repos, else concat
        if (get(action, 'meta.query') !== get(state, [repoType, 'query'])) {
            repositories = newRepositories;
        } else {
            repositories = get(state, [repoType, 'repositories'], []).concat(newRepositories)
        }

        return {
            ...state,
            [repoType]: {
                query: get(action, 'meta.query'),
                lastPageMeta: pick(action.payload, without(Object.keys(action.payload), 'values')),
                repositories,
                loadMoreCallback: get(action, 'meta.nextSearch'),
            }
        }
    },
    /**
     * Clears a list of repositories - usually triggered when a search query is removed.
     * @param {Object} state
     * @param {Object} action
     * @param {RepositoryType} action.meta.repoType - the RepositoryType that was cleared
     * @returns {Object}
     */
    [CLEAR_REPOSITORIES](state, action) {
        return {
            ...state,
            [action.meta.repoType]: undefined
        };
    }
});