/**
 * amis v3.1.0
 * Copyright 2018-2023 baidu
 */

import { __extends, __values, __awaiter, __generator, __decorate, __metadata, __assign } from 'tslib';
import React from 'react';
import { toFixed } from '@rc-component/mini-decimal';
import { normalizeOptions, resolveEventData, filter, CustomStyle, autobind, FormItem } from 'amis-core';
import cx from 'classnames';
import { NumberInput, Select } from 'amis-ui';
import { supportStatic } from './StaticHoc.js';

var numberFormatter = new Intl.NumberFormat();
var NumberControl = /** @class */ (function (_super) {
    __extends(NumberControl, _super);
    function NumberControl(props) {
        var _this = _super.call(this, props) || this;
        _this.handleChange = _this.handleChange.bind(_this);
        _this.handleChangeUnit = _this.handleChangeUnit.bind(_this);
        var unit = _this.getUnit();
        var unitOptions = normalizeOptions(props.unitOptions);
        var formItem = props.formItem, setPrinstineValue = props.setPrinstineValue, precision = props.precision, step = props.step, value = props.value;
        var normalizedPrecision = NumberInput.normalizePrecision(_this.filterNum(precision), _this.filterNum(step));
        /**
         * 如果设置了precision需要处理入参value的精度
         * 如果是带有单位的输入，则不支持精度处理
         */
        if (formItem &&
            value != null &&
            normalizedPrecision != null &&
            (!unit || unitOptions.length === 0)) {
            var normalizedValue = parseFloat(toFixed(value.toString(), '.', normalizedPrecision));
            if (!isNaN(normalizedValue)) {
                setPrinstineValue(normalizedValue);
            }
        }
        _this.state = { unit: unit, unitOptions: unitOptions };
        return _this;
    }
    /**
     * 动作处理
     */
    NumberControl.prototype.doAction = function (action, args) {
        var actionType = action === null || action === void 0 ? void 0 : action.actionType;
        var _a = this.props, min = _a.min, max = _a.max, precision = _a.precision, step = _a.step, resetValue = _a.resetValue, big = _a.big, onChange = _a.onChange, clearValueOnEmpty = _a.clearValueOnEmpty;
        if (actionType === 'clear') {
            onChange === null || onChange === void 0 ? void 0 : onChange(clearValueOnEmpty ? undefined : '');
        }
        else if (actionType === 'reset') {
            var finalPrecision = NumberInput.normalizePrecision(this.filterNum(precision), this.filterNum(step));
            var value = NumberInput.normalizeValue(resetValue !== null && resetValue !== void 0 ? resetValue : '', this.filterNum(min, big), this.filterNum(max, big), finalPrecision, resetValue !== null && resetValue !== void 0 ? resetValue : '', clearValueOnEmpty, big);
            onChange === null || onChange === void 0 ? void 0 : onChange(clearValueOnEmpty && value === '' ? undefined : value);
        }
    };
    // 解析出单位
    NumberControl.prototype.getUnit = function () {
        var e_1, _a;
        var props = this.props;
        if (props.unitOptions && props.unitOptions.length) {
            var optionValues = normalizeOptions(props.unitOptions).map(function (option) { return option.value; });
            // 如果有值就解析出来作为单位
            if (props.value && typeof props.value === 'string') {
                var unit = optionValues[0];
                // 先找长的字符，这样如果有 ab 和 b 两种后缀相同的也能识别
                optionValues.sort(function (a, b) { return b.length - a.length; });
                try {
                    for (var optionValues_1 = __values(optionValues), optionValues_1_1 = optionValues_1.next(); !optionValues_1_1.done; optionValues_1_1 = optionValues_1.next()) {
                        var optionValue = optionValues_1_1.value;
                        if (props.value.endsWith(optionValue)) {
                            unit = optionValue;
                            break;
                        }
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (optionValues_1_1 && !optionValues_1_1.done && (_a = optionValues_1.return)) _a.call(optionValues_1);
                    }
                    finally { if (e_1) throw e_1.error; }
                }
                return unit;
            }
            else {
                // 没有值就使用第一个单位
                return optionValues[0];
            }
        }
        return undefined;
    };
    NumberControl.prototype.getValue = function (inputValue) {
        var _a = this.props, resetValue = _a.resetValue, unitOptions = _a.unitOptions;
        if (inputValue &&
            typeof inputValue !== 'number' &&
            typeof inputValue !== 'string') {
            return;
        }
        if (inputValue !== null && unitOptions && this.state.unit) {
            inputValue = inputValue + this.state.unit;
        }
        return inputValue === null ? resetValue !== null && resetValue !== void 0 ? resetValue : null : inputValue;
    };
    // 派发有event的事件
    NumberControl.prototype.dispatchEvent = function (eventName) {
        return __awaiter(this, void 0, void 0, function () {
            var _a, dispatchEvent, value;
            return __generator(this, function (_b) {
                _a = this.props, dispatchEvent = _a.dispatchEvent, value = _a.value;
                dispatchEvent(eventName, resolveEventData(this.props, { value: value }));
                return [2 /*return*/];
            });
        });
    };
    NumberControl.prototype.handleChange = function (inputValue) {
        return __awaiter(this, void 0, void 0, function () {
            var _a, onChange, dispatchEvent, clearValueOnEmpty, value, resultValue, rendererEvent;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = this.props, onChange = _a.onChange, dispatchEvent = _a.dispatchEvent, clearValueOnEmpty = _a.clearValueOnEmpty;
                        value = this.getValue(inputValue);
                        resultValue = clearValueOnEmpty && value === '' ? undefined : value;
                        return [4 /*yield*/, dispatchEvent('change', resolveEventData(this.props, { value: resultValue }))];
                    case 1:
                        rendererEvent = _b.sent();
                        if (rendererEvent === null || rendererEvent === void 0 ? void 0 : rendererEvent.prevented) {
                            return [2 /*return*/];
                        }
                        onChange(resultValue);
                        return [2 /*return*/];
                }
            });
        });
    };
    /** 处理数字类的props，支持从数据域获取变量值 */
    NumberControl.prototype.filterNum = function (value, isbig) {
        if (isbig === void 0) { isbig = false; }
        if (typeof value === 'undefined') {
            return undefined;
        }
        if (typeof value !== 'number') {
            value = filter(value, this.props.data);
            // 大数模式，不转数字
            value = /^[-]?\d+/.test(value) ? (isbig ? value : +value) : undefined;
        }
        return value;
    };
    // 单位选项的变更
    NumberControl.prototype.handleChangeUnit = function (option) {
        var _this = this;
        var value = this.props.value;
        var prevUnitValue = this.state.unit;
        this.setState({ unit: option.value }, function () {
            if (value) {
                value = value.toString().replace(prevUnitValue, '');
                _this.props.onChange(value + _this.state.unit);
            }
        });
    };
    NumberControl.prototype.componentDidUpdate = function (prevProps) {
        // 匹配 数字 + ?字符
        var reg = /^([-+]?(([1-9]\d*\.?\d*)|(0\.\d*[1-9]))[^\d\.]*)$/;
        if (reg.test(this.props.value) && this.props.value !== prevProps.value) {
            var unit = this.getUnit();
            this.setState({ unit: unit });
        }
        if (this.props.unitOptions !== prevProps.unitOptions) {
            this.setState({ unitOptions: normalizeOptions(this.props.unitOptions) });
        }
    };
    NumberControl.prototype.inputRef = function (ref) {
        this.input = ref;
    };
    NumberControl.prototype.focus = function () {
        if (!this.input) {
            return;
        }
        this.input.focus();
    };
    NumberControl.prototype.render = function () {
        var _a;
        var _this = this;
        var _b;
        var _c = this.props, className = _c.className; _c.style; var ns = _c.classPrefix, value = _c.value, step = _c.step, precision = _c.precision, max = _c.max, min = _c.min, disabled = _c.disabled, placeholder = _c.placeholder, showSteps = _c.showSteps, borderMode = _c.borderMode, suffix = _c.suffix, prefix = _c.prefix, kilobitSeparator = _c.kilobitSeparator, unitOptions = _c.unitOptions, readOnly = _c.readOnly, keyboard = _c.keyboard, displayMode = _c.displayMode, big = _c.big, resetValue = _c.resetValue, clearValueOnEmpty = _c.clearValueOnEmpty, css = _c.css, themeCss = _c.themeCss, inputControlClassName = _c.inputControlClassName, id = _c.id, env = _c.env;
        var finalPrecision = this.filterNum(precision);
        var unit = (_b = this.state) === null || _b === void 0 ? void 0 : _b.unit;
        // 数据格式化
        var formatter = function (value) {
            // 增加千分分隔
            if (kilobitSeparator && value) {
                value = numberFormatter.format(value);
            }
            return (prefix ? prefix : '') + value + (suffix ? suffix : '');
        };
        // 将数字还原
        var parser = function (value) {
            if (value) {
                prefix && (value = value.replace(prefix, ''));
                suffix && (value = value.replace(suffix, ''));
                kilobitSeparator && (value = value.replace(/,/g, ''));
            }
            return value;
        };
        var finalValue = unit && value && typeof value === 'string'
            ? value.replace(unit, '')
            : value;
        return (React.createElement("div", { className: cx("".concat(ns, "NumberControl"), (_a = {},
                _a["".concat(ns, "NumberControl--withUnit")] = unitOptions,
                _a), className) },
            React.createElement(NumberInput, { inputControlClassName: inputControlClassName, inputRef: this.inputRef, value: finalValue, resetValue: resetValue, step: step, max: this.filterNum(max, big), min: this.filterNum(min, big), formatter: formatter, parser: parser, onChange: this.handleChange, disabled: disabled, placeholder: placeholder, precision: finalPrecision, showSteps: showSteps, borderMode: borderMode, readOnly: readOnly, onFocus: function () { return _this.dispatchEvent('focus'); }, onBlur: function () { return _this.dispatchEvent('blur'); }, keyboard: keyboard, displayMode: displayMode, big: big, clearValueOnEmpty: clearValueOnEmpty }),
            Array.isArray(unitOptions) && unitOptions.length !== 0 ? (unitOptions.length > 1 ? (React.createElement(Select, { value: unit, clearable: false, options: this.state.unitOptions || [], onChange: this.handleChangeUnit, className: "".concat(ns, "NumberControl-unit") })) : (React.createElement("div", { className: cx("".concat(ns, "NumberControl-unit"), " ".concat(ns, "NumberControl-single-unit"), "".concat(ns, "Select")) }, typeof unitOptions[0] === 'string'
                ? unitOptions[0]
                : unitOptions[0].label))) : null,
            React.createElement(CustomStyle, { config: {
                    themeCss: themeCss || css,
                    classNames: [
                        {
                            key: 'inputControlClassName',
                            value: inputControlClassName,
                            weights: {
                                active: {
                                    pre: "".concat(inputControlClassName, ".focused, ")
                                }
                            }
                        }
                    ],
                    id: id
                }, env: env })));
    };
    NumberControl.defaultProps = {
        step: 1,
        resetValue: '',
        clearValueOnEmpty: false
    };
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [String]),
        __metadata("design:returntype", Promise)
    ], NumberControl.prototype, "dispatchEvent", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], NumberControl.prototype, "inputRef", null);
    __decorate([
        supportStatic(),
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], NumberControl.prototype, "render", null);
    return NumberControl;
}(React.Component));
/** @class */ ((function (_super) {
    __extends(NumberControlRenderer, _super);
    function NumberControlRenderer() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    NumberControlRenderer.defaultProps = __assign({ validations: 'isNumeric' }, NumberControl.defaultProps);
    NumberControlRenderer = __decorate([
        FormItem({
            type: 'input-number'
        })
    ], NumberControlRenderer);
    return NumberControlRenderer;
})(NumberControl));

export { NumberControl as default };
