import { Build, Promised } from "./utils";

declare global {
  interface Generator<T = unknown, TReturn = any, TNext = unknown> {
    /**
     * Determines whether any element of a sequence exists or satisfies a condition.
     * @param predicate A function to test each element for a condition. Accepts all items if left undefined.
     * @returns true if the source sequence is not empty and at least one of its elements passes the test in the specified predicate; otherwise, false.
     */
    any(predicate?: (item: T) => boolean): boolean;
  }

  interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> {
    /**
     * Determines whether any element of a sequence exists or satisfies a condition.
     * @param predicate A function to test each element for a condition. Accepts all items if left undefined.
     * @returns true if the source sequence is not empty and at least one of its elements passes the test in the specified predicate; otherwise, false.
     */
    any(predicate?: (item: T) => Promised<boolean>): Promise<boolean>;
  }
}

Build(
  "any",
  function (predicate = (i) => true) {
    for (const item of this) {
      if (predicate(item)) return true;
    }

    return false;
  },
  async function (predicate = (i) => true) {
    for await (const item of this) {
      if (await Promise.resolve(predicate(item))) return true;
    }

    return false;
  }
);
