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

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

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

  if (res) {
    commit('setLines', res);
    commit('setLinesTimestamp');
  }
  commit('clearLinesLoading');
}

/** Return a subset of lines from state.lines
 */
async function getLines ({commit, dispatch, state}, [projectId, {line, fsp, lsp, incr, sortBy, sortDesc, itemsPerPage, page, text}]) {
  let filteredLines = [...state.lines];

  if (sortBy) {

    sortBy.forEach( (key, idx) => {
      filteredLines.sort( (el0, el1) => {
        const a = el0?.[key];
        const b = el1?.[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) {
        filteredLines.reverse();
      }
    });

  }

  if (line) {
    filteredLines = filteredLines.filter( line => line.line == line );
  }

  if (fsp) {
    filteredLines = filteredLines.filter( line => line.fsp == fsp );
  }

  if (lsp) {
    filteredLines = filteredLines.filter( line => line.lsp == lsp );
  }

  if (text) {
    const numberFilter = (value, search, item) => {
      return value == search;
    };

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

    const incrFilter = (value, search, item) => {
      const inc = /^(incr(ement)?|↑|\+)/i;
      const dec = /^(decr(ement)?|↓|-)/i;
      return (inc.test(search) && value) || (dec.test(search) && !value)
    }

    const searchFunctions = {
      line: numberFilter,
      fsp: numberFilter,
      lsp: numberFilter,
      remarks: textFilter,
      incr: incrFilter,
      ntba: (value, search, item) => text.toLowerCase() == "ntba" && value
    };

    filteredLines = filteredLines.filter ( line => {
      for (let key in searchFunctions) {
        const fn = searchFunctions[key];
        if (fn(line[key], text, line)) {
          return true;
        }
      }
      return false;
    });
  }

  const count = filteredLines.length;

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

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

  return {lines: filteredLines, count};
}

export default { refreshLines, getLines };
