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

const DOMAIN_FIELDS = [
    'master',
    'tech',
    'owned',
    'name',
];

function setGendarmeData(req, domain) {
    return sendHandledRequest({
        method: 'get',
        url: `${req.config.api.gendarme}/domain/status`,
        query: {
            name: domain.name,
        },
        headers: {
            'X-Ya-Service-Ticket': _.get(req.context, 'tvm_tickets.gendarme'),
        },
        source: req,
        label: 'read_mx_data',
        noTrailingSlash: true,
    })
        .then(data => {
            if (data && data.status === 'ok') {
                domain.mx = _.get(data, 'response.mx.match');
                domain.delegated = _.get(data, 'response.ns.match');
            }

            return domain;
        })
        .catch(() => domain);
}

function read(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: [req.config.api.directory, 'v7', 'domains'],
        query: _.extend({ fields: DOMAIN_FIELDS.join(',') }, req.query),
        source: req,
        label: 'read_domains',
    })
        .then(domains => {
            if (Array.isArray(domains)) {
                return Promise.all(domains.map(domain => setGendarmeData(req, domain)));
            }
        })
        .then(domains => {
            req.context.domains = _.keyBy(domains, 'name');

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

function add(req, res, next) {
    return sendHandledRequest({
        method: 'post',
        url: `${req.config.api.directory}/domains/`,
        source: req,
        label: 'add_domain',
    })
        .then(result => {
            req.context.domain = result;

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

function remove(req, res, next) {
    let domainName = _.get(req, 'query.domain');

    try {
        domainName = encodeURIComponent(domainName);
    } catch (e) {
        // empty block
    }

    return sendHandledRequest({
        method: 'delete',
        url: `${req.config.api.directory}/domains/${domainName}/`,
        source: req,
        label: 'remove_domains',
    })
        .then(() =>
            // если успешно удалили домен, то после нужно обновить список доменов
            read(req, res, next)
        )
        .catch(next);
}

function checkDomainOccupation(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: [req.config.api.directory, 'v8', 'who-is'],
        query: {
            domain: req.query.domain,
        },
        source: req,
        label: 'check_domain_occupation',
    })
        .then(response => {
            _.set(req.context, 'confirmation.isOccupied', Boolean(response && response.org_id));

            return next ? next() : req;
        })
        .catch(() => {
            _.set(req.context, 'confirmation.isOccupied', false);

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

function getOwnershipInfo(req, res, next) {
    return sendHandledRequest({
        method: 'get',
        url: [
            req.config.api.directory,
            'v7',
            'domains',
            {
                type: 'domain',
                value: encodeURIComponent(req.query.domain),
            },
            'ownership-info',
        ],
        timeout: 30000,
        source: req,
        label: 'get_ownership_domain_info',
    })
        .then(response => {
            const isOwned = response && response.status === 'owned';

            if (isOwned) {
                return read(req, res, next);
            }

            req.context.confirmation = _.merge(req.context.confirmation || {}, response);

            // [DIR-5547] для неподтвержденного домена у которого еще не запущена проверка владения
            // нужно проверить не пренадлежит ли он другой организаци и если так, то показать предупреждение
            if (!req.context.confirmation.last_check) {
                return checkDomainOccupation(req, res, next);
            }

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

function checkOwnership(req, res, next) {
    return sendHandledRequest({
        method: 'post',
        url: [
            req.config.api.directory,
            'v7',
            'domains',
            {
                type: 'domain',
                value: encodeURIComponent(req.query.domain),
            },
            'check-ownership',
        ],
        body: _.pick(req.query, ['verification_type']),
        timeout: 30000,
        source: req,
        label: 'check_domain_ownership',
    })
        .then(response => {
            const isOwned = _.get(response, 'owned', false);

            if (isOwned) {
                return read(req, res, next);
            }

            return getOwnershipInfo(req, res, next);
        })
        .catch(next);
}

module.exports = {
    add,
    read,
    remove,
    getOwnershipInfo,
    checkOwnership,
};
