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

declare global {
  interface Generator<T = unknown, TReturn = any, TNext = unknown> {
    /**
     * Returns the maximum value in a sequence of number values.
     * @returns The maximum value in the sequence.
     */
    max(this: Generator<number, TReturn, TNext>): number;
    /**
     * Invokes a transform function on each element of a generic
     * sequence and returns the maximum resulting value.
     * @param selector A transform function to apply to each element.
     * @returns The maximum value in the sequence.
     */
    max(selector: (item: T) => number): number;
  }

  interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> {
    /**
     * Returns the maximum value in a sequence of number values.
     * @returns The maximum value in the sequence.
     */
    max(this: Generator<number, TReturn, TNext>): Promise<number>;
    /**
     * Invokes a transform function on each element of a generic
     * sequence and returns the maximum resulting value.
     * @param selector A transform function to apply to each element.
     * @returns The maximum value in the sequence.
     */
    max(selector: (item: T) => Promised<number>): Promise<number>;
  }
}

Build(
  "max",
  function (selector = (i) => i as number) {
    return Math.max(...this.select(selector).array());
  },
  async function (selector = (i) => i as number) {
    return Math.max(...(await this.select(selector).array()));
  }
);
