const _ = require('lodash');
const user = require('./user');
const department = require('./department');
const permissions = require('./permissions');

function getParentChain(context, departmentId) {
    const contextDepartment = _.find(context.departments, { id: Number(departmentId) }, {});
    const parentIds = (contextDepartment.parents || []).map(parent => parent.id);

    return [contextDepartment.id].concat(parentIds);
}

function read(req, res, next) {
    // если id не передан, запрашиваем корневой отдел
    if (!req.query.id) {
        req.query.id = '1';
    }

    const originalQuery = _.clone(req.query);
    const requests = [];

    const departmentRequest = department.read(req);

    requests.push(departmentRequest);

    let userListRequest;
    let departmentListRequest;

    if (originalQuery.extension === 'deep') {
        userListRequest = departmentRequest
            .then(nextReq => {
                const parentRequests = getParentChain(nextReq.context, originalQuery.id)
                    .map(parentId => {
                        nextReq.query = { department_id: parentId };

                        return user.readList(nextReq);
                    });

                return Promise.all(parentRequests);
            });

        departmentListRequest = departmentRequest
            .then(nextReq => {
                const parentRequests = getParentChain(nextReq.context, originalQuery.id)
                    .map(parentId => {
                        nextReq.query = { parent_id: parentId };

                        return department.readList(nextReq);
                    });

                return Promise.all(parentRequests);
            });

        requests.push(userListRequest, departmentListRequest);
    }

    if (originalQuery.extension === 'shallow') {
        req.query = {
            department_id: originalQuery.id,
        };
        userListRequest = user.readList(req);

        req.query = {
            parent_id: originalQuery.id,
        };
        departmentListRequest = department.readList(req);

        requests.push(userListRequest, departmentListRequest);
    }

    if (originalQuery.extension) {
        req.query = {
            id: originalQuery.id,
            type: 'department',
        };

        const permissionsRequest = permissions.read(req);

        requests.push(permissionsRequest);
    }

    return Promise.all(requests)
        .then(nextReq => next ? next() : nextReq)
        .catch(next);
}

function readFlat(req, res, next) {
    // если id не передан, запрашиваем корневой отдел
    if (!req.query.id) {
        req.query.id = '1';
    }

    const originalQuery = _.clone(req.query);
    const requests = [];

    const departmentRequest = department.read(req);

    requests.push(departmentRequest);

    req.query = {
        recursive_department_id: originalQuery.id,
    };

    const userListRequest = user.readList(req);

    requests.push(userListRequest);

    if (originalQuery.extension && originalQuery.id) {
        req.query = {
            id: originalQuery.id,
            type: 'department',
        };

        const permissionsRequest = permissions.read(req);

        requests.push(permissionsRequest);
    }

    return Promise.all(requests)
        .then(nextReq => next ? next() : nextReq)
        .catch(next);
}

function addMembers(req, res, next) {
    const departmentId = Number(req.query.id);
    const members = _.get(req, 'body.members', []);

    const requests = members.map(member => {
        switch (member.type) {
            case 'user':
                req = _.extend(req, {
                    body: { department_id: departmentId },
                    query: { id: member.id },
                });

                return user.update(req);

            case 'department':
                req = _.extend(req, {
                    body: { parent_id: departmentId },
                    query: { id: member.id },
                });

                return department.update(req);
        }
    }).filter(Boolean);

    return Promise.all(requests)
        .then(nextReq => next ? next() : nextReq)
        .catch(next);
}

module.exports = _.extend({}, department, { read, readFlat, addMembers });
