import { NumberFormatDigitInternalSlots } from '@formatjs/intl-utils';
import { NumberFormatDigitOptions } from '@formatjs/intl-utils';
import { NumberFormatLocaleInternalData } from '@formatjs/intl-utils';
import { NumberFormatNotation } from '@formatjs/intl-utils';
import { RawNumberLocaleData } from '@formatjs/intl-utils';

/**
 * Check if a formatting number with unit is supported
 * @public
 * @param unit unit to check
 */
export declare function isUnitSupported(unit: string): boolean;

export declare type NumberFormat = NumberFormat_2;

/**
 * https://tc39.es/ecma402/#sec-intl-numberformat-constructor
 */
export declare const NumberFormat: NumberFormatConstructor;

declare interface NumberFormat_2 {
    resolvedOptions(): ResolvedNumberFormatOptions;
    formatToParts(x: number): NumberFormatPart[];
    format(x: number): string;
}

declare interface NumberFormatConstructor {
    new (locales?: string | string[], options?: NumberFormatOptions): NumberFormat_2;
    (locales?: string | string[], options?: NumberFormatOptions): NumberFormat_2;
    __addLocaleData(...data: RawNumberLocaleData[]): void;
    supportedLocalesOf(locales: string | string[], options?: Pick<NumberFormatOptions, 'localeMatcher'>): string[];
    getDefaultLocale(): string;
    __defaultLocale: string;
    localeData: Record<string, NumberFormatLocaleInternalData>;
    availableLocales: string[];
    polyfilled: boolean;
}

declare interface NumberFormatInternal extends NumberFormatDigitInternalSlots {
    locale: string;
    dataLocale: string;
    style: NumberFormatOptionsStyle;
    currency?: string;
    currencyDisplay: NumberFormatOptionsCurrencyDisplay;
    unit?: string;
    unitDisplay: NumberFormatOptionsUnitDisplay;
    currencySign: NumberFormatOptionsCurrencySign;
    notation: NumberFormatOptionsNotation;
    compactDisplay: NumberFormatOptionsCompactDisplay;
    signDisplay: NumberFormatOptionsSignDisplay;
    useGrouping: boolean;
    pl: Intl.PluralRules;
    boundFormat?: Intl.NumberFormat['format'];
    numberingSystem: string;
    dataLocaleData: NumberFormatLocaleInternalData;
}

export declare type NumberFormatOptions = Intl.NumberFormatOptions & NumberFormatDigitOptions & {
    localeMatcher?: NumberFormatOptionsLocaleMatcher;
    style?: NumberFormatOptionsStyle;
    compactDisplay?: NumberFormatOptionsCompactDisplay;
    currencyDisplay?: NumberFormatOptionsCurrencyDisplay;
    currencySign?: NumberFormatOptionsCurrencySign;
    notation?: NumberFormatOptionsNotation;
    signDisplay?: NumberFormatOptionsSignDisplay;
    unit?: string;
    unitDisplay?: NumberFormatOptionsUnitDisplay;
    numberingSystem?: string;
};

declare type NumberFormatOptionsCompactDisplay = 'short' | 'long';

declare type NumberFormatOptionsCurrencyDisplay = 'symbol' | 'code' | 'name' | 'narrowSymbol';

declare type NumberFormatOptionsCurrencySign = 'standard' | 'accounting';

declare type NumberFormatOptionsLocaleMatcher = 'lookup' | 'best fit';

declare type NumberFormatOptionsNotation = NumberFormatNotation;

declare type NumberFormatOptionsSignDisplay = 'auto' | 'always' | 'never' | 'exceptZero';

declare type NumberFormatOptionsStyle = 'decimal' | 'percent' | 'currency' | 'unit';

declare type NumberFormatOptionsUnitDisplay = 'long' | 'short' | 'narrow';

declare interface NumberFormatPart {
    type: NumberFormatPartTypes;
    value: string;
}

declare type NumberFormatPartTypes = Intl.NumberFormatPartTypes | 'exponentSeparator' | 'exponentMinusSign' | 'exponentInteger' | 'compact' | 'unit' | 'literal';

declare type ResolvedNumberFormatOptions = Intl.ResolvedNumberFormatOptions & Pick<NumberFormatInternal, 'currencySign' | 'unit' | 'unitDisplay' | 'notation' | 'compactDisplay' | 'signDisplay'>;

/**
 * Number.prototype.toLocaleString ponyfill
 * https://tc39.es/ecma402/#sup-number.prototype.tolocalestring
 */
export declare function toLocaleString(x: number, locales?: string | string[], options?: NumberFormatOptions): string;

export { }
