if (typeof(Storage) !== "undefined") {

  class CollapseState {
    static get _KEY() { return "collapseState"; }

    set(id, value) {
      const state = this._state;
      state[id] = value;
      window.localStorage.setItem(CollapseState._KEY, JSON.stringify(state));
    }

    get(id) {
      const state = this._state;
      return state[id];
    }

    get _state() {
      if (window.localStorage.getItem(CollapseState._KEY) === null) {
        window.localStorage.setItem(CollapseState._KEY, JSON.stringify({}));
      }

      const data = window.localStorage.getItem(CollapseState._KEY);
      return JSON.parse(data);
    }
  }

  // EVENT HANDLER - Store state when element is hidden
  $(document).on("hidden.bs.collapse", (event) => {
    const state = new CollapseState();
    state.set(event.target.id, "hide");
  });

  // EVENT HANDLER - Store state when element is shown
  $(document).on("shown.bs.collapse", (event) => {
    const state = new CollapseState();
    state.set(event.target.id, "show");
  });

  // Set initial state of elements from storage
  $(document).on("turbolinks:load", function() {
    const state = new CollapseState();
    const collapsibles = document.querySelectorAll("[data-toggle=collapse][data-behavior=stateful]");

    collapsibles.forEach( (collapsible) => {
      const targetSelector = collapsible.dataset.target.toString().replace("#", "");
      const target = document.getElementById(targetSelector);
      const value = state.get(target.id);

      switch (value) {
        case "show":
          collapsible.classList.remove("collapsed");
          target.classList.add("show");
          break;
        case "hide":
          collapsible.classList.add("collapsed");
          target.classList.remove("show");
          break;
      }
    })
  });

} else {
  console.log("No Web Storage support..");
}
