/**
 * Лента событий.
 * Создаётся проект “Лента”, где показываются
 * удаление, создание, перемещение, переименование объектов.
 *
 * События можно фильтровать по пользователю, типу
 * и дате события, для этого нужно выбрать соответствующее состояние
 * стикера в панели стикеров.
 */

// функция записывающая событие
function trackChange(type, item, extra) {
  var data = Current.company.getData() || {};
  var lenta = data.lenta || {};

  var updates = lenta.updates || {};
  const time = App.time();
  updates[time] = {
    type: type,
    itemId: item.id,
    time: App.time(),
    user: Current.user.id,
    extra: extra || []
  };
  lenta.updates = updates;
  data.lenta = lenta;
  Current.company.setData(data);
}

function areDatesEqual(d1, d2) {
  return (
    d1.getFullYear() === d2.getFullYear() &&
    d1.getMonth() === d2.getMonth() &&
    d1.getDate() === d2.getDate()
  );
}

// записываем события добавления, удаления, переименования,
// перенесения и отправки сообщения
Items.onAdd = function(obj) {
  trackChange('add', obj);
};
Items.onDelete = function(obj) {
  trackChange('delete', obj);
};
Items.onRename = function(obj, newName) {
  trackChange('rename', obj, [obj.name, newName]);
};
Items.onMove = function(obj, from, to) {
  trackChange('move', obj, [from.id, to.id]);
};
Chat.onPostMessage = function(msg) {
  trackChange('message', msg.getTask(), [msg.text]);
};

var projectName = 'Лента событий';
var boardName = 'События';
var stickerName = 'Действие';
var props = {
  limits: {}, // userId -> limit
  step: 50,
  startLimit: 20
};

