import { unzip as unzipToolkit } from '../../array/unzip.ts';
import { isArray } from '../predicate/isArray.ts';
import { isArrayLikeObject } from '../predicate/isArrayLikeObject.ts';

/**
 * Gathers elements in the same position in an internal array
 * from a grouped array of elements and returns them as a new array.
 *
 * The returned array's length matches the longest nested array.
 * Missing positions in shorter arrays are filled with `undefined`.
 *
 * @template T - The type of elements in the nested array.
 * @param array - The nested array to unzip.
 * @returns A new array of unzipped elements.
 *
 * @example
 * const zipped = [['a', true, 1],['b', false, 2]];
 * const result = unzip(zipped);
 * // result will be [['a', 'b'], [true, false], [1, 2]]
 */
export function unzip<T>(array: T[][] | ArrayLike<ArrayLike<T>> | null | undefined): T[][] {
  if (!isArrayLikeObject(array) || !array.length) {
    return [];
  }
  array = isArray(array) ? array : Array.from(array);
  array = (array as T[][]).filter(item => isArrayLikeObject(item));
  return unzipToolkit(array as T[][]);
}
