let dialogStack = {};
dialogStack.dialogs = [];

const dialogStackStore = {
  state: {
    dialogs: [],
    currentResult: null,
    currentReturnElement: null,
  },
  mutations: {
    pushDialogStack(state, {component, data, elementId, callback}){
      // Generate a new _id so that Vue knows how to shuffle the array
      const _id = Random.id();
      state.dialogs.push({
        _id,
        component,
        data,
        elementId,
        callback,
      });
      updateHistory();
    },
    replaceDialog(stat, {component, data, elementId, callback}){
      const _id = Random.id();
      if (!state.dialogs.length){
        throw new Meteor.Error("can't replace dialog if no dialogs are open");
      }
      state.dialogs.$set(0, {
        _id,
        component,
        data,
        elementId,
        callback,
      });
    },
    popDialogStackMutation (state, result){
      const dialog = state.dialogs.pop();
      state.currentResult = null;
      updateHistory();
      if (!dialog) return;
      if (dialog.callback){
        let returnElementId = dialog.callback(result);
        state.currentReturnElement = returnElementId;
      } else {
        state.currentReturnElement = null;
      }
    },
    setCurrentResult (state, result){
      state.currentResult = result;
    },
  },
  actions: {
    popDialogStack(context, result){
      if (history && history.state && history.state.openDialogs){
        context.commit("setCurrentResult", result);
        history.back();
      } else {
        context.commit("popDialogStackMutation", result);
      }
    }
  }
};

export default dialogStackStore;

const updateHistory = function(){
  // history should looks like: [{openDialogs: 0}, {openDialogs: n}] where
  // n is the number of open dialogs

  // If we can't access the history object, give up
  if (!history) return;
  // Make sure that there is a state tracking open dialogs
  // replace the state without bashing it in the process
  if (!history.state || !_.isFinite(history.state.openDialogs)){
    let newState = _.clone(history.state)  || {};
    newState.openDialogs = 0;
    history.replaceState(newState, "");
  }

  const numDialogs = dialogStackStore.state.dialogs.length;
  const stateDialogs = history.state.openDialogs;

  // If the number of dialogs and state dialogs are equal, we don't need to do
  // anything
  if (numDialogs === stateDialogs) return;

  if (stateDialogs > 0){
    // On a dialog count
    if (numDialogs === 0){
      // but shouldn't be
      history.back();
    } else {
      // but should replace with correct count
      let newState = _.clone(history.state) || {};
      newState.openDialogs = dialogStackStore.state.dialogs.length;
      history.replaceState(newState, "");
    }
  } else if (numDialogs > 0 && stateDialogs === 0){
    // On the zero state, push a dialog count
    history.pushState({openDialogs: numDialogs}, "");
  } else {
    console.warn(
      "History could not be updated correctly, unexpected case",
      {stateDialogs, numDialogs},
    )
  }
};
