/**
 * Configure the tabs behavior.
 */
const jekyllTabsConfiguration = {
  syncTabsWithSameLabels: false,
  addCopyToClipboardButton: false,
  copyToClipboardButtonHtml: '<button>Copy</button>',
};

const jekyllTabsModule = (function() {

  /**
   * Remove all "active" classes on li elements that belong to the given ul element.
   */
  const removeActiveClasses = function (ulElement) {
      const liElements = ulElement.querySelectorAll('ul > li');

      Array.prototype.forEach.call(liElements, function(liElement) {
          liElement.classList.remove('active');
      });
  }

  /**
   * Get the element position looking from the perspective of the parent element.
   *
   * Considering the following html:
   *
   * <ul>
   *   <li class="zero">0</li>
   *   <li class="one">1</li>
   *   <li class="two">2</li>
   * </ul>
   *
   * Then getChildPosition(document.querySelector('.one')) would return 1.
   */
  const getChildPosition = function (element) {
      var parent = element.parentNode;
      var i = 0;

      for (var i = 0; i < parent.children.length; i++) {
          if (parent.children[i] === element) {
              return i;
          }
      }

      throw new Error('No parent found');
  }

  /**
   * Returns a list of elements of the given tag that contains the given text.
   */
  const findElementsContaining = function(elementTag, text) {
      const elements = document.querySelectorAll(elementTag);
      const elementsThatContainText = [];

      for (let i = 0; i < elements.length; i++) {
          const element = elements[i];

          if (element.textContent.includes(text)) {
              elementsThatContainText.push(element);
          }
      }

      return elementsThatContainText;
  }

  /**
   * Handle adding or removing active classes on tab list items.
   */
  const handleTabClicked = function(link) {
      liTab = link.parentNode;
      ulTab = liTab.parentNode;
      liPositionInUl = getChildPosition(liTab);

      if (liTab.className.includes('active')) {
          return;
      }

      tabContentId = ulTab.getAttribute('data-tab');
      tabContentElement = document.getElementById(tabContentId);

      // Remove all "active" classes first.
      removeActiveClasses(ulTab);
      removeActiveClasses(tabContentElement);

      // Then add back active classes depending on the tab (ul element) that was clicked on.
      tabContentElement.querySelectorAll('ul > li')[liPositionInUl].classList.add('active');
      liTab.classList.add('active');
  }

  /**
   * Create a javascript element from html markup.
   */
  const createElementFromHtml = function(html) {
      const template = document.createElement('template');
      template.innerHTML = html.trim();

      return template.content.firstChild;
  }

  /**
   * Copy the given text in the clipboard.
   *
   * See https://stackoverflow.com/questions/51805395/navigator-clipboard-is-undefined
   */
  const copyToClipboard = function(text) {
      if (navigator.clipboard && window.isSecureContext) {
          navigator.clipboard.writeText(text);
      } else {
          // Use the 'out of viewport hidden text area' trick
          const textArea = document.createElement("textarea");
          textArea.value = text;

          // Move textarea out of the viewport so it's not visible
          textArea.style.position = "absolute";
          textArea.style.left = "-999999px";

          document.body.prepend(textArea);
          textArea.select();

          try {
              document.execCommand('copy');
          } catch (error) {
              console.error(error);
          } finally {
              textArea.remove();
          }
      };
  }

  return {
      findElementsContaining,
      handleTabClicked,
      createElementFromHtml,
      copyToClipboard,
  };

})();

window.addEventListener('load', function () {
  const tabLinks = document.querySelectorAll('ul.tab > li > a');

  Array.prototype.forEach.call(tabLinks, function(link) {
      link.addEventListener('click', function (event) {
          event.preventDefault();

          jekyllTabsModule.handleTabClicked(link);

          if (jekyllTabsConfiguration.syncTabsWithSameLabels) {
              const linksWithSameName = jekyllTabsModule.findElementsContaining('a', link.textContent);

              for(let i = 0; i < linksWithSameName.length; i++) {
                  if (linksWithSameName[i] !== link) {
                      jekyllTabsModule.handleTabClicked(linksWithSameName[i]);
                  }
              }
          }
      }, false);
  });

  if (jekyllTabsConfiguration.addCopyToClipboardButton) {
      const preElements = document.querySelectorAll('ul.tab-content > li pre');

      for(let i = 0; i < preElements.length; i++) {
          const preElement = preElements[i];
          const preParentNode = preElement.parentNode;
          const button = jekyllTabsModule.createElementFromHtml(jekyllTabsConfiguration.copyToClipboardButtonHtml);

          preParentNode.style.position = 'relative';
          button.style.position = 'absolute';
          button.style.top = '0px';
          button.style.right = '0px';

          preParentNode.appendChild(button);

          button.addEventListener('click', function () {
              jekyllTabsModule.copyToClipboard(preElement.innerText);
          });
      }
  }

});