function initializeCommentsPage() {
  if (document.getElementById('comments-container')) {
    toggleCodeOfConduct();
    var commentableId = document.getElementById('comments-container').dataset.commentableId;
    var commentableType = document.getElementById('comments-container').dataset.commentableType;
    commentableIdList = commentableId.split(",");
    var f = (function() {
      for (var i = 0; i < commentableIdList.length; i++) {
        (function(i){
          var ajaxReq;
          if (window.XMLHttpRequest) {
            ajaxReq = new XMLHttpRequest();
          } else {
            ajaxReq = new ActiveXObject('Microsoft.XMLHTTP');
          }
          ajaxReq.onreadystatechange = function () {
            if (ajaxReq.readyState === XMLHttpRequest.DONE) {
              var responseObj = JSON.parse(ajaxReq.response);
              var reactions = responseObj.reactions;
              var allNodes = document.getElementsByClassName('single-comment-node');
              var positiveReactionCounts = responseObj.positive_reaction_counts;
              for (var i = 0; i < reactions.length; i++) {
                var buttForComment = document.getElementById('button-for-comment-' + reactions[i].reactable_id);
                if (buttForComment) {
                  buttForComment.classList.add('reacted');
                }
              }
              for (var i = 0; i < positiveReactionCounts.length; i++) {
                var buttForComment = document.getElementById('button-for-comment-' + positiveReactionCounts[i].id);
                if (buttForComment) {
                  if (positiveReactionCounts[i].count > 0) {
                    if (!document.getElementById('reactions-count-' + positiveReactionCounts[i].id)) {
                      buttForComment.innerHTML = buttForComment.innerHTML + "<span class='reactions-count' id='reactions-count-" + positiveReactionCounts[i].id + "'>" + positiveReactionCounts[i].count + '</span>';
                    } else {
                      document.getElementById('reactions-count-' + positiveReactionCounts[i].id).innerHTML = positiveReactionCounts[i].count;
                    }
                  }
                }
              }

              for (var i = 0; i < allNodes.length; i++) {
                if (allNodes[i].dataset.commentAuthorId == responseObj.current_user.id) {
                  allNodes[i].dataset.currentUserComment = "true";
                  var userActionsEl = allNodes[i].children[0].children[2].children[0];
                  var buttEl = document.getElementById('button-for-comment-' + allNodes[i].dataset.commentId);
                  if (userActionsEl && buttEl) {
                    userActionsEl.className = 'current-user-actions';
                    userActionsEl.style.display = 'inline-block';
                    document.getElementById('button-for-comment-' + allNodes[i].dataset.commentId).classList.add('reacted');
                  }
                }
              }
            }
          };

          ajaxReq.open("GET", "/reactions?commentable_id=" + commentableIdList[i] + "&commentable_type=" + commentableType, true);
          ajaxReq.send();
        })(i);
      }
    })();

    var butts = document.getElementsByClassName('reaction-button');
    for (var i = 0; i < butts.length; i++) {
      var butt = butts[i];
      butt.onclick = function (event) {
        var thisButt = this;
        event.preventDefault();
        sendHapticMessage('medium');
        var userStatus = document.getElementsByTagName('body')[0].getAttribute('data-user-status');
        if (userStatus === 'logged-out') {
          showModal('react-to-comment');
          return;
        }

        thisButt.classList.add('reacted');
        thisButt.disabled = true;

        function successCb(response) {
          var reactionCountSpan = thisButt.children[2];
          if (response.result === 'create') {
            thisButt.classList.add('reacted');
            if (reactionCountSpan) {
              reactionCountSpan.innerHTML = parseInt(reactionCountSpan.innerHTML) + 1;
            }
          } else {
            thisButt.classList.remove('reacted');
            if (reactionCountSpan) {
              reactionCountSpan.innerHTML = parseInt(reactionCountSpan.innerHTML) - 1;
            }
          }
        }
        var formData = new FormData();
        formData.append('reactable_type', 'Comment');
        formData.append('reactable_id', thisButt.dataset.commentId);
        getCsrfToken()
          .then(sendFetch('reaction-creation', formData))
          .then(function (response) {
            thisButt.disabled = false;
            if (response.status === 200) {
              response.json().then(successCb);
            }
          });
      };
    }
    var replyButts = document.getElementsByClassName('toggle-reply-form');
    for (var i = 0; i < replyButts.length; i++) {
      var butt = replyButts[i];
      butt.onclick = function (event) {
        event.preventDefault();
        if (event.target.classList.contains("thread-indication")) {
          return false;
        } else {
          var userStatus = document.getElementsByTagName('body')[0].getAttribute('data-user-status');
          if (userStatus == 'logged-out') {
            showModal('reply-to-comment');
            return;
          }
          var actionNode = event.target.parentNode;
          var parentId = actionNode.dataset.commentId;
          document.getElementById("button-for-comment-" + actionNode.dataset.commentId).style.zIndex = "5";
          var waitingOnCSRF = setInterval(function () {
            var metaTag = document.querySelector("meta[name='csrf-token']");
            if (metaTag) {
              clearInterval(waitingOnCSRF);
              actionNode.innerHTML = buildCommentFormHTML(commentableId, commentableType, parentId);
              setTimeout(function () {
                actionNode.getElementsByTagName('textarea')[0].focus();
              }, 30);
            }
          }, 1);
          // document.getElementById('textarea-for-'+parentId).focus();
        };
        return false;
      }
    }
    var editButts = document.getElementsByClassName('edit-butt');
    for (var i = 0; i < editButts.length; i++) {
      var butt = editButts[i];
      butt.onclick = function () {
        // event.preventDefault();
        // alert("edit clicked!")
      };
    }
    if (document.getElementById('new_comment')) {
      document.getElementById('new_comment').addEventListener('submit', handleCommentSubmit);
    }
  }
  listenForDetailsToggle();
}

