var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import React from 'react';
import warning from 'warning';
import { getOwnerGlobalObject } from '../../lib/globalObject.js';
import { isNonNullable, isNullable, isElement } from '../../lib/utils.js';
import { Input } from '../Input/index.js';
import { CommonWrapper } from '../../internal/CommonWrapper/index.js';
import { rootNode } from '../../lib/rootNode/index.js';
import { createPropsGetter } from '../../lib/createPropsGetter.js';
import { isInstanceOf } from '../../lib/isInstanceOf.js';
import { scrollInputCaretIntoView } from '../../lib/scrollInputCaretIntoView.js';
import { FocusControlWrapper } from '../../internal/FocusControlWrapper/index.js';
import { MAX_SAFE_DIGITS } from './constants.js';
import { SelectionHelper } from './SelectionHelper.js';
import { CurrencyHelper } from './CurrencyHelper.js';
import { CurrencyInputHelper } from './CurrencyInputHelper.js';
import { CURRENCY_INPUT_ACTIONS, extractAction } from './CurrencyInputKeyboardActions.js';
export var CurrencyInputDataTids = {
    root: 'CurrencyInput__root',
};
/** Поле для денежных сумм. */
var CurrencyInput = /** @class */ (function (_super) {
    __extends(CurrencyInput, _super);
    function CurrencyInput() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.getProps = createPropsGetter(CurrencyInput_1.defaultProps);
        _this.state = __assign(__assign({}, _this.getState(_this.getProps().value, _this.getProps().fractionDigits, _this.getProps().hideTrailingZeros)), { focused: false });
        _this.tempSelectionForOnChange = SelectionHelper.fromPosition(0);
        _this.renderMain = function (props) {
            var fractionDigits = props.fractionDigits, signed = props.signed, onSubmit = props.onSubmit, integerDigits = props.integerDigits, hideTrailingZeros = props.hideTrailingZeros, rest = __rest(props, ["fractionDigits", "signed", "onSubmit", "integerDigits", "hideTrailingZeros"]);
            return (React.createElement(FocusControlWrapper, { onBlurWhenDisabled: _this.resetFocus },
                React.createElement(Input, __assign({ "data-tid": CurrencyInputDataTids.root }, rest, { align: _this.getProps().align, value: _this.state.formatted, onBlur: _this.handleBlur, onFocus: _this.handleFocus, onMouseUp: _this.handleMouseUp, onKeyDown: _this.handleKeyDown, onValueChange: _this.handleValueChange, onPaste: _this.handlePaste, onCopy: _this.handleCopy, onCut: _this.handleCut, "aria-label": _this.props['aria-label'], onMouseEnter: _this.props.onMouseEnter, onMouseLeave: _this.props.onMouseLeave, onMouseOver: _this.props.onMouseOver, ref: _this.refInput, placeholder: _this.state.focused ? '' : getPlaceholder(props) }))));
        };
        /** Программно устанавливает фокус на поле.
         * Появляется фокусная рамка, элемент получает клавиатурные события и воспринимается как текущий элемент для чтения скринридерами.
         * @public
         */
        _this.focus = function () {
            if (_this.input) {
                _this.input.focus();
            }
        };
        /** Программно снимает фокус с кнопки.
         * @public
         */
        _this.blur = function () {
            if (_this.input) {
                _this.input.blur();
            }
        };
        _this.handleMouseUp = function (event) {
            _this.setSelectionFromEvent(event);
        };
        _this.handleKeyDown = function (event) {
            var selection = _this.getSelection(event.target);
            _this.tempSelectionForOnChange = selection;
            if (_this.props.onKeyDown) {
                _this.props.onKeyDown(event);
                if (event.defaultPrevented) {
                    return;
                }
            }
            var action = extractAction(event);
            if (action === CURRENCY_INPUT_ACTIONS.Ignore) {
                return;
            }
            if (action !== CURRENCY_INPUT_ACTIONS.Unknown) {
                event.preventDefault();
            }
            switch (action) {
                case CURRENCY_INPUT_ACTIONS.Submit: {
                    if (_this.props.onSubmit) {
                        _this.props.onSubmit();
                    }
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.Backspace: {
                    _this.inputValue(CurrencyInputHelper.moveCursor(_this.state.formatted, selection, -1), selection.end, '');
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.Delete: {
                    _this.inputValue(selection.start, CurrencyInputHelper.moveCursor(_this.state.formatted, selection, +1), '');
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.MoveCursorLeft: {
                    _this.moveCursor(selection, -1);
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.MoveCursorRight: {
                    _this.moveCursor(selection, +1);
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.Home: {
                    _this.setState({ selection: SelectionHelper.fromPosition(0) });
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.End: {
                    var end = _this.state.formatted.length;
                    _this.setState({ selection: SelectionHelper.fromPosition(end) });
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.ExtendSelectionLeft: {
                    _this.extendSelection(selection, -1);
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.ExtendSelectionRight: {
                    _this.extendSelection(selection, +1);
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.FullSelection: {
                    _this.setState({
                        selection: SelectionHelper.forward(0, _this.state.formatted.length),
                    });
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.ExtendSelectionToStart: {
                    _this.setState({
                        selection: SelectionHelper.backward(0, selection.start),
                    });
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.ExtendSelectionToEnd: {
                    var inputEnd = _this.state.formatted.length;
                    _this.setState({
                        selection: SelectionHelper.forward(selection.start, inputEnd),
                    });
                    return;
                }
                case CURRENCY_INPUT_ACTIONS.Comma: {
                    _this.inputValue(selection.start, selection.end, ',');
                    return;
                }
            }
        };
        _this.scrollInput = function () {
            var _a;
            var node = (_a = _this.input) === null || _a === void 0 ? void 0 : _a.getNode();
            if (node) {
                scrollInputCaretIntoView(node, _this.state.selection);
            }
        };
        _this.getSelection = function (input) {
            var selection = getInputSelectionFromEvent(input);
            return {
                start: selection.start,
                end: selection.end,
                direction: _this.state.selection.direction,
            };
        };
        _this.moveCursor = function (selection, step) {
            var position = CurrencyInputHelper.moveCursor(_this.state.formatted, selection, step);
            _this.setState({ selection: SelectionHelper.fromPosition(position) });
        };
        _this.extendSelection = function (selection, step) {
            var extended = CurrencyInputHelper.extendSelection(_this.state.formatted, selection, step);
            _this.setState({ selection: extended });
        };
        _this.inputValue = function (start, end, value) {
            var result = CurrencyInputHelper.safeInsert(_this.state.formatted, start, end, value, {
                integerDigits: _this.props.integerDigits,
                fractionDigits: _this.getProps().fractionDigits,
                unsigned: !_this.props.signed,
            });
            if (result) {
                var formatted_1 = result.value;
                var selection = SelectionHelper.fromPosition(result.position);
                _this.setState({ formatted: formatted_1, selection: selection }, function () {
                    var parsedValue = CurrencyHelper.parse(formatted_1);
                    if (_this.props.value !== parsedValue) {
                        _this.props.onValueChange(parsedValue);
                    }
                });
                return true;
            }
            if (_this.input) {
                _this.input.blink();
            }
            return false;
        };
        _this.getOnChangeDelta = function (value) {
            var selection = _this.tempSelectionForOnChange;
            var oldValue = _this.state.formatted;
            if (selection.start !== selection.end) {
                return value.substring(selection.start, value.length - (oldValue.length - selection.end));
            }
            else if (value.length > oldValue.length) {
                return value.substr(selection.start, value.length - oldValue.length);
            }
            return null;
        };
        _this.handleValueChange = function (value) {
            var selection = _this.tempSelectionForOnChange;
            var delta = _this.getOnChangeDelta(value);
            if (isNonNullable(delta) && !_this.inputValue(selection.start, selection.end, delta)) {
                _this.setState({ selection: selection });
            }
        };
        _this.handlePaste = function (event) {
            var _a, _b;
            var data = event.clipboardData.getData('text');
            var selection = _this.getSelection(event.target);
            _this.inputValue(selection.start, selection.end, data);
            event.preventDefault();
            (_b = (_a = _this.props).onPaste) === null || _b === void 0 ? void 0 : _b.call(_a, event);
        };
        _this.handleCopy = function (event) {
            var selection = _this.getSelection(event.target);
            if (selection.start !== selection.end) {
                var substring = _this.state.formatted.substring(selection.start, selection.end);
                var data = CurrencyHelper.formatForClipboard(substring);
                event.clipboardData.setData('text', data);
            }
            event.preventDefault();
        };
        _this.handleCut = function (event) {
            var selection = _this.getSelection(event.target);
            if (selection.start !== selection.end) {
                var substring = _this.state.formatted.substring(selection.start, selection.end);
                var data = CurrencyHelper.formatForClipboard(substring);
                event.clipboardData.setData('text', data);
                _this.inputValue(selection.start, selection.end, '');
            }
            event.preventDefault();
        };
        _this.handleFocus = function (event) {
            var _a = event.target, selectionStart = _a.selectionStart, selectionEnd = _a.selectionEnd, selectionDirection = _a.selectionDirection;
            var valueLength = event.target.value.length;
            var selection = {
                start: selectionStart !== selectionEnd ? selectionStart || 0 : selectionStart || valueLength,
                end: selectionEnd !== selectionStart ? selectionEnd || 0 : selectionEnd || valueLength,
                direction: selectionDirection || 'none',
            };
            _this.setState({
                focused: true,
                selection: selection,
            });
            if (_this.props.onFocus) {
                _this.props.onFocus(event);
            }
        };
        _this.resetFocus = function () {
            var value = CurrencyHelper.parse(_this.state.formatted);
            _this.setState(__assign(__assign({}, _this.getState(value, _this.getProps().fractionDigits, _this.getProps().hideTrailingZeros)), { focused: false }));
        };
        _this.handleBlur = function (event) {
            var _a, _b;
            _this.resetFocus();
            (_b = (_a = _this.props).onBlur) === null || _b === void 0 ? void 0 : _b.call(_a, event);
        };
        _this.refInput = function (element) {
            _this.input = element;
        };
        return _this;
    }
    CurrencyInput_1 = CurrencyInput;
    CurrencyInput.prototype.validateProps = function (props) {
        warning(isNumeric(props.value) || isNullable(props.value), '[CurrencyInput]: Prop `value` is not a valid number. Received value is `' + props.value + '`.');
        warning((props.integerDigits || 0) + (props.fractionDigits || 0) <= MAX_SAFE_DIGITS, "[CurrencyInput]: Sum of 'integerDigits' and 'fractionDigits' exceeds ".concat(MAX_SAFE_DIGITS, ".") +
            "\nSee CurrencyInput documentation");
    };
    CurrencyInput.prototype.componentDidMount = function () {
        this.validateProps(this.getProps());
    };
    CurrencyInput.prototype.componentDidUpdate = function (prevProps, prevState) {
        var _a = this.getProps(), value = _a.value, fractionDigits = _a.fractionDigits, hideTrailingZeros = _a.hideTrailingZeros;
        this.validateProps(this.getProps());
        if ((isNumeric(value) && Number(value) !== CurrencyHelper.parse(prevState.formatted)) ||
            prevProps.fractionDigits !== fractionDigits) {
            this.setState(this.getState(value, fractionDigits, hideTrailingZeros));
        }
        if (isNonNullable(prevProps.value) && isNullable(value)) {
            this.setState({ formatted: '' });
        }
        if (this.state.focused && this.input) {
            var _b = this.state.selection, start = _b.start, end = _b.end;
            this.input.setSelectionRange(start, end);
        }
        if (prevState.selection !== this.state.selection) {
            this.scrollInput();
        }
    };
    CurrencyInput.prototype.render = function () {
        return (React.createElement(CommonWrapper, __assign({ rootNodeRef: this.setRootNode }, this.getProps()), this.renderMain));
    };
    CurrencyInput.prototype.getState = function (value, fractionDigits, hideTrailingZeros) {
        return {
            formatted: CurrencyHelper.format(value, { fractionDigits: fractionDigits, hideTrailingZeros: hideTrailingZeros }),
            selection: SelectionHelper.fromPosition(0),
        };
    };
    CurrencyInput.prototype.setSelectionFromEvent = function (event) {
        var selection = getInputSelectionFromEvent(event.target);
        var normilized = CurrencyInputHelper.normalizeSelection(this.state.formatted, selection);
        this.setState({ selection: normilized });
    };
    var CurrencyInput_1;
    CurrencyInput.__KONTUR_REACT_UI__ = 'CurrencyInput';
    CurrencyInput.displayName = 'CurrencyInput';
    CurrencyInput.defaultProps = {
        align: 'right',
        fractionDigits: 2,
        hideTrailingZeros: false,
        value: null,
        inputMode: 'decimal',
    };
    CurrencyInput = CurrencyInput_1 = __decorate([
        rootNode
    ], CurrencyInput);
    return CurrencyInput;
}(React.PureComponent));
export { CurrencyInput };
function getInputSelectionFromEvent(input) {
    var _a, _b;
    if (!isElement(input) || !isInstanceOf(input, getOwnerGlobalObject(input).HTMLInputElement)) {
        warning(false, 'input is not HTMLInputElement');
        return {
            start: 0,
            end: 0,
            direction: 'none',
        };
    }
    return {
        start: (_a = input.selectionStart) !== null && _a !== void 0 ? _a : 0,
        end: (_b = input.selectionEnd) !== null && _b !== void 0 ? _b : 0,
        direction: input.selectionDirection,
    };
}
function isNumeric(value) {
    return !isNaN(parseFloat(value)) && isFinite(value);
}
var getPlaceholder = function (props) {
    if (isNullable(props.placeholder)) {
        return CurrencyHelper.format(0, {
            fractionDigits: props.fractionDigits,
            hideTrailingZeros: props.hideTrailingZeros,
        });
    }
    return props.placeholder;
};
//# sourceMappingURL=CurrencyInput.js.map