const _ = require('lodash');
const url = require('url');
const template = require('./common/template');
const i18n = require('./common/i18n');
const cache = require('./common/cache');

const ENV_MAP = {
    prod: 'production',
    test: 'testing'
};

const ACTION_KEY_NAMESPACE = 'action.';

function layout(req, res) {
    let config = req.context.config;

    let reqData = _.pick(req, [ 'query', 'params' ]);
    let envKey = (config.env || '').split('.').pop();

    let commonData = {
        action: {},
        account: getAccount(req, res),
        session: req.context.session,
        locale: i18n.getLocale(req.context),
        url: req.originalUrl,
        env: ENV_MAP[envKey] || envKey,
        version: config.version
    };

    Object.keys(req.query).forEach(key => {
        if (key.indexOf(ACTION_KEY_NAMESPACE) === 0)
            commonData.action[key.substring(ACTION_KEY_NAMESPACE.length)] = req.query[key];
    });

    let render = (layoutId, layoutData) => {
        // console.log(JSON.stringify(layoutData, null, 2));

        layoutData = Object.assign(
            { layout_id: layoutId },
            verifyLayout(req, res, layoutData) || {}
        );

        cache.storeAll(req, res);

        req.context.page_id = [layoutId, _.get(layoutData, 'org_list.filter')]
            .filter(Boolean)
            .join('.');

        res.render(layoutData.layout_id + '.hbs', {
            Layout: _.merge(reqData, commonData, layoutData),
            rum: require('./rum')(req)
        });
    };

    return { render };
}

function verifyLayout(req, res, layoutData) {
    let responseStatus = _.get(layoutData, 'data.code');

    if (res.statusCode === 401 || containsCode(layoutData, 'authentication-error')) {
        return {
            layout_id: 'unauthenticated',
            sign_in_url: template.build(_.get(req.context.config, 'passport.session.login'), {
                retpath: getCurrentUrl(req)
            })
        };
    }

    if (res.statusCode === 403 || containsCode(layoutData, 'forbidden')) {
        return {
            layout_id: 'unauthorized'
        };
    }

    return layoutData;
}

function containsCode(data, code) {
    return _.some(data, item => item && item.code === code);
}

function getAccount(req, res) {
    let user = _.get(req.context, 'session.default_user');
    
    if (!user) return;
    
    return {
        name: user.login,
        avatar: template.build('//yapic.yandex.net/get/${uid}/islands-200', {
            uid: _.get(user, 'uid.value')
        })
    };
}

function getCurrentUrl(req) {
    return url.format({
        protocol: req.protocol,
        host: req.get('host'),
        port: req.get('port'),
        pathname: req.originalUrl
    });
}

module.exports = layout;
