// Copyright (c) 2020-2021 Drew Lemmy
// This file is part of TenebraWeb 2 under AGPL-3.0.
// Full details: https://github.com/tmpim/TenebraWeb2/blob/master/LICENSE.txt
/** Sort an array in-place in a human-friendly manner. */
export function localeSort(arr: any[]): void {
  arr.sort((a, b) => a.localeCompare(b, undefined, {
    sensitivity: "base",
    numeric: true
  }));
}

/**
 * Sorting function that pushes nullish to the end of the array.
 *
 * @param key - The property of T to sort by.
 * @param human - Whether or not to use a human-friendly locale sort for
 *   string values.
*/
export const keyedNullSort = <T>(key: keyof T, human?: boolean) => (a: T, b: T, sortOrder?: "ascend" | "descend" | null): number => {
  // We effectively reverse the sort twice when sorting in 'descend' mode, as
  // ant-design will internally reverse the array, but we always want to push
  // nullish values to the end.
  const va = sortOrder === "descend" ? b[key] : a[key];
  const vb = sortOrder === "descend" ? a[key] : b[key];

  // Push nullish values to the end
  if (va === vb) return 0;
  if (va === undefined || va === null) return 1;
  if (vb === undefined || vb === null) return -1;

  if (typeof va === "string" && typeof vb === "string") {
    // Use localeCompare for strings
    const ret = va.localeCompare(vb, undefined, human ? {
      sensitivity: "base",
      numeric: true
    } : undefined);
    return sortOrder === "descend" ? -ret : ret;
  } else {
    // Use the built-in comparison for everything else (mainly numbers)
    return sortOrder === "descend"
      ? (vb as any) - (va as any)
      : (va as any) - (vb as any);
  }
};
