(function() {
  'use strict';

  var SHOW_HIDE_UTIL_NAME = 'showHide';
  var SHOW_HIDE_UTIL_SELECTOR = '[uw-show-hide]';

  var SHOW_HIDE_LOCAL_STORAGE_KEY = 'SHOW_HIDE';
  var SHOW_HIDE_INITIALIZED_CLASS = 'show-hide--initialized';
  var SHOW_HIDE_COLLAPSED_CLASS = 'show-hide--collapsed';
  var SHOW_HIDE_TOGGLE_CLASS = 'show-hide__toggle';
  var SHOW_HIDE_TOGGLE_RIGHT_CLASS = 'show-hide__toggle--right';

  /**
   *
   * ShowHide Utility
   *
   * Attribute: uw-show-hide
   *
   * Params: (all optional)
   *  data-show-hide-id: string
   *    If this param is given the state of the utility will be persisted in the clients local storage.
   *  data-show-hide-collapsed: boolean property
   *    If this param is present the ShowHide utility will be collapsed. This value will be overruled by any value stored in the LocalStorage.
   *  data-show-hide-align: 'right'
   *    Where to put the arrow that marks the element as a ShowHide toggle. Left of toggle by default.
   *
   * Example usage:
   * <div>
   *   <div uw-show-hide>Click me
   *   <div>This will be toggled
   *   <div>This will be toggled as well
   */
  var showHideUtil = function(element) {

    var showHideId;

    function init() {
      if (!element) {
        throw new Error('ShowHide utility cannot be setup without an element!');
      }

      if (element.classList.contains(SHOW_HIDE_INITIALIZED_CLASS)) {
        return false;
      }

      // register click listener
      addClickListener();

      // param showHideId
      if (element.dataset.showHideId) {
        showHideId = element.dataset.showHideId;
      }

      // param showHideCollapsed
      var collapsed = false;
      if (element.dataset.showHideCollapsed !== undefined) {
        collapsed = true;
      }
      if (showHideId) {
        var localStorageCollapsed = getLocalStorage()[showHideId];
        if (typeof localStorageCollapsed !== 'undefined') {
          collapsed = localStorageCollapsed;
        }
      }
      element.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS, collapsed);

      // param showHideAlign
      var alignment = element.dataset.showHideAlign;
      if (alignment === 'right') {
        element.classList.add(SHOW_HIDE_TOGGLE_RIGHT_CLASS);
      }

      // mark as initialized
      element.classList.add(SHOW_HIDE_INITIALIZED_CLASS, SHOW_HIDE_TOGGLE_CLASS);

      return {
        name: SHOW_HIDE_UTIL_NAME,
        element: element,
        destroy: function() {},
      };
    }

    function addClickListener() {
      element.addEventListener('click', function clickListener() {
        var newState = element.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS);

        if (showHideId) {
          setLocalStorage(showHideId, newState);
        }
      });
    }

    function setLocalStorage(id, state) {
      var lsData = getLocalStorage();
      lsData[id] = state;
      window.localStorage.setItem(SHOW_HIDE_LOCAL_STORAGE_KEY, JSON.stringify(lsData));
    }

    function getLocalStorage() {
      return JSON.parse(window.localStorage.getItem(SHOW_HIDE_LOCAL_STORAGE_KEY)) || {};
    }

    return init();
  };

  if (UtilRegistry) {
    UtilRegistry.register({
      name: SHOW_HIDE_UTIL_NAME,
      selector: SHOW_HIDE_UTIL_SELECTOR,
      setup: showHideUtil
    });
  }

})();