function toggleCodeOfConduct() {
  var user = userData();
  if (!user) {
    return;
  }
  var codeOfConduct = user.checked_code_of_conduct
  var commentCount = user.number_of_comments
  var checkboxWrapper = document.getElementById('toggle-code-of-conduct-checkbox');
  if (checkboxWrapper && !codeOfConduct && commentCount < 1) {
    checkboxWrapper.innerHTML = '<input type="checkbox" name="checked_code_of_conduct" class="checkbox" required/>\
                                  <label for="checked_code_of_conduct">I\'ve read the <a href="<%= URL.url('code-of-conduct') %>">code of conduct</a></label>'
  }
}

function replaceActionButts(el) {
  var loggedInActionButts = "";
  var wrapper = el.getElementsByClassName("actions")[0]
  if (el.dataset.currentUserComment == "true") {
    loggedInActionButts = '<a data-no-instant href="' + el.parentNode.parentNode.dataset.path + '/delete_confirm" class="edit-butt">DELETE</a>\
                            <a href="' + el.parentNode.parentNode.dataset.path + '/edit">EDIT</a>'
  }
  wrapper.innerHTML = '<span class="current-user-actions">' + loggedInActionButts + '</span><a href="#" class="toggle-reply-form">REPLY</a>';
}

function warmNewCommentsArea() {
  var path = '/stories/warm_comments'+ window.location.pathname
  window.fetch(path)
}

function handleCommentSubmit(event) {
  event.preventDefault();
  var form = event.target;
  form.classList.add('submitting');
  var parentComment = document.getElementById("comment-node-" + event.target.dataset.commentId);

  var body = JSON.stringify({
    comment: {
      body_markdown: form.getElementsByTagName("textarea")[0].value,
      commentable_id: form.querySelector("#comment_commentable_id").value,
      commentable_type: form.querySelector("#comment_commentable_type").value,
      parent_id: form.querySelector("#comment_parent_id") ? form.querySelector("#comment_parent_id").value : null,
    }
  });

  getCsrfToken()
    .then(sendFetch('comment-creation', body))
    .then(function (response) {
      if (response.status === 200) {
        response.json().then(function (newComment) {
          var newNode = document.createElement('div');
          newNode.innerHTML = buildCommentHTML(newComment);
          var docBody = document.getElementsByTagName('body')[0]

          var userData = JSON.parse(docBody.getAttribute('data-user'))
          userData.checked_code_of_conduct = true;

          docBody.dataset.user = JSON.stringify(userData);

          var checkbox = form.getElementsByClassName('code-of-conduct')[0]
          if (checkbox) {
            checkbox.innerHTML = ""
          }

          var mainCommentsForm = document.getElementById("new_comment");
          if (parentComment) {
            replaceActionButts(parentComment);
            if (newComment.depth > 2) {
              parentComment.getElementsByClassName("toggle-reply-form")[0].innerHTML = ""
            }
            var actionsNode = parentComment.getElementsByClassName("inner-comment")[0];
            actionsNode.parentNode.insertBefore(newNode, actionsNode.nextSibling);
          }

          else if (mainCommentsForm) {
            var mainCommentsForm = document.getElementById("new_comment");
            mainCommentsForm.classList.remove("submitting");
            const textArea = document.getElementById("text-area");
            textArea.classList = "";
            textArea.value = newComment.comment_template || "";
            var preview = document.getElementById("preview-div");
            preview.classList.add("preview-toggle");
            preview.innerHTML = "";
            var container = document.getElementById("comment-trees-container");
            container.insertBefore(newNode, container.firstChild);
          }
          else if (document.getElementById("notifications-container")) {
            var newDiv = document.createElement("span")
            newDiv.innerHTML = '<div class="reply-sent-notice">Reply sent — <a href="' + newComment.url + '">Check it out</a></div>'
            form.replaceWith(newDiv);
          }
          else {
            window.location.replace(newComment.url)
          }
          warmNewCommentsArea();
          initializeCommentsPage();
          initializeCommentDate();
          initializeCommentDropdown();
        })
      } else {
        response.json().then(function parseError(errorReponse) {
          form.classList.remove('submitting');
          window.alert(errorReponse.error); // eslint-disable-line no-alert
          return false;
        });
      }
      return false;
    });
  return false;
}

