Utils PassioNutrient


import type {
  PassioFoodItem,
  PassioIDAttributes,
  PassioRecipe,
  UnitMass,
} from '@passiolife/nutritionai-react-native-sdk-v3';
import type { MacroChartData } from '../screens/nutrients/macro/useMacrosNutrients';

// Define the types of nutrients
export type NutrientsTypes =
  | 'calories'
  | 'protein'
  | 'carbs'
  | 'fat'
  | 'saturatedFat'
  | 'transFat'
  | 'polyunsaturatedFat'
  | 'sodium'
  | 'fiber'
  | 'sugar'
  | 'sugarAdded'
  | 'vitaminD'
  | 'iron'
  | 'potassium'
  | 'vitaminA'
  | 'vitaminC'
  | 'alcohol'
  | 'sugarAlcohol'
  | 'vitaminB12'
  | 'vitaminB12Added'
  | 'vitaminB6'
  | 'vitaminE'
  | 'vitaminEAdded'
  | 'phosphorus'
  | 'iodine'
  | 'cholesterol';

// Define the structure of individual nutrients
export interface Nutrients {
  unitMass?: UnitMass;
  name: NutrientsTypes;
}

export const getNutrientsFromRecipe = (
  recipe: PassioRecipe,
  type: NutrientsTypes[]
): Nutrients[] => {
  let nutrients: Nutrients[] = [];
  recipe.foodItems.forEach((item) => {
    nutrients.push(...getNutrients(item, type));
  });
  return mergeNutrients(nutrients);
};

export const getNutrientsFromAttribute = (
  passioIDAttributes: PassioIDAttributes,
  nutrientNames: NutrientsTypes[]
): Nutrients[] => {
  if (passioIDAttributes.foodItem) {
    return getNutrients(passioIDAttributes.foodItem, nutrientNames);
  } else if (passioIDAttributes.recipe) {
    return getNutrientsFromRecipe(passioIDAttributes.recipe, nutrientNames);
  } else {
    return [];
  }
};

const getNutrients = (
  foodItem: PassioFoodItem,
  nutrientNames: NutrientsTypes[]
): Nutrients[] => {
  return nutrientNames
    .map((name) => { 
      // General case for other nutrients
      return getNutrient(foodItem, name);
    })
    .filter((item): item is Nutrients => !!item);
};

export const getNutrientFromRecipe = (
  recipe: PassioRecipe,
  type: NutrientsTypes
): Nutrients[] => {
  let nutrients: Nutrients[] = [];
  recipe.foodItems.forEach((item) => {
    const result = getNutrient(item, type);
    if (result) {
      nutrients.push(result);
    }
  });
  return mergeNutrients(nutrients);
};

// Get a single nutrient from Passio Food Item
const getNutrient = (
  foodItem: PassioFoodItem,
  name: NutrientsTypes
): Nutrients | null => {
  if (foodItem[name]) {
    return {
      name,
      unitMass: foodItem[name] ?? undefined,
    } as Nutrients;
  } else {
    return null;
  }
};

export const micros: NutrientsTypes[] = [
  'saturatedFat',
  'transFat',
  'polyunsaturatedFat',
  'sodium',
  'fiber',
  'sugar',
  'sugarAdded',
  'vitaminD',
  'iron',
  'potassium',
  'vitaminA',
  'alcohol',
  'sugarAlcohol',
  'vitaminB12',
  'vitaminB12Added',
  'vitaminB6',
  'vitaminE',
  'vitaminEAdded',
  'phosphorus',
  'iodine',
  'cholesterol',
];

export const macros: NutrientsTypes[] = ['calories', 'carbs', 'protein', 'fat'];

export const formatNutrient = (value?: number): number => {
  try {
    return Number((value ? value : 0).toFixed(2));
  } catch (e) {
    return -1;
  }
};

export const mergeNutrients = (nutrientsArray: Nutrients[]): Nutrients[] => {
  const mergedMap = new Map<NutrientsTypes, Nutrients>();

  for (const nutrient of nutrientsArray) {
    const { name, unitMass } = nutrient;

    if (mergedMap.has(name)) {
      // Nutrient with the same name already exists, add their values
      const existingNutrient = mergedMap.get(name);
      if (existingNutrient && unitMass?.value !== undefined) {
        existingNutrient.unitMass = {
          value:
            (existingNutrient.unitMass?.value ?? 0) + (unitMass.value ?? 0),
          unit: unitMass.unit ?? '',
        };
      }
    } else {
      // Nutrient with this name doesn't exist yet, add it to the map
      mergedMap.set(name, {
        ...nutrient,
        unitMass: unitMass ? { ...unitMass } : undefined,
      });
    }
  }

  // Convert the map back to an array
  const mergedArray = Array.from(mergedMap.values());

  return mergedArray;
};

export const mergeAndSumMacroChartData = (
  data: MacroChartData[]
): MacroChartData[] => {
  const mergedData: MacroChartData[] = [];

  data.forEach((item) => {
    const existingItem = mergedData.find(
      (mergedItem) => mergedItem.label === item.label
    );

    if (existingItem) {
      existingItem.value += item.value;
    } else {
      mergedData.push({ ...item });
    }
  });

  return mergedData;
};

Last updated