const _ = require('lodash');
const sendHandledRequest = require('../../lib/sendHandledRequest');
const stackResponse = require('../../lib/stackResponse');

const setUserAvatar = require('./user.avatar.file');
const setUserAvatarUrl = require('./user.avatar.url');

const USER_FIELDS = [
    'aliases', 'birthday', 'timezone', 'contacts', 'department',
    'email', 'gender', 'groups', 'groups.name', 'groups.type', 'role',
    'is_dismissed', 'is_enabled', 'name', 'nickname',
    'position', 'language', 'avatar_id', 'org_id',
];

function create(req, res, next) {
    return sendHandledRequest({
        method: 'post',
        url: [req.config.api.directory, 'users'],
        source: req,
        timeout: 20000,
        label: 'create_user',
    })
        .then(user => {
            stackResponse(req.context, 'users', user);

            return next ? next() : req;
        })
        .catch(next);
}

function read(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: [
            req.config.api.directory, 'v6',
            'users', { value: req.query.id, type: 'number' },
        ],
        source: req,
        query: _.extend({ fields: USER_FIELDS.join(',') }, req.query),
        timeout: 20000,
        label: 'read_user',
    })
        .then(user => {
            stackResponse(req.context, 'users', user);

            return next ? next() : req;
        })
        .catch(next);
}

function update(req, res, next) {
    return sendHandledRequest({
        method: 'patch',
        url: [req.config.api.directory, 'users', { value: req.query.id, type: 'number' }],
        source: req,
        timeout: 20000,
        label: 'update_user',
    })
        .then(user => {
            stackResponse(req.context, 'users', user);

            return next ? next() : req;
        })
        .catch(next);
}

function updateList(req, res, next) {
    return sendHandledRequest({
        method: 'post',
        url: [req.config.api.directory, 'v8', 'users', 'bulk-update'],
        source: req,
        timeout: 20000,
        label: 'update_user_list',
    })
        .then(users => {
            stackResponse(req.context, 'users', users);

            return next ? next() : req;
        })
        .catch(next);
}

// basic query: { department_id, page, per_page }
function readList(req, res, next) {
    const defaultOptions = {
        fields: USER_FIELDS.join(','),
        per_page: _.get(req.config, 'directory.perPage.default'),
        ordering: 'name',
    };
    const query = _.extend(defaultOptions, req.query);

    return sendHandledRequest({
        method: 'get',
        url: [req.config.api.directory, 'v7', 'users'],
        query,
        source: req,
        timeout: 20000,
        label: 'read_user_list',
    })
        .then(userList => {
            const list = _.extend(userList, { type: 'users', query });

            stackResponse(req.context, 'lists', list);

            return next ? next() : req;
        })
        .catch(next);
}

function addAlias(req, res, next) {
    return sendHandledRequest({
        method: 'post',
        url: [
            req.config.api.directory, 'users',
            { value: req.query.id, type: 'number' }, 'aliases',
        ],
        source: req,
        label: 'add_user_alias',
    })
        .then(() => next ? next() : req)
        .catch(next);
}

function removeAlias(req, res, next) {
    return sendHandledRequest({
        method: 'delete',
        url: [
            req.config.api.directory, 'users',
            { value: req.query.id, type: 'number' }, 'aliases',
            req.query.name,
        ],
        source: req,
        label: 'remove_user_alias',
    })
        .then(() => next ? next() : req)
        .catch(next);
}

function setAvatar(req, res, next) {
    if (req.body.avatar_url) {
        return setUserAvatarUrl(req, res, next);
    }

    return setUserAvatar(req, res, next);
}

function updateUserType(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: [req.config.api.directory, 'users', 'type'],
        source: req,
        label: 'update_user_type',
    })
        .then(({ internal }) => {
            if (internal) {
                _.extend(req.context.session, { internal });
                req.context.sessions = req.context.sessions
                    .map(session => session.id === req.context.session.id ? req.context.session : session);
            }

            return next ? next() : req;
        })
        .catch(() => next ? next() : req);
}

module.exports = {
    create,
    read,
    update,
    updateList,
    addAlias,
    removeAlias,
    setAvatar,
    readList,
    updateUserType,
};