if (Current.user.isAdmin) {
  // создаём проект, если ещё нет
  if (!Current.company.find(projectName)) {
    Current.company.add(projectName);
    console.log('Создан проект “Лента событий”.');
  }

  var pr = Current.company.find(projectName);
  // создаём доску если ещё нет
  if (!pr.list().length) {
    pr.add(boardName);
  }
  var board = pr.list().shift();

  var userSticker = Stickers.get('User');
  var deadlineSticker = Stickers.get('Deadline');

  // стикер “Action type” создадим,
  // чтобы по нему фильтровать ленту событий (по типу события)
  var sticker = Stickers.get('Action type');
  if (!sticker) {
    sticker = Stickers.create('Action type');
    ['add', 'rename', 'move', 'message', 'delete', 'restore'].forEach(function(
      type
    ) {
      sticker.addState(type);
    });
  }

  if (!Stickers.isInBoard(board, sticker)) {
    Stickers.addToBoard(board, sticker);
  }
  if (!Stickers.isInBoard(board, userSticker)) {
    Stickers.addToBoard(board, userSticker);
  }
  if (!Stickers.isInBoard(board, deadlineSticker)) {
    Stickers.addToBoard(board, deadlineSticker);
  }

  // отрисовываем список событий
  drawTimeline();
  // и перерисовываем при различных обновлениях
  Current.onBoardChange = drawTimeline;
  Items.onUpdate = drawTimeline;
  Stickers.onBoardFilterChange = drawTimeline;

  // рисует ленту событий, если пользователь находится
  // в проекте “Лента событий”
  function drawTimeline() {
    if (!Current.board || Current.board.id !== board.id) {
      return;
    }
    board.ui.clear();
    board.ui.style = {
      marginLeft: '18px',
      marginTop: '12px'
    };
    var updObj = (Current.company.getData().lenta || {}).updates || {};
    var updates = Object.keys(updObj).map(k => updObj[k]);
    // фильтруем события по выбранным состояниям
    // стикеров “Пользователь” и “Action type”
    var filterUser = Stickers.getFilterValue(board, userSticker);
    var filterType = Stickers.getFilterValue(board, sticker);
    var filterDeadline = Stickers.getFilterValue(board, deadlineSticker);
    if (filterType && filterType.length) {
      updates = updates.filter(function(up) {
        return up && filterType.indexOf(up.type) > -1;
      });
    }
    if (filterUser && filterUser.length) {
      updates = updates.filter(function(up) {
        return up && filterUser.indexOf(up.user) > -1;
      });
    }
    if (filterDeadline && filterDeadline.length === 2) {
      updates = updates.filter(function(up) {
        const dt = up.time;
        const d = new Date(dt);
        const t1t = +filterDeadline[0];
        const t1 = new Date(t1t);
        const t2t = +filterDeadline[1];
        const t2 = new Date(t2t);
        return (
          up &&
          ((dt >= t1t && dt <= t2t) ||
            areDatesEqual(d, t1) ||
            areDatesEqual(d, t2))
        );
      });
    }

    var columns = {};
    updates.forEach(u => {
      var col = columns[u.user] || [];
      col.push(u);
      columns[u.user] = col;
    });

    Object.keys(columns).forEach(uid => {
      var p1 = UI.panel();
      p1.style = panelStyle();
      var ups = columns[uid].reverse();
      var len = ups.length;
      ups.forEach(u => {
        var row = drawUpdate(u);
        if (row) {
          p1.add(row);
        }
      });
      if (!props.limits[uid]) {
        props.limits[uid] = props.startLimit;
      }
      // кнопка “Показать ещё…”
      if (props.limits[uid] < len) {
        var btn = UI.button('Показать ещё…');
        btn.onClick = function() {
          props.limits[uid] += props.step;
          drawTimeline();
        };
        p1.add(btn);
      }
      if (props.limits[uid] > props.startLimit) {
        var btn2 = UI.button('Свернуть');
        btn2.onClick = function() {
          props.limits[uid] = props.startLimit;
          drawTimeline();
        };
        p1.add(btn2);
      }
      board.ui.add(p1);
    });
  }

  // рисует одно событие
  // мы сохраняли событие в trackChange в формате
  // {
  //   type: {тип объекта: add, delete, move, restore, rename, message}
  //   time: {timestamp сервера},
  //   user: {id пользователя},
  //   itemId: {id объекта, с которым произвели действие}
  // }
  function drawUpdate(u) {
    if (!u) {
      return;
    }
    var container = UI.panel();
    container.style = {
      width: '320px',
      background: '#fff',
      borderRadius: '2px',
      minHeight: '40px',
      padding: '4px 4px 4px 40px',
      margin: '0 0 8px',
      position: 'relative',
      overflow: 'hidden',
      wordWrap: 'break-word'
    };
    var item = Items.get(u.itemId);
    var user = Users.get(u.user);
    var when = UI.text(App.formatDateTime(u.time));
    var who = UI.user(user, 30);
    var what = item.type + ' “' + item.name + '”';
    var tools = UI.panel();
    if (u.type === 'delete' && item.deleted) {
      var undel = UI.button('Восстановить');
      undel.onClick = function() {
        item.deleted = false;
        trackChange('restore', item);
        drawTimeline();
      };
      undel.style = {
        fontSize: '13px'
      };
      tools.add(undel);
      tools.style = {
        paddingBottom: '4px'
      };
    }

    var action = '';
    if (u.type === 'add') {
      if (item.type === 'Task') {
        what = 'Создана задача';
      } else if (item.type === 'Column') {
        what = 'Создана колонка';
      } else if (item.type === 'Board') {
        what = 'Создана доска';
      } else if (item.type === 'Project') {
        what = 'Создан проект';
      }
      what += ' “' + item.name + '”';
      action = item.path;
    } else if (u.type === 'delete') {
      if (item.type === 'Task') {
        what = 'Удалена задача';
      } else if (item.type === 'Column') {
        what = 'Удалена колонка';
      } else if (item.type === 'Board') {
        what = 'Удалена доска';
      } else if (item.type === 'Project') {
        what = 'Удалён проект';
      }
      what += ' “' + item.name + '”';
      action = item.path;
    } else if (u.type === 'restore') {
      if (item.type === 'Task') {
        what = 'Восстановлена задача';
      } else if (item.type === 'Column') {
        what = 'Восстановлена колонка';
      } else if (item.type === 'Board') {
        what = 'Восстановлена доска';
      } else if (item.type === 'Project') {
        what = 'Восстановлен проект';
      }
      what += ' “' + item.name + '”';
      action = item.path;
    } else if (u.type === 'rename') {
      what = `Переименовано “${u.extra[0]}” => “${u.extra[1]}”`;
      action = item.path;
    } else if (u.type === 'move') {
      if (item.type === 'Task') {
        what = 'Перенесена задача';
      } else if (item.type === 'Column') {
        what = 'Перенесена колонка';
      } else if (item.type === 'Board') {
        what = 'Перенесена доска';
      } else if (item.type === 'Project') {
        what = 'Перенесён проект';
      }
      what += ' “' + item.name + '”';
      action = `перенесено: “${Items.get(u.extra[0]).name}” => “${
        Items.get(u.extra[1]).name
      }”`;
    } else if (u.type === 'message') {
      what = 'Сообщение: “' + u.extra[0] + '”';
      action = 'В задаче “' + item.name + '” (' + item.path + ')';
    }

    var actionEl = UI.text(action);
    container.add(who);
    container.add(when);
    container.add(UI.text(what));
    container.add(actionEl);
    container.add(tools);

    who.style = {
      position: 'absolute',
      left: '4px'
    };
    when.style = {
      color: '#777',
      fontSize: '13px'
    };
    actionEl.style = {
      color: '#777',
      fontSize: '13px'
    };
    return container;
  }

  function panelStyle() {
    return {
      width: '340px',
      background: 'rgba(255, 255, 255, 0.85)',
      color: '#333',
      padding: '8px 8px',
      borderRadius: '2px',
      marginRight: '10px',
      marginBottom: '16px',
      minHeight: '200px',
      float: 'left'
    };
  }
}

// убираем возможность удаления/переименования нашего проекта и доски
if (Current.company.find(projectName)) {
  var pr = Current.company.find(projectName);
  var board = pr.list().shift();
  if (board) {
    function disallow(item) {
      if (item.id === pr.id || item.id === board.id) {
        return false;
      }
    }
    Items.allowAdd = disallow;
    Items.allowDelete = disallow;
    Items.allowRename = disallow;
    board.ui.showDefaults = false;
  }
}
