import { uniqBy as uniqByToolkit } from '../../array/uniqBy.ts';
import { ary } from '../../function/ary.ts';
import { identity } from '../../function/identity.ts';
import { ValueIteratee } from '../_internal/ValueIteratee.ts';
import { isArrayLikeObject } from '../predicate/isArrayLikeObject.ts';
import { iteratee as createIteratee } from '../util/iteratee.ts';

/**
 * Creates a duplicate-free version of an array, using an optional transform function.
 *
 * @template T
 * @param array - The array to inspect.
 * @param iteratee - The transform function or property name to get values from.
 * @returns Returns the new duplicate-free array.
 *
 * @example
 * uniqBy([2.1, 1.2, 2.3], Math.floor);
 * // => [2.1, 1.2]
 */
export function uniqBy<T>(array: ArrayLike<T> | null | undefined, iteratee: ValueIteratee<T>): T[];
export function uniqBy<T>(
  array: ArrayLike<T> | null | undefined,
  iteratee: ((value: T) => unknown) | PropertyKey | [keyof T, unknown] | Partial<T> = identity
): T[] {
  if (!isArrayLikeObject(array)) {
    return [];
  }

  return uniqByToolkit(Array.from(array), ary(createIteratee(iteratee), 1));
}
