(function() {
  'use strict';

  window.utils = window.utils || {};

  var ALERTS_CLASS = 'alerts';
  var ALERTS_TOGGLER_CLASS = 'alerts__toggler';
  var ALERTS_TOGGLER_VISIBLE_CLASS = 'alerts__toggler--visible';
  var ALERTS_TOGGLER_APPEAR_DELAY = 120;

  var ALERT_CLASS = 'alert';
  var ALERT_CLOSER_CLASS = 'alert__closer';
  var ALERT_INVISIBLE_CLASS = 'alert--invisible';
  var ALERT_AUTO_HIDE_DELAY = 10;
  var ALERT_AUTOCLOSING_MATCHER = '.alert-info, .alert-success';

  var JS_INITIALIZED_CLASS = 'js-initialized';

  window.utils.alerts = function(alertsEl) {

    if (alertsEl.classList.contains(JS_INITIALIZED_CLASS)) {
      return false;
    }

    if (!alertsEl || !alertsEl.classList.contains(ALERTS_CLASS)) {
      throw new Error('utils.alerts has to be called with alerts element');
    }

    var togglerCheckRequested = false;

    var togglerEl = alertsEl.querySelector('.' + ALERTS_TOGGLER_CLASS);

    var alertElements = Array.from(alertsEl.querySelectorAll('.' + ALERT_CLASS))
      .filter(function(alert) {
        return !alert.classList.contains(JS_INITIALIZED_CLASS);
      });

    function initToggler() {
      togglerEl.addEventListener('click', function() {
        alertElements.forEach(function(alertEl) {
          toggleAlert(alertEl, true);
        });
        togglerEl.classList.remove(ALERTS_TOGGLER_VISIBLE_CLASS);
      });
      alertsEl.classList.add(JS_INITIALIZED_CLASS);
    }

    function initAlert(alertEl) {
      var autoHideDelay = ALERT_AUTO_HIDE_DELAY;
      if (alertEl.dataset.decay) {
        autoHideDelay = parseInt(alertEl.dataset.decay, 10);
      }

      var closeEl = alertEl.querySelector('.' + ALERT_CLOSER_CLASS);
      closeEl.addEventListener('click', function() {
        toggleAlert(alertEl);
      });

      if (autoHideDelay > 0 && alertEl.matches(ALERT_AUTOCLOSING_MATCHER)) {
        window.setTimeout(function() {
          toggleAlert(alertEl);
        }, autoHideDelay * 1000);
      }

      alertEl.classList.add(JS_INITIALIZED_CLASS);
    }

    function toggleAlert(alertEl, visible) {
      alertEl.classList.toggle(ALERT_INVISIBLE_CLASS, !visible);
      checkToggler();
    }

    function checkToggler() {
      if (togglerCheckRequested) {
        return;
      }

      var alertsHidden = alertElements.reduce(function(acc, alert) {
        return acc && alert.classList.contains(ALERT_INVISIBLE_CLASS);
      }, true);

      window.setTimeout(function() {
        togglerEl.classList.toggle(ALERTS_TOGGLER_VISIBLE_CLASS, alertsHidden);
        togglerCheckRequested = false;
      }, ALERTS_TOGGLER_APPEAR_DELAY);
    }

    initToggler();
    alertElements.forEach(initAlert);

    return {
      scope: alertsEl,
      destroy: function() {},
    };
  };
})();
