
/** Fetch labels from server
 */
async function refreshLabels ({commit, dispatch, state, rootState}) {

  if (state.loading) {
    commit('abortLabelsLoading');
  }

  commit('setLabelsLoading');
  const pid = rootState.project.projectId;
  const url = `/project/${pid}/label`;
  const init = {
    cache: "reload",
    signal: state.loading.signal
  };
  const res = await dispatch('api', [url, init]);

  if (res) {
    commit('setLabels', res);
    commit('setLabelsTimestamp');
  }
  commit('clearLabelsLoading');
}

/** Return a subset of labels from state.labels.
 *
 * Note that, unlike other actions in the get* family,
 * the return value is not isomorphic to the state.
 *
 * While state.labels is an object, getLabels() returns
 * an array with each item have the shape:
 *
 * { label: "labelName", view: {…}, model: {…} }
 *
 * This is intended to be useful, for instance, for a table
 * of labels.
 */
async function getLabels ({commit, dispatch, state}, [projectId, {sortBy, sortDesc, itemsPerPage, page, text, label}]) {

  let filteredLabels = Object.entries(state.labels).map(i => {
    return {
      label: i[0],
      ...i[1]
    }
  });

  if (sortBy) {

    sortBy.forEach( (key, idx) => {
      filteredLabels.sort( (el0, el1) => {
        const a = key == "label" ? el0[0] : el0[1].view[key];
        const b = key == "label" ? el1[0] : el1[1].view[key];
        if (a < b) {
          return -1;
        } else if (a > b) {
          return 1;
        } else if (a == b) {
          return 0;
        } else if (a && !b) {
          return 1;
        } else if (!a && b) {
          return -1;
        } else {
          return 0;
        }
      });
      if (sortDesc && sortDesc[idx] === true) {
        filteredLabels.reverse();
      }
    });

  }

  if (label) {
    filteredLabels = filteredLabels.filter( label => label.label == label );
  }

  if (text) {
    const textFilter = (value, search, item) => {
      return String(value).toLowerCase().includes(search.toLowerCase());
    };

    const searchFunctions = {
      label: numberFilter,
      description: textFilter,
    };

    filteredLabels = filteredLabels.filter ( item => {
      return textFilter(item.label, text, item) ?? textFilter(item.view.description, text, item);
    });
  }

  const count = filteredLabels.length;

  if (itemsPerPage && itemsPerPage > 0) {
    const offset = (page > 0)
      ? (page-1) * itemsPerPage
      : 0;

    filteredLabels = filteredLabels.slice(offset, offset+itemsPerPage);
  }

  return {labels: filteredLabels, count};
}

export default { refreshLabels, getLabels };
