src/components/providers/Menu/utils.js

const toObject = (arry = []) =>
  arry.reduce((accu, i) => ({...accu, [i.id]: i}), {});

const populate = (arr, sourceEntity, populateEntityFrom) =>
  arr[sourceEntity].map((i) => ({
    ...i,
    [populateEntityFrom]: i[populateEntityFrom].reduce((accu, x) => {
      const entity = arr[populateEntityFrom].find((t) => t.id === x);
      if (entity) {
        accu.push(entity);
      }
      return accu;
    }, []),
  }));

const populateSubgroups = (arr) =>
  arr.map((i) => ({
    ...i,
    subgroups: i.subgroups.reduce((accu, x) => {
      const entity = arr.find((t) => t.id === x);
      if (entity) {
        accu.push(entity);
      }
      return accu;
    }, []),
  }));

const getUpsellsItemPrice = (item, itemHash) => {
  const priceRange = item.options
    .filter((option) => option && option.min !== 0)
    .reduce(
      (acc, cur) => {
        const prices = cur.items.map((i) => {
          return itemHash[i]?.price ?? 0;
        });
        return prices.some((val) => val !== 0)
          ? [
              acc[0] + Math.min(...prices) * cur.min,
              acc[1] + Math.max(...prices) * cur.min,
            ]
          : [item.price, item.price];
      },
      [item.price, item.price],
    );
  const price = priceRange.every((i) => i === priceRange[0])
    ? priceRange[0]
    : priceRange;
  return price;
};

const updateItems = (itemsMapped = [], isUpsells = false) =>
  itemsMapped
    .reduce(
      (accu, currItem) => [
        ...accu,
        {
          ...currItem,
          ...{
            // Additional item props to add or change
            isNested: false,
          },
          ...(isUpsells && {
            // Upsell only item props to add
            priceRange: getUpsellsItemPrice(currItem, toObject(itemsMapped)),
          }),
        },
      ],
      [],
    )
    .sort((a, b) => a.priority || 0 - b.priority || 0);

const sortGroups = (groupData) =>
  groupData.sort((a, b) => {
    const priorityA = a.priority || 0;
    const priorityB = b.priority || 0;
    return priorityB - priorityA;
  });

const sortNestedEntityByPriority = (arr) =>
  arr.sort((a, b) => {
    const priorityA = a ? a.priority || 0 : 0;
    const priorityB = b ? b.priority || 0 : 0;
    return priorityB - priorityA;
  });

/**
 * Trim groupHash Value and return the first two of each menu group
 *
 * @param {object} menuGroupHash - Either upsell, item, empty default to item
 * @returns {object}
 */
const getMarketMenuMap = (menuGroupHash) =>
  Object.entries(menuGroupHash).reduce((acc, [id, group]) => {
    return {
      ...acc,
      [id]: {
        ...group,
        items: group.items.slice(0, 2),
      },
    };
  }, {});

/**
 * Receive a array of menus and generate a Map with structure of [restaurantGroupId] : [menu, menu]
 *
 * @param {array} menuGroupHash - Either upsell, item, empty default to item
 * @returns {object}
 */
const createUniqueResGroupMap = (menuArr) => {
  const tempMap = new Map();
  menuArr.forEach((menuItem) => {
    if (tempMap.has(menuItem.restaurantGroup)) {
      tempMap.set(menuItem.restaurantGroup, [
        ...tempMap.get(menuItem.restaurantGroup),
        menuItem,
      ]);
    } else {
      tempMap.set(menuItem.restaurantGroup, [menuItem]);
    }
  });
  return tempMap;
};

const setImageUrlToHttps = (menuObj) => {
  const newObj = menuObj || {};
  Object.keys(newObj).forEach((key) => {
    const element = newObj[key];
    element.forEach((item) => {
      if (item?.images?.length) {
        item.images[0] = item.images[0].replace(/^http:/, "https:");
      }
    });
  });
  return newObj;
};

export {
  createUniqueResGroupMap,
  getMarketMenuMap,
  getUpsellsItemPrice,
  populate,
  populateSubgroups,
  setImageUrlToHttps,
  sortGroups,
  sortNestedEntityByPriority,
  toObject,
  updateItems,
};