function handleFocus(event) {
  var userStatus = document.getElementsByTagName('body')[0].getAttribute('data-user-status');
  var area = event.target;
  if (userStatus == 'logged-out') {
    event.preventDefault();
    showModal('reply-to-comment');
    area.blur();
    setTimeout(function () {
      area.blur();
      showModal('reply-to-comment');
    }, 100);
  } else {
    handleSizeChange(event);
  }
}

function handleBlur(event) {
  setTimeout(function () {
    var el = document.getElementById('text-area');
    if (el.value.length == 0) {
      el.className = '';
    }
  }, 100);
}

function handleKeyUp(event) {
  handleSizeChange(event);
}

// Handler for when Ctrl+Enter OR Command+Enter is pressed
function handleSubmit(event) {
  // Get user details and extract code of conduct & comment count
  var user = userData();
  if (!user) {
    return;
  }

  var commentCount = user.number_of_comments;

  // var codeOfConduct = user.checked_code_of_conduct;
  // Code of conduct is false the first time even if the user has accepted it
  // so we are not using it in the check below
  // It also seems unnecessary if comment count >= 1 indicates that
  // it was previously accepted

  // Ensure that user has commented at least once
  // and we have a non-empty comment to post
  if (commentCount >= 1 &&
    event.target.value.trim() !== '') {
    // get a reference to the submit button for the text area (first level comment vs. reply comment)
    var parentFormId = event.target.parentElement.parentElement.id || event.target.parentElement.id;
    var submitButton = document.querySelector('#' + parentFormId + ' input[type="submit"].comment-action-button');
    submitButton.click();
  }
}

// Handler when Ctrl+B/I OR Command+B/I is pressed
function handleBoldAndItalic(event) {
  var textArea = event.target;

  var selection = textArea.value.substring(textArea.selectionStart, textArea.selectionEnd);
  var selectionStart = textArea.selectionStart;
  var surroundingStr = event.keyCode === KEY_CODE_B ? "**" : "_";

  replaceSelectedText(textArea, `${surroundingStr}${selection}${surroundingStr}`);

  var selectionStartWithOffset = selectionStart + surroundingStr.length;
  textArea.setSelectionRange(selectionStartWithOffset, selectionStartWithOffset + selection.length);
}

// Handler when Ctrl+K OR Command+K is pressed
function handleLink(event) {
  var textArea = event.target;

  var selection = textArea.value.substring(textArea.selectionStart, textArea.selectionEnd);
  var selectionStart = textArea.selectionStart;

  replaceSelectedText(textArea, `[${selection}](url)`);

  // start position + length of selection + [](
  var startOffset = selectionStart + selection.length + 3;

  // start offset + 'url'.length
  var endOffset = startOffset + 3;

  textArea.setSelectionRange(startOffset, endOffset);
}

function replaceSelectedText(textArea, text) {
  // Chrome and other modern browsers (except FF and IE 8,9,10,11)
  if (document.execCommand('insertText', false, text)) {
  }
  // Firefox (non-standard method)
  else if (typeof textArea.setRangeText === "function") {
    textArea.setRangeText(text);
  }

  /*
    Disabling IE 8-11 for now as there's no easy way to verify all this
    We can revisit this if it's really needed and find a jQuery plugin to use

    // IE 8-10
    else if(document.selection) {
      const ieRange = document.selection.createRange();
      ieRange.text = text;

      // Move cursor after the inserted text
      ieRange.collapse(false); // to the end
      ieRange.select();
    }
    else {
      // Does not support IE 11 yet
    }
  */
}

var KEY_CODE_B = 66;
var KEY_CODE_I = 73;
var KEY_CODE_K = 75;
var ENTER_KEY_CODE = 13;

