/*
  Сервис интеграции ПП Парус 8 с WEB API
  Дополнительный модуль: Рассылка E-Mail (MAIL)
*/

//------------------------------
// Подключение внешних библиотек
//------------------------------

const xml2js = require("xml2js"); //Конвертация XML в JSON и JSON в XML
const cfg = require("./../config"); //Настройки сервера приложений
const { makeErrorText, sendMail } = require("./../core/utils"); //Вспомогательные функции

//---------------------
// Глобальные константы
//---------------------

//Статусы отправки
const NSTATUS_ERR = 2;
const NSTATUS_DONE = 3;

//------------
// Тело модуля
//------------

//Установка статуса отправки
const setSendMsg = async prms => {
    await prms.dbConn.executeStored({
        connection: prms.dbConn.connection,
        sName: "PKG_EXS_EXT_MAIL.EXSEXTMAIL_SET_STATUS",
        inPrms: {
            NRN: prms.nRn,
            SERR_TEXT: prms.sErrMsg,
            NSTATUS: prms.nStatus
        }
    });
};

//Считывание записей прикладываемых документов
const getMailAttach = async prms => {
    let attachData = await prms.dbConn.executeStored({
        connection: prms.dbConn.connection,
        sName: "PKG_EXS_EXT_MAIL.GET_ATTACH",
        inPrms: { NIDENT: prms.nIdent },
        outPrms: { RCDOCUMENTS: prms.dbConn.connector.DT_CURSOR }
    });
    let rowsRes = [];
    if (attachData)
        if (attachData.RCDOCUMENTS)
            attachData.RCDOCUMENTS.map(data => {
                rowsRes.push({
                    filename: data.filename,
                    content: data.bdata
                });
            });
    return rowsRes;
};

//Разбор XML
const parseXML = xmlDoc => {
    return new Promise((resolve, reject) => {
        xml2js.parseString(xmlDoc, { explicitArray: false, mergeAttrs: true }, (err, result) => {
            if (err) reject(err);
            else resolve(result);
        });
    });
};

//Обработчик "До" для исходящего сообщения
const before = async prms => {
    //Инициализируем переменные
    let res = "OK";
    let parseRes = null;
    //Разбираем параметры отправки
    try {
        //Формируем объект на основании XML
        parseRes = await parseXML(prms.queue.blMsg.toString());
        //Если есть присоединенные файлы - добавляем их
        if (parseRes.mail.ident) {
            parseRes.mail.attachments = await getMailAttach({ dbConn: prms.dbConn, nIdent: parseRes.mail.ident });
        }
        //Если указан текст в обычном формате
        if (parseRes.mail.text) {
            parseRes.mail.text = Buffer.from(parseRes.mail.text, "base64").toString("utf-8");
        }
        //Если указан текст в формате HTML
        if (parseRes.mail.html) {
            parseRes.mail.html = Buffer.from(parseRes.mail.html, "base64").toString("utf-8");
        }
    } catch (e) {
        parseRes = prms.queue.blMsg.toString();
        res = `Ошибка разбора параметров отправки: ${makeErrorText(e)}`;
    }
    if (res === "OK") {
        try {
            await sendMail({
                mail: cfg.mail,
                sTo: parseRes.mail.to,
                sSubject: parseRes.mail.title,
                sMessage: parseRes.mail.text,
                sHTML: parseRes.mail.html,
                attachments: parseRes.mail.attachments
            });
        } catch (e) {
            res = `Ошибка отправки E-Mail сообщения: ${makeErrorText(e)}`;
        }
    }
    //Если сообщение отправилось
    if (res === "OK") {
        //Если имеется рег. номер записи очереди отправки E-mail - обновляем информацию о текущем сообщении
        if (parseRes.mail.nExsextmailId) {
            await setSendMsg({
                dbConn: prms.dbConn,
                nRn: parseRes.mail.nExsextmailId,
                sErrMsg: "",
                nStatus: NSTATUS_DONE
            });
        }
    } else {
        //Если количество попыток не указано или это последняя попытка
        if (prms.queue.nRetryAttempts === 0 || (prms.queue.nRetryAttempts !== 0 && prms.queue.nExecCnt + 1 === prms.queue.nRetryAttempts)) {
            //Если имеется рег. номер записи очереди отправки E-mail - обновляем информацию о текущем сообщении
            if (parseRes.mail.nExsextmailId) {
                await setSendMsg({
                    dbConn: prms.dbConn,
                    nRn: parseRes.mail.nExsextmailId,
                    sErrMsg: res,
                    nStatus: NSTATUS_ERR
                });
            }
        }
        //Выдаем ошибку
        throw new Error(res);
    }
    //Возвращаем результат и флаг того, что дальше отрабатывать это сообщение не надо
    return {
        blMsg: Buffer.from(JSON.stringify({ message: parseRes, state: res })),
        bStopPropagation: true
    };
};

//-----------------
// Интерфейс модуля
//-----------------

exports.before = before;
