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

const DEFAULT_KEY = 'connect';

// настройки, которые отдаются клиенту, когда сервер настроек
// не ответил или ответил ошибкой
const DEFAULT_SETTINGS = {
    initial_user_agreement: '0', // непустая строка - соглашение принято
    dashboard_intro_visited: true,
    admin_intro_visited: true,
    staff_intro_visited: true,
    news_mail_subscription: {
        confirm: true,
    },
    default: true,
};

const DEFAULT_SUBSCRIPTION_DATA = {
    confirm: false,
    last_shown: null,
    declined: false,
};

const SETTINGS_COMPATIBILITY_MAP = {
    admin_intro_visited: 'portal_intro_visited',
    staff_intro_visited: 'portal_intro_visited',
};

function normalizeSettings(data) {
    const oldKeys = [];

    if (!data || typeof data !== 'object') {
        data = {};
    }

    _.forEach(SETTINGS_COMPATIBILITY_MAP, (oldKey, newKey) => {
        if (data[oldKey] !== undefined) {
            data[newKey] = data[oldKey];
            oldKeys.push(oldKey);
        }
    });

    oldKeys.forEach(key => data[key] !== undefined && delete data[key]);

    return data;
}

function readOrganizationSettings(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: `${req.config.api.directory}/settings`,
        source: req,
        label: 'read_organization_settings',
    })
        .then(settings => {
            req.context.organization_settings = _.extend(
                req.context.organization_settings || {},
                settings
            );

            return next ? next() : settings;
        });
}

function readUserSettings(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: [req.config.api.settings, req.query.key || DEFAULT_KEY],
        headers: _.extend({}, req.context.headers, {
            Authorization: `Token ${req.config.tokens.settings}`,
        }),
        noTrailingSlash: true,
        source: req,
        label: 'read_user_settings',
    })
        .then(response => {
            req.context.user_settings = _.extend(
                req.context.user_settings || {},
                normalizeSettings(response)
            );

            if (!req.context.user_settings.news_mail_subscription) {
                req.context.user_settings.news_mail_subscription = {
                    ...DEFAULT_SUBSCRIPTION_DATA,
                };
            }

            return next ? next() : response;
        })
        .catch(() => {
            req.context.user_settings = _.extend(
                req.context.user_settings || {},
                DEFAULT_SETTINGS
            );

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

function read(req, res, next) {
    return Promise.all([
        readUserSettings(req),
        readOrganizationSettings(req),
    ]).then(data => next ? next() : data)
        .catch(next);
}

function update(req, res, next) {
    return sendHandledRequest({
        method: 'put',
        url: [req.config.api.settings, req.query.key || DEFAULT_KEY],
        headers: _.extend({}, req.context.headers, {
            Authorization: `Token ${req.config.tokens.settings}`,
            'Content-Type': 'application/json',
        }),
        noTrailingSlash: true,
        source: req,
        label: 'update_settings',
    })
        .then(response => {
            req.context.user_settings = response;

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

function remove(req, res, next) {
    return sendHandledRequest({
        method: 'delete',
        url: [req.config.api.settings, req.query.key || DEFAULT_KEY],
        headers: _.extend({}, req.context.headers, {
            Authorization: `Token ${req.config.tokens.settings}`,
        }),
        noTrailingSlash: true,
        source: req,
        label: 'remove_settings',
    })
        .then(response => {
            req.context.user_settings = response;

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

function readKeys(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: [req.config.api.settings],
        headers: _.extend({}, req.context.headers, {
            Authorization: `Token ${req.config.tokens.settings}`,
        }),
        source: req,
        label: 'read_settings_keys',
    })
        .then(response => {
            req.context.available_settings = response;

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

module.exports = {
    read, readUserSettings, update, remove, readKeys,
};
