const getModalDialog = async (body, handler) => {
  const dialogTitle = i18n.tr("Комментарий");
  const exitButtonText = i18n.tr("Закрыть");
  const saveButtonText = i18n.tr("Сохранить");

  const dialog = $('<div class="uk-flex-top" uk-modal>');
  const md = $('<div class="uk-modal-dialog uk-margin-auto-vertical">');
  const modalBody = $('<div class="uk-modal-body" uk-overflow-auto>');
  const footer = $('<div class="uk-modal-footer uk-text-right">');


  modalBody.append(body);
  footer.append(`<button class="uk-button uk-button-default uk-modal-close" type="button">${exitButtonText}</button>`);
  md.append(`<div class="uk-modal-header"><h3>${dialogTitle}</h3></div>`).append(modalBody).append(footer);
  dialog.append(md);

  const actionButton = $('<button class="uk-button uk-button-primary uk-margin-left" type="button">');
  actionButton.html(saveButtonText).on('click', handler);
  footer.append(actionButton);

  return dialog;
}

this.DocumentComments = class {
  constructor(documentID, workID, container){
    this.documentID = documentID;
    this.workID = workID;
    this.container = container;

    this.commentType = 'DOCUMENT'; // WORK, DOCUMENT, PERSONAL

    this.init();
  }

  async getComments(){
    return new Promise(async resolve => {
      rest.synergyGet(`api/docflow/doc/comments/list?documentID=${this.documentID}&count=100&locale=${AS.OPTIONS.locale}`,
        resolve,
        err => {
          console.log(`ERROR [ getComments ]: ${JSON.stringify(err)}`);
          resolve(null);
        }
      );
    });
  }

  async getWorkComments(type){
    return new Promise(async resolve => {
      rest.synergyGet(`api/workflow/work/${this.workID}/comments?type=${type}&count=100&locale=${AS.OPTIONS.locale}`, resolve, err => {
        console.log(`ERROR [ getWorkComments ]: ${JSON.stringify(err)}`);
        resolve(null);
      });
    });
  }

  async removeComment(commentID){
    return new Promise(async resolve => {
      rest.synergyGet(`api/docflow/doc/comments/remove?commentID=${commentID}`, resolve, err => {
        console.log(`ERROR [ removeComment ]: ${JSON.stringify(err)}`);
        resolve(null);
      });
    });
  }

  async removeWorkComment(commentID) {
    return new Promise(async resolve => {
      rest.synergyGet(`api/workflow/work/comments/remove?commentID=${commentID}`, resolve, err => {
        console.log(`ERROR [ removeWorkComment ]: ${JSON.stringify(err)}`);
        resolve(null);
      });
    });
  }

  async saveComment(param){
    const {comment, commentID} = param;
    const bodyObject = {documentID: this.documentID, comment: encodeURIComponent(comment)};
    if(commentID) bodyObject.commentID = commentID;

    return new Promise(async resolve => {
      rest.synergyPost(`api/docflow/doc/comments/save?locale=${AS.OPTIONS.locale}`,
        bodyObject, "application/x-www-form-urlencoded; charset=utf-8", resolve,
        err => {
          console.log(`ERROR [ saveComment ]: ${JSON.stringify(err)}`);
          resolve(null);
        }
      );
    });
  }

  async saveWorkComment(param) {
    const {comment, commentID} = param;
    const bodyObject = {workID: this.workID, type: this.commentType, comment: encodeURIComponent(comment)};
    if(commentID) bodyObject.commentID = commentID;

    return new Promise(async resolve => {
      rest.synergyPost(`api/workflow/work/${this.workID}/comments/save?locale=${AS.OPTIONS.locale}`,
        bodyObject, "application/x-www-form-urlencoded; charset=utf-8", resolve,
        err => {
          console.log(`ERROR [ saveWorkComment ]: ${JSON.stringify(err)}`);
          resolve(null);
        }
      );
    });
  }

  getCommentArticle(data){
    const {commentID, comment, author: {name: authorName}, created_label, is_editable, is_deletable} = data;
    const article = $('<article>', {class: "uk-comment uk-comment-primary uk-visible-toggle uk-padding-small"});
    const header = $('<header>', {class: "uk-comment-header uk-position-relative uk-margin-remove"});
    const buttonsBlock = $('<div>', {class: "uk-position-top-right uk-hidden-hover"});
    const commentBody = $('<div>', {class: "uk-comment-body uk-margin-small-top"});

    if(is_editable == 'true') {
      const editCommentButton = $(`<a href="#" uk-icon="icon: pencil"></a>`);
      buttonsBlock.append(editCommentButton);

      editCommentButton.on('click', async e => {
        e.preventDefault();
        e.target.blur();

        const commentInput = $(`<textarea class="uk-textarea add-comment-input" rows="5"></textarea>`);
        commentInput.val(comment);

        const dialog = await getModalDialog(commentInput, async () => {
          try {
            if(commentInput.val() != "") {
              Cons.showLoader();
              commentInput.removeClass('uk-form-danger');

              if(this.workID) {
                await this.saveWorkComment({commentID, comment: commentInput.val()});
              } else {
                await this.saveComment({commentID, comment: commentInput.val()});
              }

              this.renderComments();
              Cons.hideLoader();
              UIkit.modal(dialog).hide();
            } else {
              commentInput.addClass('uk-form-danger');
            }
          } catch (err) {
            Cons.hideLoader();
            UIkit.modal(dialog).hide();
            showMessage(err.message, 'error');
          }
        });

        UIkit.modal(dialog).show();
        dialog.on('hidden', () => {
          dialog.remove();
        });

      });
    }

    if(is_deletable == 'true') {
      const delCommentButton = $(`<a href="#" uk-icon="icon: trash"></a>`);
      buttonsBlock.append(delCommentButton);

      delCommentButton.on('click', async e => {
        e.preventDefault();
        e.target.blur();

        if(this.workID) {
          await this.removeWorkComment(commentID);
        } else {
          await this.removeComment(commentID);
        }

        this.renderComments();
      });
    }

    header
    .append(`<h4 class="uk-comment-title uk-margin-remove">${authorName || ''}</h4>`)
    .append(`<span class="uk-comment-meta uk-margin-remove">${created_label}</span>`)
    .append(buttonsBlock);

    commentBody.html(comment.replaceAll('\n', '<br>'));
    article.append(header).append(commentBody);

    return article;
  }

  async renderComments(){
    if(this.workID) {
      const workComments = await this.getWorkComments('WORK');
      const docComments = await this.getWorkComments('DOCUMENT');
      const userComments = await this.getWorkComments('PERSONAL');

      this.commentListWork.empty();
      this.commentListDoc.empty();
      this.commentListUser.empty();

      if(workComments && workComments.length > 0) {
        workComments.forEach(data => this.commentListWork.append(this.getCommentArticle(data)));
      }

      if(docComments && docComments.length > 0) {
        docComments.forEach(data => this.commentListDoc.append(this.getCommentArticle(data)));
      }

      if(userComments && userComments.length > 0) {
        userComments.forEach(data => this.commentListUser.append(this.getCommentArticle(data)));
      }

    } else {
      const listComments = await this.getComments();
      this.commentListDoc.empty();

      if(listComments && listComments.length) {
        listComments.forEach(data => this.commentListDoc.append(this.getCommentArticle(data)));
      }
    }
  }

  renderApp(){
    this.container.empty();

    const actionPanel = $('<div>', {class: 'tab-comments-container'});
    const tabs = $('<div>', {class: 'tab-buttons-container'});
    const textareaContainer = $('<div style="padding: 0 5px; width: 100%;">');

    this.commentListDoc = $('<div>', {class: 'comments-container'});
    this.commentListWork = $('<div>', {class: 'comments-container'});
    this.commentListUser = $('<div>', {class: 'comments-container'});

    const tabDoc = $(`<span class="comment-tab-name">${i18n.tr("Документ")}</span>`);
    const tabWork = $(`<span class="comment-tab-name">${i18n.tr("Работа")}</span>`);
    const tabUser = $(`<span class="comment-tab-name">${i18n.tr("Личные")}</span>`);

    this.addCommentInput = $('<textarea class="uk-textarea add-comment-input" rows="2"></textarea>')
    .attr('placeholder', i18n.tr("Введите комментарий и нажмите Enter..."));

    this.addCommentButton = $('<a href="#" id="add-comment-button" uk-icon="plus"></a>');
    textareaContainer.append(this.addCommentInput);

    actionPanel.append(this.addCommentButton, tabs);
    this.container.append(actionPanel, textareaContainer, '<hr style="margin: 10px 0;" />');

    if(this.workID) {
      this.commentType = 'WORK';
      tabWork.addClass('active');
      this.commentListWork.addClass('active');
      tabs.append(tabWork, tabDoc, tabUser);
      tabs.addClass('uk-child-width-expand');
      this.container.append(this.commentListWork, this.commentListDoc, this.commentListUser);
    } else {
      this.commentType = 'DOCUMENT';
      tabDoc.addClass('active');
      this.commentListDoc.addClass('active');
      tabs.append(tabDoc);
      this.container.append(this.commentListDoc);
    }

    tabDoc.on('click', e => {
      this.commentType = 'DOCUMENT';
      tabWork.removeClass('active');
      tabUser.removeClass('active');
      tabDoc.addClass('active');
      this.commentListWork.removeClass('active');
      this.commentListUser.removeClass('active');
      this.commentListDoc.addClass('active');
    });

    tabWork.on('click', e => {
      this.commentType = 'WORK';
      tabUser.removeClass('active');
      tabDoc.removeClass('active');
      tabWork.addClass('active');
      this.commentListDoc.removeClass('active');
      this.commentListUser.removeClass('active');
      this.commentListWork.addClass('active');
    });

    tabUser.on('click', e => {
      this.commentType = 'PERSONAL';
      tabWork.removeClass('active');
      tabDoc.removeClass('active');
      tabUser.addClass('active');
      this.commentListDoc.removeClass('active');
      this.commentListWork.removeClass('active');
      this.commentListUser.addClass('active');
    });

  }

  initCommentListiners(){

    this.addCommentInput.off().on('keyup', async e => {
      if (e.keyCode === 13) {
        e.preventDefault();
        e.target.blur();
        const comment = this.addCommentInput.val().replaceAll('\n', '').trim();
        if(comment != '') {

          if(this.workID) {
            await this.saveWorkComment({comment});
          } else {
            await this.saveComment({comment});
          }

          this.addCommentInput.val('');
          this.renderComments();
        } else {
          this.addCommentInput.val('');
        }
      }
    });

    this.addCommentButton.off().on('click', async e => {
      e.preventDefault();
      e.target.blur();

      const commentInput = $(`<textarea class="uk-textarea add-comment-input" rows="5"></textarea>`);

      const dialog = await getModalDialog(commentInput, async () => {
        try {
          if(commentInput.val() != "") {
            Cons.showLoader();
            commentInput.removeClass('uk-form-danger');

            if(this.workID) {
              await this.saveWorkComment({comment: commentInput.val()});
            } else {
              await this.saveComment({comment: commentInput.val()});
            }

            this.renderComments();
            Cons.hideLoader();
            UIkit.modal(dialog).hide();
          } else {
            commentInput.addClass('uk-form-danger');
          }
        } catch (err) {
          Cons.hideLoader();
          UIkit.modal(dialog).hide();
          showMessage(err.message, 'error');
        }
      });

      UIkit.modal(dialog).show();
      dialog.on('hidden', () => {
        dialog.remove();
      });

    });
  }

  async init(){
    if(!this.workID && !this.documentID) return;

    if(!this.workID && this.documentID)  {
      const docInfo = await appAPI.getDocumentInfo(this.documentID);
      if(docInfo && docInfo.actions.length) this.workID = docInfo.actions[0];
    }

    if(this.workID && !this.documentID) {
      this.documentID = await appAPI.getWorkDocument(this.workID);
    }

    this.container.off().on('change_locale_after', e => {
      this.renderApp();
      this.renderComments();
      this.initCommentListiners();
    });

    this.renderApp();
    this.renderComments();
    this.initCommentListiners();
  }

}
