/*
 * Чтение списка организаций пользователя
 */

const { URL } = require('url');
const querystring = require('querystring');
const _ = require('lodash');
const ycookie = require('@yandex-int/y-cookie');
const responseContext = require('../lib/responseContext');
const organization = require('../routes/api/organization');
const getUrl = require('../lib/getUrl');

function changeOrg(req, res, orgId) {
    const currentUrl = new URL(responseContext.getUrl(req, req.originalUrl));

    currentUrl.searchParams.delete('org-id');

    const query = {
        org_id: orgId,
        mode: 'portal',
        sk: req.context.sk,
        retpath: currentUrl.href,
    };

    res.redirect(getUrl(`/context?${querystring.stringify(query)}`));
}

function readOrganizations(req, res, next) {
    if (!_.get(req.context, 'headers.x-uid') || responseContext.isSetup(req)) {
        return next();
    }

    let currentOrg;

    return organization.readList(req)
        // все организации, кроме заданной в x-org-id, будут запрашиваться без сервисов;
        // если к моменту этого запроса x-org-id не задан, то нужно отдельно
        // дозапросить сервисы в следующем then
        .then(() => {
            const { domain } = req.query;
            const pageRequest = req.accepts(['html']) === 'html';
            const orgs = req.context.organizations || [];

            const queryOrgId = req.query['org-id'];
            const ycookieOrgId = _.get(ycookie.parse(req.cookies.yp), 'org_id.value');

            let currentOrgId = req.headers['x-org-id'] || ycookieOrgId ||
                (orgs[0] && String(orgs[0].id));

            if (pageRequest && domain && responseContext.isAdminPage(req)) {
                // в первом проходе ищем по мастер доменам
                let orgWithDomain = _.find(
                    orgs,
                    org => _.get(org, 'domains.master') === domain
                );

                if (!orgWithDomain) {
                    // во втором проходе смотрим по всем доменам из организации
                    orgWithDomain = _.find(
                        orgs,
                        org => _.get(org, 'domains.all', []).includes(domain)
                    );
                }

                if (orgWithDomain) {
                    const domainOrgId = String(orgWithDomain.id);

                    if (domainOrgId !== currentOrgId) {
                        return changeOrg(req, res, domainOrgId);
                    }
                }
            }

            if (pageRequest && queryOrgId && queryOrgId !== currentOrgId) {
                return changeOrg(req, res, queryOrgId);
            }

            currentOrg = _.find(
                orgs,
                org => String(org.id) === currentOrgId
            );

            if (!currentOrg && orgs[0]) {
                currentOrg = orgs[0];
                currentOrgId = String(currentOrg.id);
            }

            if (currentOrg) {
                responseContext.setCurrentOrganizationId(req, currentOrgId);
                // проставляем заголовок x-org-id, только если нашли эту организацию в списке
                req.context.headers['x-org-id'] = currentOrgId;
            }
        })
        // если для текущей организации сервисы не получены предыдущим запросом,
        // дозапрашиваем их отдельно
        .then(() => {
            if (currentOrg && !currentOrg.services) {
                const originalQuery = _.clone(req.query);

                req.query.id = currentOrg.id;

                return organization.readDetails(req, res)
                    .then(() => {
                        req.query = originalQuery;
                    });
            }
        })
        .then(() => next())
        .catch(next);
}

module.exports = readOrganizations;
