import { Big } from 'big.js';
import { OneOrMore } from './typeHelpers.mjs';

type BigNumberSource = number | bigint | string | Big | BigNumber;
type BigNumber = Omit<Big, keyof Big> & {
    ___B: "BigNumber";
};
declare namespace BigNumber {
    const roundUp: 3, roundDown: 0, roundHalfUp: 1, roundHalfEven: 2;
    type RoundingMode = typeof roundUp | typeof roundDown | typeof roundHalfUp | typeof roundHalfEven;
    const setDefaultRoundingMode: (roundingMode: RoundingMode) => void;
    const isBigNumber: (num: any) => num is BigNumber;
    const safeFrom: (value: BigNumberSource) => undefined | BigNumber;
    const from: (value: BigNumberSource) => BigNumber;
    const toString: (value: BigNumberSource) => string;
    const toNumber: (value: BigNumberSource) => number;
    const toBigInt: Curry2<[options: {
        roundingMode?: RoundingMode;
    }, value: BigNumberSource], bigint>;
    const toFixed: Curry2<[options: {
        precision?: number;
        roundingMode?: RoundingMode;
    }, value: BigNumberSource], string>;
    const toExponential: Curry2<[options: {
        precision?: number;
        roundingMode?: RoundingMode;
    }, value: BigNumberSource], string>;
    const isNegative: (value: BigNumberSource) => boolean;
    const isGtZero: (value: BigNumberSource) => boolean;
    const isZero: (value: BigNumberSource) => boolean;
    const isEq: Curry2<[value: BigNumberSource, a: BigNumberSource], boolean>;
    const isGt: Curry2<[value: BigNumberSource, a: BigNumberSource], boolean>;
    const isGte: Curry2<[value: BigNumberSource, a: BigNumberSource], boolean>;
    const isLt: Curry2<[value: BigNumberSource, a: BigNumberSource], boolean>;
    const isLte: Curry2<[value: BigNumberSource, a: BigNumberSource], boolean>;
    const setPrecision: Curry2<[options: {
        precision?: number;
        roundingMode?: RoundingMode;
    }, value: BigNumberSource], BigNumber>;
    const getPrecision: (value: BigNumberSource) => number;
    const getIntegerLength: (value: BigNumberSource) => number;
    const leftMoveDecimals: Curry2<[distance: number, value: BigNumberSource], BigNumber>;
    const rightMoveDecimals: Curry2<[distance: number, value: BigNumberSource], BigNumber>;
    const moveDecimals: Curry2<[options: {
        distance: number;
    }, value: BigNumberSource], BigNumber>;
    const getDecimalPart: Curry2<[options: {
        precision: number;
    }, value: BigNumberSource], string | undefined>;
    const abs: (value: BigNumberSource) => BigNumber;
    const neg: (value: BigNumberSource) => BigNumber;
    const sqrt: (value: BigNumberSource) => BigNumber;
    const add: Curry2<[value: BigNumberSource, a: BigNumberSource], BigNumber>;
    const minus: Curry2<[value: BigNumberSource, a: BigNumberSource], BigNumber>;
    const mul: Curry2<[value: BigNumberSource, a: BigNumberSource], BigNumber>;
    /**
     * @example
     * cumulativeMul(v, [a, b, c]) // =>
     * [
     *   v,
     *   v * a,
     *   v * a * b,
     *   v * a * b * c
     * ]
     */
    const cumulativeMul: Curry2<[value: BigNumberSource, as: readonly BigNumberSource[]], OneOrMore<BigNumber>>;
    const div: Curry2<[value: BigNumberSource, a: BigNumberSource], BigNumber>;
    const pow: Curry2<[value: BigNumberSource, a: number], BigNumber>;
    const round: Curry2<[options: {
        precision?: number;
        roundingMode?: RoundingMode;
    }, value: BigNumberSource], BigNumber>;
    const toPrecision: Curry2<[options: {
        precision?: number;
        roundingMode?: RoundingMode;
    }, value: BigNumberSource], string>;
    const ascend: Curry2<[a: BigNumberSource, b: BigNumberSource], 0 | 1 | -1>;
    const descend: Curry2<[a: BigNumberSource, b: BigNumberSource], 0 | 1 | -1>;
    const sort: (comparator: (a: BigNumber, b: BigNumber) => -1 | 0 | 1, numbers: readonly BigNumberSource[]) => BigNumber[];
    const max: (numbers: OneOrMore<BigNumberSource>) => BigNumber;
    const min: (numbers: OneOrMore<BigNumberSource>) => BigNumber;
    const clamp: (range: [min: BigNumber, max: BigNumber], n: BigNumber) => BigNumber;
    const sum: (numbers: BigNumberSource[]) => BigNumber;
    const ZERO: BigNumber;
    const ONE: BigNumber;
}
interface Curry2<Args extends [any, any], Ret> {
    (a: Args[0]): (b: Args[1]) => Ret;
    (a: Args[0], b: Args[1]): Ret;
}

export { BigNumber, type BigNumberSource };
