import { DrinkComposite, isDrinkWithContainers, isDrinkWithContainersAndHistory } from "./types"; function getLatestActivityTimestamp(n: DrinkComposite): Date | null { const drinkTimestamp = (n as { addedAt?: Date | null }).addedAt ?? null; if (isDrinkWithContainers(n)) { const containerTimestamps = n.containers .map((container) => (container as { lastAdded?: Date | null }).lastAdded) .filter((value): value is Date => value != null); if (containerTimestamps.length > 0) { const latestContainerTimestamp = containerTimestamps.reduce((latest, current) => current > latest ? current : latest, containerTimestamps[0]); if (drinkTimestamp == null) { return latestContainerTimestamp; } return drinkTimestamp > latestContainerTimestamp ? drinkTimestamp : latestContainerTimestamp; } } return drinkTimestamp; } function sortName(n1:DrinkComposite, n2:DrinkComposite) : number{ if (n1.name > n2.name) { return 1; } if (n1.name < n2.name) { return -1; } return 0; } function sortAbvLowHigh(n1:DrinkComposite, n2:DrinkComposite) : number{ return n1.abv - n2.abv; } function sortAbvHighLow(n1:DrinkComposite, n2:DrinkComposite) : number{ return n2.abv - n1.abv; } function totalInventory(n:DrinkComposite) : number{ if(isDrinkWithContainers(n)){ let total = 0; n.containers.map((container) =>{ total += container.inventory; }); return total; } return 0; } function sortInventoryLowHigh(n1:DrinkComposite, n2:DrinkComposite) : number{ return totalInventory(n1) - totalInventory(n2); } function sortInventoryHighLow(n1:DrinkComposite, n2:DrinkComposite) : number{ return totalInventory(n2) - totalInventory(n1); } function totalPopularity(n:DrinkComposite) : number{ if(isDrinkWithContainersAndHistory(n)){ let total = 0; n.containers.map((container) =>{ total += container.checkouts.length; }); return total; } return 0; } function sortPopularity(n1:DrinkComposite, n2:DrinkComposite) : number{ return totalPopularity(n2) - totalPopularity(n1); } function sortNewest(n1:DrinkComposite, n2:DrinkComposite) : number{ const left = getLatestActivityTimestamp(n1); const right = getLatestActivityTimestamp(n2); if (!left && !right) { return 0; } if (!left) { return 1; } if (!right) { return -1; } return right.getTime() - left.getTime(); } export function sortDrinksFromSearch(searchParams: URLSearchParams, searchResult: DrinkComposite[]) : DrinkComposite[] { var callback = sortNewest; if(searchParams.has("sort", "new")){ callback = sortNewest; } if(searchParams.has("sort", "name")){ callback = sortName; } if(searchParams.has("sort", "abv-asc")){ callback = sortAbvLowHigh; } if(searchParams.has("sort", "abv-desc")){ callback = sortAbvHighLow; } if(searchParams.has("sort", "inv-asc")){ callback = sortInventoryLowHigh; } if(searchParams.has("sort", "inv-desc")){ callback = sortInventoryHighLow; } if(searchParams.has("sort", "popular")){ callback = sortPopularity; } var sortedArray: DrinkComposite[] = searchResult.sort(callback); return sortedArray; }