/**
 *   ПОЛУЧЕНИЕ СПИСКА СТАТЕЙ ДАННОГО ПОЛЬЗОВАТЕЛЯ
 *   Copyright © 2021, А.М.Гольдин. ISC license
 */
"use strict";

// Возвращает массив с элементами - объектами (данными статей)
// В случае пустого аргумента выдает последние 5 опубликованных статей
// arg  - это массив ["soc", "pupkin", "сковородка"]
//        (раздел, автор или соавтор, фрагмент названия или ключевое слово;
//        любой или этих трех элементов или все три могут быть пустыми)
// user - это данные клиента [3, "ivanov", "Иванов", "Ян", "Карлович"]
//        (в настоящем скрипте не используются)
module.exports = async (arg, user) => {
   let resp = [], tooRes = false;
   if (arg[2]) if (arg[2].length < 3) return "none";

   // Промисификатор поиска с выдачей некоторых полей
   const dbFindExt = (objFind, objParam) => {return new Promise((res, rej) => {
      db["articles"].find(objFind, objParam, (err, docs) => {
         if (err) rej(err); else res(docs);
      })
   })};

   // Сортировка массива объектов по полю dt2 по убыванию
   const srt = arr => {
      const newDt = dt => dt.replace(/(\d+).(\d+).(\d+)/, "a$3$2$1");
      let newArr = arr.sort((x,y) => newDt(x.dt2) < newDt(y.dt2) ? 1 : -1);
      return newArr;
   }

   // Изготовление строки библиографического описания из объекта статьи
   const bibl = art => {
      const fioBr = fio => {
         let fioArr = fio.split(' '),
             name = fioArr[1][0] + ". ",
             otch = fioArr[2] ? fioArr[2][0] + ". " : '';
         return `<nobr>${name + otch + fioArr[0]}</nobr>`;
      }
      const fioZag = fio => {
         let fioArr = fio.split(' '),
             otch = fioArr[2] ? fioArr[2][0] + ". " : '';
         return `<nobr>${fioArr[0]}, ${fioArr[1][0]}. </nobr>${otch}`;
      }
      let soavt = `${fioBr(art.author)},`;
      if (art.coauth) {         
         for (let s in art.coauth) {
            let fio = fioBr(art.coauth[s][0]);
            soavt += ` ${fio},`;
         }
         soavt = soavt.replace(/,$/, '.');
      }
      return `<b>${fioZag(art.author)}</b>${art.head} / ${soavt}<nobr> `
         + `—</nobr> Текст : электронный // Архив публикаций обучающихся и `
         + `сотрудников СУНЦ УрФУ : [сайт].<nobr> —</nobr> URL: `
         + `<a href="/pub/${art._id}" target="_blank">`
         + `http://lycarch.urfu.ru/pub/${art._id}</a>.<nobr> —</nobr> Дата `
         + `публикации: ${art.dt2}.<nobr> —</nobr> Режим доступа: свободный.`
         + `<nobr> —</nobr> [Ключевые слова: ${art.keywords}.]`;
   }

   try {
      // Если все три параметра поиска пустые, получаем последние 5 статей
      if (!arg[0] && !arg[1] && !arg[2]) {
         let res = await dbFindExt({status: 7}, {dt2: 1});
         if (!res.length) return "[]";
         res = srt(res).slice(0, 5);
         let ids = res.map(x => x._id);
         resp = await dbFind(
            "articles",
            {$where: function () {return ids.includes(this._id)}}
         );
         if (resp.length) resp = srt(resp);   
      }
      // Иначе ищем статьи по критериям поиска
      else {
         let findObj = {};
         if (arg[0]) findObj.unit = arg[0];
         if (arg[1]) findObj.us = arg[1];

         resp = await dbFind("articles", {$where: function () {
            if (this.status != 7) return false;
            let flagUn, flagAu, flagCn;
            flagUn = flagAu = flagCn = false;

            // Совпадение тематического раздела
            if (!arg[0] || this.unit == arg[0]) flagUn = true;

            // Совпадение автора или соавтора
            let authors =
               [this.author.split(' ')[0].toLowerCase().replace(/ё/g, 'е')];
            if (this.coauth) for (let ca in this.coauth) {
               let fio = this.coauth[ca][0];
               if (fio) authors.push(
                  fio.split(' ')[0].toLowerCase().replace(/ё/g, 'е')
               );
            }
            if (!arg[1] ||
               authors.includes(arg[1].toLowerCase().replace(/ё/g, 'е'))
            ) flagAu = true;

            // Наличие контекста в названии или ключевого слова
            let kw = this.keywords.replace(/,\s*/g, '^');
            if (!arg[2] ||
               (this.head + '^' + kw).toLowerCase().replace(/ё/g, 'е')
               .includes(arg[2].toLowerCase().replace(/ё/g, 'е'))
            ) flagCn = true;

            return flagUn && flagAu && flagCn;
         }});
         if (!resp.length) return "[]";
         if (resp.length > 50) {
            resp = srt(resp).slice(0, 50);
            tooRes = true;
         }
         else resp = srt(resp);
      }
      
      resp = resp.map(x => bibl(x));
      if (tooRes)
         resp.push("<i>Найдено более 50 статей; приведены первые 50.</i>");
      return JSON.stringify(resp);
   }
   catch(e) {return "none";}
};