function handleKeyDown(event) {
  if (event.ctrlKey || event.metaKey) {
    switch (event.keyCode) {
      case KEY_CODE_B:
        event.preventDefault();
        handleBoldAndItalic(event);
        break;
      case KEY_CODE_I:
        event.preventDefault();
        handleBoldAndItalic(event);
        break;
      case KEY_CODE_K:
        event.preventDefault();
        handleLink(event);
        break;
      case ENTER_KEY_CODE:
        event.preventDefault();
        handleSubmit(event);
        break;
      default:
        break;
    }
  }
}

function handleSizeChange(event) {
  var lines = event.target.value.split(/\r*\n/);
  var lineCount = lines.length;
  if (lineCount > 11) {
    document.getElementById('text-area').className = 'embiggened-max';
  } else if (lineCount > 6) {
    document.getElementById('text-area').className = 'embiggened-more';
  } else {
    document.getElementById('text-area').className = 'embiggened';
  }
}

function validateField(event) {
  if (document.getElementById('text-area')) {
    var commentField = document.getElementById('text-area').value;
    if (commentField == '') {
      event.preventDefault();
    }
  }
}

function generateUploadFormdata(image) {
  var token = document.querySelector("meta[name='csrf-token']").content;
  var formData = new FormData();
  formData.append('authenticity_token', token);
  formData.append('image', image[0]);
  return formData;
}

function handleImageUpload(event, randomIdNumber) {
  var commentableId = document.getElementById('comments-container').dataset.commentableId;
  event.preventDefault();
  document.getElementById('image-upload-' + randomIdNumber).click();
  document.getElementById('image-upload-' + randomIdNumber).onchange = function (e) {
    var image = document.getElementById('image-upload-' + randomIdNumber).files;
    if (image.length > 0) {
      document.getElementById("image-upload-file-label-" + randomIdNumber).style.color = '#888888';
      document.getElementById("image-upload-file-label-" + randomIdNumber).innerHTML = "Uploading...";
      document.getElementById("image-upload-submit-" + randomIdNumber).value = "uploading";
      setTimeout(function () {
        document.getElementById("image-upload-submit-" + randomIdNumber).click(function () { });
      }, 50)
    }
  }

  document.getElementById("image-upload-submit-" + randomIdNumber).onclick = function (e) {
    e.preventDefault();
    var image = document.getElementById('image-upload-' + randomIdNumber).files;
    if (image.length > 0) {
      getCsrfToken()
        .then(sendFetch("image-upload", generateUploadFormdata(image)))
        .then(function (response) {
          if (response.status === 200) {
            response.json().then(
              function uploadImageCb(json) {
                var address = document.getElementById("uploaded-image-" + randomIdNumber);
                var button = document.getElementById("image-upload-button-" + randomIdNumber);
                var messageContainer = document.getElementById("image-upload-file-label-" + randomIdNumber)
                // button.style.display = "none";
                messageContainer.style.display = "none";
                address.value = json.links[0];
                address.classList.add("showing");
                address.select();

                var uploadedMessage = 'Uploaded! Paste into editor';
                messageContainer.innerHTML = uploadedMessage;
                messageContainer.style.color = '#00c673';
                messageContainer.style.position = "relative";
                messageContainer.style.top = "5px";
              }
            );
          } else {
            response.json().then(function(responseBody) {
              var errorMessage = responseBody.error || 'Invalid file!';
              document.getElementById("image-upload-file-label-" + randomIdNumber).innerHTML = errorMessage;
              document.getElementById("image-upload-file-label-" + randomIdNumber).style.color = '#e05252';
              document.getElementById("image-upload-submit-" + randomIdNumber).style.display = 'none';
            });
          }
        })
        .catch(function (err) {
          // there's currently no error handling
        })
    }
  }
}

function listenForDetailsToggle() {
  var detailItems = document.getElementsByTagName("DETAILS");
  for (var i = 0; i < detailItems.length; i++) {
    detailItems[i].addEventListener("toggle", event => {
      var item = event.target
      var itemSummaryContent = item.getElementsByTagName("SPAN")[0]
      var usernames = item.getElementsByClassName("comment-username")
      var number = "";
      if (usernames.length > 1) {
        number = " + " + (usernames.length - 1) + " replies"
      }
      var itemUsername = usernames[0].textContent + number
      if (item.open) {
        itemSummaryContent.innerHTML = "&nbsp;"
      } else {
        itemSummaryContent.innerHTML = itemUsername;
      }
      item.getElementsByTagName("SUMMARY")[0].blur();
    });
  }
}
