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 __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;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import React, { useEffect, useImperativeHandle, useRef } from 'react';
import { IMaskInput } from '@skbkontur/react-imask';
import { forwardRefAndName } from '../../lib/forwardRefAndName.js';
import { isKeyArrow, isKeyArrowHorizontal, isKeyArrowLeft, isKeyArrowUp, isKeyEnd, isKeyHome, isModShift, isShortcutJumpCaret, isShortcutSelectAll, someKeys, } from '../../lib/events/keyboard/identifiers.js';
import { MouseDrag } from '../../lib/events/MouseDrag.js';
import { scrollInputCaretIntoView } from '../../lib/scrollInputCaretIntoView.js';
export var FixedIMaskInput = forwardRefAndName('FixedIMaskInput', function FixedIMaskInput(props, ref) {
    var inputRef = props.inputRef, restProps = __rest(props, ["inputRef"]);
    var imaskRef = useRef(null);
    var focused = useRef(false);
    useEffect(function () {
        var _a;
        if ((_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.element) {
            fillTypedValue();
            var mouseDrag_1 = MouseDrag.listen(imaskRef.current.element).onMouseDragEnd(function (e) {
                var _a, _b;
                var direction = 'none';
                if (mouseDrag_1.mouseDragStartEvent &&
                    ((_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.element.selectionStart) !== ((_b = imaskRef.current) === null || _b === void 0 ? void 0 : _b.element.selectionEnd)) {
                    direction = mouseDrag_1.mouseDragStartEvent.pageX > e.pageX ? 'backward' : 'forward';
                }
                var _c = getSelection(), start = _c[0], end = _c[1];
                setSelection(start, end, direction);
                scrollCaretIntoView();
            });
        }
    }, []);
    useImperativeHandle(ref, function () { return imaskRef.current; }, [
        imaskRef.current,
    ]);
    return (React.createElement(IMaskInput, __assign({}, restProps, { ref: imaskRef, inputRef: inputRef, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, onMouseUp: handleMouseUp, onAccept: handleAccept, onInput: handleInput })));
    function getTypedValue() {
        var _a;
        var _b = ((_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.maskRef.masked) || {}, _c = _b._value, _value = _c === void 0 ? '' : _c, _d = _b.displayValue, displayValue = _d === void 0 ? '' : _d;
        var end = getMaxCaretPosition();
        var value = _value !== '' || focused.current === true ? displayValue : '';
        return value.slice(0, end);
    }
    function fillTypedValue() {
        var _a, _b, _c;
        (_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.element.setAttribute('data-typed-value', getTypedValue());
        (_b = imaskRef.current) === null || _b === void 0 ? void 0 : _b.element.setAttribute('data-unmasked-value', (_c = imaskRef.current) === null || _c === void 0 ? void 0 : _c.maskRef.unmaskedValue);
    }
    function getMaxCaretPosition() {
        var maskChars = [];
        if (imaskRef.current) {
            maskChars.push(imaskRef.current.maskRef.masked.placeholderChar);
            if (imaskRef.current.maskRef.masked.blocks) {
                Object.values(imaskRef.current.maskRef.masked.blocks).forEach(function (_a) {
                    var placeholderChar = _a.placeholderChar;
                    return placeholderChar && maskChars.push(placeholderChar);
                });
            }
            return imaskRef.current.element.value.split(new RegExp(maskChars.join('|')))[0].length;
        }
        return Infinity;
    }
    function normalizeSelection() {
        var _a = getSelection(), start = _a[0], end = _a[1];
        var max = getMaxCaretPosition();
        if (end > max) {
            setSelection(start, max);
        }
    }
    function getNormalizedRange(calc) {
        return typeof calc === 'number' ? Math.min(getMaxCaretPosition(), Math.max(0, calc)) : 0;
    }
    function getSelection() {
        if (imaskRef.current) {
            return [
                imaskRef.current.element.selectionStart || 0,
                imaskRef.current.element.selectionEnd || 0,
                imaskRef.current.element.selectionDirection || 'none',
            ];
        }
        return [0, 0, 'none'];
    }
    function setSelection() {
        var _a;
        var _b = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            _b[_i] = arguments[_i];
        }
        var start = _b[0], end = _b[1], direction = _b[2];
        (_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.element.setSelectionRange(getNormalizedRange(start), getNormalizedRange(end), direction || 'none');
    }
    function scrollCaretIntoView() {
        var _a;
        var element = (_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.element;
        if (element) {
            scrollInputCaretIntoView(element);
        }
    }
    function jumpCaret(prev, headDirection) {
        var _a, _b;
        var word = /а-яa-z0-9_/.valueOf();
        var wordRegExp = new RegExp("([".concat(word, "])+[\\s]*|([^").concat(word, "])+"), 'gi');
        var next = headDirection === 'right' ? prev : 0;
        (_b = (_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.element.value.match(wordRegExp)) === null || _b === void 0 ? void 0 : _b.reduce(function (s, a) {
            var pos = a.length + (s.slice(-1)[0] || 0);
            if (headDirection === 'right' && next === prev && next < pos) {
                next = getNormalizedRange(pos);
            }
            else if (headDirection === 'left' && prev > pos) {
                next = getNormalizedRange(pos);
            }
            return __spreadArray(__spreadArray([], s, true), [pos], false);
        }, []);
        return next;
    }
    /**
     * Вычислят положение каретки при управлении клавишами
     * @param e
     */
    function calcSelection(e) {
        var _a = getSelection(), start = _a[0], end = _a[1], direction = _a[2];
        var isSelectionMode = isModShift()(e);
        var tail = start !== end && direction === 'backward' ? end : start;
        var head = start !== end && direction === 'backward' ? start : end;
        var headDirection = someKeys(isKeyArrowLeft, isKeyArrowUp, isKeyHome)(e) ? 'left' : 'right';
        var step = isKeyArrowHorizontal(e) ? 1 : Infinity;
        var increment = headDirection === 'left' ? -step : step;
        if (isShortcutJumpCaret(e)) {
            head = jumpCaret(head, headDirection);
        }
        else if (head !== tail && !isSelectionMode && isKeyArrowHorizontal(e)) {
            head = headDirection === 'right' ? Math.max(tail, head) : Math.min(tail, head);
        }
        else {
            head = head + increment;
        }
        if (isSelectionMode) {
            var start_1 = Math.min(tail, head);
            var end_1 = Math.max(tail, head);
            return [getNormalizedRange(start_1), getNormalizedRange(end_1), end_1 === head ? 'forward' : 'backward'];
        }
        tail = head;
        return [getNormalizedRange(tail), getNormalizedRange(head), 'none'];
    }
    function handleMouseUp(e) {
        var _a;
        normalizeSelection();
        (_a = props.onMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, e);
    }
    function handleFocus(e) {
        var _a;
        focused.current = true;
        fillTypedValue();
        setTimeout(normalizeSelection);
        (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
    }
    function handleBlur(e) {
        var _a;
        focused.current = false;
        fillTypedValue();
        (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
    }
    function handleAccept() {
        var _a;
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        fillTypedValue();
        (_a = props.onAccept) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spreadArray([props], args, false));
    }
    function handleInput(e) {
        var _a, _b, _c;
        var maskRef = (_a = imaskRef.current) === null || _a === void 0 ? void 0 : _a.maskRef;
        if (maskRef && maskRef.rawInputValue === '') {
            // в случае, когда пользователь стер все из инпута, очищаем value полностью
            // иначе в value остаются символы маски
            (_b = props.onAccept) === null || _b === void 0 ? void 0 : _b.call(props, '', maskRef, e.nativeEvent);
        }
        (_c = props.onInput) === null || _c === void 0 ? void 0 : _c.call(props, e);
    }
    function handleKeyDown(e) {
        var _a;
        var nearest = getMaxCaretPosition();
        if (isShortcutSelectAll(e)) {
            e.preventDefault();
            setSelection(0, nearest);
            scrollCaretIntoView();
        }
        else if (isKeyArrow(e) || isKeyEnd(e) || isKeyHome(e)) {
            e.preventDefault();
            var _b = calcSelection(e), start = _b[0], end = _b[1], direction = _b[2];
            setSelection(start, end, direction);
            scrollCaretIntoView();
        }
        (_a = props.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(props, e);
    }
});
//# sourceMappingURL=FixedIMaskInput.js.map