import _ from 'lodash';
import { ActionTypes } from 'constants/Common';
import dispatcher from 'dispatcher';
import Url from 'lib/Url';
import getErrors from 'lib/getErrors';
import departmentApi from 'api/department';
import sync from 'services/sync';

import ApplicationStore from 'stores/Application';
import DepartmentStore from 'stores/Departments';
import UsersStore from 'stores/Users';
import AppActions from 'actions/App/OrgStructure';

export default {
    createDepartment,
    updateDepartment,
    removeDepartment,
    addMembers,
    getList,
    readRoot,
};

/**
 * Создание нового отдела
 * @method  createDepartment
 * @param   {Object}   data
 * @returns {Promise}
 */
function createDepartment(data) {
    return departmentApi.create(data).then(response => {
        const errors = getErrors(response);

        if (!errors.isEmpty()) {
            return { errors };
        }

        dispatcher.dispatch(ActionTypes.RECEIVE_MIXED_DATA, response);

        const id = (_.find(response.sources, { type: 'department' }) || {}).id;

        if (id) {
            Url.open(Url.getDepartmentPath(id));
        }

        sync.refreshDepartmentCounters([data.parent_id]);
    });
}

/**
 * Обновление данных об отделе
 * @method updateDepartment
 * @param  {Object}    data
 * @param  {String}    id - id отдела
 * @returns {Promise}
 */
function updateDepartment(data, id) {
    const originalDepartment = DepartmentStore.get(id);
    const originalParent = originalDepartment ? originalDepartment.get('parent') : null;

    return departmentApi.update(data, id).then(response => {
        const errors = getErrors(response);

        if (!errors.isEmpty()) {
            return { errors };
        }

        dispatcher.dispatch(ActionTypes.RECEIVE_MIXED_DATA, response);
        AppActions.showDepartment(id);

        const department = DepartmentStore.get(id);
        const parent = department ? department.get('parent') : null;

        if (parent !== originalParent) {
            sync.refreshDepartmentCounters([originalParent, parent]);
        }
    });
}

/**
 * Удаление отдела
 * @method removeDepartment
 * @param  {String}    id - id отдела
 * @returns {Promise}
 */
function removeDepartment(id) {
    const department = DepartmentStore.get(id);
    const parentId = department ? department.get('parent') : null;

    return departmentApi.remove(id).then(response => {
        const errors = getErrors(response);

        if (!errors.isEmpty()) {
            return { errors };
        }

        dispatcher.dispatch(ActionTypes.DISCARD_DEPARTMENT, { id });

        if (parentId) {
            Url.open(Url.getDepartmentPath(parentId));
        } else {
            Url.open(Url.getContextPath('/'));
        }
    });
}

/**
 * Обновление состава отдела
 * @method addMembers
 * @param  {Object}    data
 * @param  {String}    id - id отдела
 * @returns {Promise}
 */
function addMembers(data, id) {
    return departmentApi.addMembers(data, id).then(response => {
        const errors = getErrors(response);

        if (!errors.isEmpty()) {
            return { errors };
        }

        const sectionValues = ApplicationStore.getSectionValues();
        const [sectionName] = sectionValues;
        let sectionId = sectionValues[1];

        switch (sectionName) {
            case 'departments':
                break;
            case 'users': {
                const user = UsersStore.get(sectionId);

                if (user) {
                    sectionId = user.get('department') || id;
                }
                break;
            }
            default:
                sectionId = id;
        }

        AppActions.showDepartment(sectionId);
        sync.refreshDepartmentCounters([sectionId]);
    });
}

function getList(options) {
    return departmentApi.getList(options)
        .then(response => {
            const errors = getErrors(response);

            if (!errors.isEmpty()) {
                return { errors };
            }

            dispatcher.dispatch(ActionTypes.RECEIVE_MIXED_DATA, response);

            return response;
        });
}

function readRoot() {
    return departmentApi.read({ extension: 'deep' })
        .then(response => {
            const errors = getErrors(response);

            if (!errors.isEmpty()) {
                return { errors };
            }

            dispatcher.dispatch(ActionTypes.RECEIVE_MIXED_DATA, response);

            return response;
        });
}
