import { extend, isNullOrUndefined, isBlazor, getValue } from '../util';
import { ParserBase as parser } from './parser-base';
import { IntlBase as base } from './intl-base';
var parseRegex = /^([^0-9]*)(([0-9,]*[0-9]+)(\.[0-9]+)?)([Ee][+-]?[0-9]+)?([^0-9]*)$/;
var groupRegex = /,/g;
var keys = ['minusSign', 'infinity'];
/**
 * Module for Number Parser.
 *
 * @private
 */
var NumberParser = /** @class */ (function () {
    function NumberParser() {
    }
    /**
     * Returns the parser function for given skeleton.
     *
     * @param {string} culture -  Specifies the culture name to be which formatting.
     * @param {NumberFormatOptions} option - Specific the format in which number  will parsed.
     * @param {Object} cldr - Specifies the global cldr data collection.
     * @returns {Function} ?
     */
    NumberParser.numberParser = function (culture, option, cldr) {
        var _this = this;
        var dependable = base.getDependables(cldr, culture, '', true);
        var parseOptions = { custom: true };
        var numOptions;
        if ((base.formatRegex.test(option.format)) || !(option.format)) {
            extend(parseOptions, base.getProperNumericSkeleton(option.format || 'N'));
            parseOptions.custom = false;
            if (!parseOptions.fractionDigits) {
                if (option.maximumFractionDigits) {
                    parseOptions.maximumFractionDigits = option.maximumFractionDigits;
                }
            }
        }
        else {
            extend(parseOptions, base.customFormat(option.format, null, null));
        }
        var numbers = getValue('numbers', dependable.parserObject);
        // eslint-disable-next-line
        numOptions = parser.getCurrentNumericOptions(dependable.parserObject, parser.getNumberingSystem(cldr), true, isBlazor());
        parseOptions.symbolRegex = parser.getSymbolRegex(Object.keys(numOptions.symbolMatch));
        // eslint-disable-next-line
        parseOptions.infinity = numOptions.symbolNumberSystem[keys[1]];
        var symbolpattern;
        if (!isBlazor()) {
            symbolpattern = base.getSymbolPattern(parseOptions.type, numOptions.numberSystem, dependable.numericObject, parseOptions.isAccount);
            if (symbolpattern) {
                symbolpattern = symbolpattern.replace(/\u00A4/g, base.defaultCurrency);
                var split = symbolpattern.split(';');
                parseOptions.nData = base.getFormatData(split[1] || '-' + split[0], true, '');
                parseOptions.pData = base.getFormatData(split[0], true, '');
            }
        }
        else {
            parseOptions.nData = extend({}, {}, getValue(parseOptions.type + 'nData', numbers));
            parseOptions.pData = extend({}, {}, getValue(parseOptions.type + 'pData', numbers));
            if (parseOptions.type === 'currency' && option.currency) {
                base.replaceBlazorCurrency([parseOptions.pData, parseOptions.nData], getValue('currencySymbol', numbers), option.currency);
            }
        }
        return function (value) {
            return _this.getParsedNumber(value, parseOptions, numOptions);
        };
    };
    /**
     * Returns parsed number for the provided formatting options
     *
     * @param {string} value ?
     * @param {NumericParts} options ?
     * @param {NumericOptions} numOptions ?
     * @returns {number} ?
     */
    NumberParser.getParsedNumber = function (value, options, numOptions) {
        var isNegative;
        var isPercent;
        var tempValue;
        var lead;
        var end;
        var ret;
        if (value.indexOf(options.infinity) !== -1) {
            return Infinity;
        }
        else {
            value = parser.convertValueParts(value, options.symbolRegex, numOptions.symbolMatch);
            value = parser.convertValueParts(value, numOptions.numberParseRegex, numOptions.numericPair);
            value = value.indexOf('-') !== -1 ? value.replace('-.', '-0.') : value;
            if (value.indexOf('.') === 0) {
                value = '0' + value;
            }
            var matches = value.match(parseRegex);
            if (isNullOrUndefined(matches)) {
                return NaN;
            }
            lead = matches[1];
            tempValue = matches[2];
            var exponent = matches[5];
            end = matches[6];
            isNegative = options.custom ? ((lead === options.nData.nlead) && (end === options.nData.nend)) :
                ((lead.indexOf(options.nData.nlead) !== -1) && (end.indexOf(options.nData.nend) !== -1));
            isPercent = isNegative ?
                options.nData.isPercent :
                options.pData.isPercent;
            tempValue = tempValue.replace(groupRegex, '');
            if (exponent) {
                tempValue += exponent;
            }
            ret = +tempValue;
            if (options.type === 'percent' || isPercent) {
                ret = ret / 100;
            }
            if (options.custom || options.fractionDigits) {
                ret = parseFloat(ret.toFixed(options.custom ?
                    (isNegative ? options.nData.maximumFractionDigits : options.pData.maximumFractionDigits) : options.fractionDigits));
            }
            if (options.maximumFractionDigits) {
                ret = this.convertMaxFracDigits(tempValue, options, ret, isNegative);
            }
            if (isNegative) {
                ret *= -1;
            }
            return ret;
        }
    };
    NumberParser.convertMaxFracDigits = function (value, options, ret, isNegative) {
        var decimalSplitValue = value.split('.');
        if (decimalSplitValue[1] && decimalSplitValue[1].length > options.maximumFractionDigits) {
            ret = +(ret.toFixed(options.custom ?
                (isNegative ? options.nData.maximumFractionDigits : options.pData.maximumFractionDigits) : options.maximumFractionDigits));
        }
        return ret;
    };
    return NumberParser;
}());
export { NumberParser };
