import _ from 'lodash';
import { Promise } from 'rsvp';

import ApplicationStore from 'stores/Application';
import GroupStore from 'stores/Groups';

import userApi from 'api/user';
import departmentApi from 'api/department';
import groupApi from 'api/group';
import orgProfileApi from 'api/org.profile';
import { start, succeed, succeedAll, fail } from './handlers';

export default {
    showUser,
    showDepartment,
    showGroup,
    showGroups,
    showGroupMember,
    showRootDepartment,
    showOrgProfile,
};

function showUser(id) {
    start();

    return userApi.read({ id, extension: 'auto' }).then(succeed)
        .catch(fail);
}

function showDepartment(id) {
    start();

    return departmentApi.read({ id, extension: 'auto' }).then(succeed)
        .catch(fail);
}

function showGroup(subsection, id) {
    const isSectionOpen = subsection === ApplicationStore.getSubsectionName();
    const isGroupAvailable = Boolean(id && GroupStore.get(id));

    const extension = isSectionOpen && isGroupAvailable ? 'shallow' : 'deep';

    start();

    return groupApi.read({ id, extension, subsection, type: 'generic' }).then(succeed)
        .catch(fail);
}

function showGroups(subsection) {
    return showGroup(subsection);
}

function showGroupMember(subsection, groupId, member) {
    const isSectionOpen = subsection === ApplicationStore.getSubsectionName();
    const isGroupAvailable = Boolean(groupId && GroupStore.get(groupId));

    const extension = isSectionOpen && isGroupAvailable ? 'shallow' : 'deep';

    start();

    const groupRequest = groupApi.read({
        id: groupId, extension, subsection,
    });

    const requestOptions = {
        id: member.id, extension: 'shallow',
    };
    let nestedObjectRequest;

    switch (member.type) {
        case 'user':
            nestedObjectRequest = userApi.read(requestOptions);
            break;
        case 'department':
            nestedObjectRequest = departmentApi.readFlat(requestOptions);
            break;
        case 'group':
            nestedObjectRequest = groupApi.readFlat(requestOptions);
            break;
    }

    const requests = [groupRequest];

    if (nestedObjectRequest) {
        nestedObjectRequest = nestedObjectRequest.then(response => {
            // убираем из ответа на nestedObjectRequest команды, уже имеющиеся в сторе,
            // чтобы не перезатереть команды из groupRequest неполными данными;
            // неполные данные о командах, которые приходят в nestedObjectRequest и
            // которых нет в сторе, оставляем, их достаточно для отображения информации
            // о вложенном объекте
            if (response && response.groups) {
                // отфильтровываем команды, уже имеющиеся в сторе, и команду с groupId,
                // загружающуюся в groupRequest
                const groupFilter = group => !GroupStore.get(group.id) && group.id !== groupId;
                const newIds = _.filter(response.groups, groupFilter).map(group => group.id);

                response.groups = _.pick(response.groups, newIds);
            }

            return _.omit(response, ['permissions']);
        });
        requests.push(nestedObjectRequest);
    }

    return Promise.all(requests).then(succeedAll).catch(fail);
}

function showRootDepartment() {
    start();

    return departmentApi.read({ extension: 'auto' }).then(succeed)
        .catch(fail);
}

function showOrgProfile() {
    start();

    return orgProfileApi.read().then(succeed)
        .catch(fail);
}
