import { InternalDate } from '../../../lib/date/InternalDate.js';
import { InternalDateGetter } from '../../../lib/date/InternalDateGetter.js';
import { InternalDateTransformer } from '../../../lib/date/InternalDateTransformer.js';
import { InternalDateComponentType, InternalDateValidateCheck } from '../../../lib/date/types.js';
import { inputNumber } from './inputNumber.js';
var InternalDateMediator = /** @class */ (function () {
    function InternalDateMediator() {
        var _this = this;
        this.iDate = new InternalDate();
        this.update = function (props, locale) {
            var start = _this.iDate.getRangeStart();
            var min = start && start.toInternalString();
            var end = _this.iDate.getRangeEnd();
            var max = end && end.toInternalString();
            var order = locale.order, separator = locale.separator;
            _this.iDate.setOrder(order).setSeparator(separator);
            if (props.minDate !== min) {
                _this.iDate.setRangeStart(props.minDate
                    ? new InternalDate({
                        order: order,
                        separator: separator,
                        value: props.minDate,
                    })
                    : null);
            }
            if (props.maxDate !== max) {
                _this.iDate.setRangeEnd(props.maxDate
                    ? new InternalDate({
                        order: order,
                        separator: separator,
                        value: props.maxDate,
                    })
                    : null);
            }
            if (!props.value || props.value !== _this.iDate.toInternalString()) {
                _this.iDate.parseInternalValue(props.value);
            }
            return _this;
        };
        this.paste = function (pasted) {
            _this.iDate.parseValue(pasted).restore().cutOffExcess();
            return _this;
        };
        this.restore = function () {
            if (_this.iDate.isIncomplete()) {
                var restored = _this.iDate.clone().restore();
                if (!_this.iDate.isEqual(restored)) {
                    _this.iDate.duplicateOf(restored);
                }
                return true;
            }
            return false;
        };
        this.getFragments = function () {
            return _this.iDate.toFragments({
                withSeparator: true,
                withPad: true,
            });
        };
        this.deleteOneCharRight = function (type, inputMode) {
            var prev = _this.iDate.get(type);
            prev = String(inputMode ? prev : InternalDateTransformer.padDateComponent(type, prev));
            var next = prev.replace(/.$/, '') || null;
            _this.iDate.set(type, next);
        };
        this.isChangedLocale = function (locale) {
            return locale.order !== _this.iDate.getOrder() || locale.separator !== _this.iDate.getSeparator();
        };
        this.isNull = function (type) { return _this.iDate.get(type) === null; };
        this.isEmpty = function () { return _this.iDate.isEmpty(); };
        this.get = function (type) { return _this.iDate.get(type); };
        this.clear = function (type) { return _this.iDate.set(type, null); };
        this.validateString = function (value) {
            return InternalDateTransformer.parseValueToDate(value, _this.iDate.getOrder()) !== null;
        };
        this.getString = function () { return (_this.iDate.isEmpty() ? '' : _this.iDate.toString()); };
        this.getInternalString = function () { return (_this.iDate.isEmpty() ? '' : _this.iDate.toInternalString()); };
        this.getTypesOrder = function () {
            return _this.iDate.toFragments().map(function (_a) {
                var type = _a.type;
                return type;
            });
        };
        this.getLeftmostType = function () { return _this.getTypesOrder()[0]; };
        this.getRightmostType = function () { return _this.getTypesOrder()[2]; };
    }
    InternalDateMediator.prototype.inputKey = function (key, type, inputMode) {
        var prevValue = this.iDate.get(type);
        if (type === null) {
            var leftMostType = this.getLeftmostType();
            this.clear(leftMostType);
        }
        if (type !== InternalDateComponentType.Year) {
            this.iDate.cutOffExcess(type);
        }
        else {
            this.iDate.restore(type);
        }
        var maxValue = InternalDateGetter.getDefaultMax(type, this.iDate.getComponentsLikeNumber(), true);
        var _a = inputNumber(type, prevValue, key, inputMode, maxValue), nextValue = _a.nextValue, nextInputMode = _a.nextInputMode;
        this.iDate.set(type, nextValue);
        return { inputMode: nextInputMode, changed: nextValue !== prevValue };
    };
    InternalDateMediator.prototype.shiftDateComponent = function (type, step) {
        var calculatedType = type !== null && type !== void 0 ? type : this.getLeftmostType();
        var iDate = this.iDate.clone();
        var start = iDate.getRangeStart();
        var end = iDate.getRangeEnd();
        var isValidRange = iDate.validate({ checks: [InternalDateValidateCheck.Range] });
        if (!isValidRange) {
            // Удерживаем дату в заданном диапазоне
            if (start && InternalDateGetter.max([iDate, start]) === start) {
                iDate.duplicateOf(start);
            }
            else if (end && InternalDateGetter.min([iDate, end]) === end) {
                iDate.duplicateOf(end);
            }
        }
        else {
            var clone = iDate.clone().shift(calculatedType, step, { isRange: false, isLoop: true, isCutFeb: true });
            if (clone.validate({ checks: [InternalDateValidateCheck.Range] })) {
                iDate.duplicateOf(clone);
            }
        }
        var changed = !this.iDate.isEqualComponentDate(calculatedType, iDate);
        this.iDate = iDate;
        return changed;
    };
    InternalDateMediator.prototype.getShiftedType = function (type, step) {
        var typesOrder = this.getTypesOrder();
        var index = type === null ? 0 : typesOrder.indexOf(type);
        var nextIndex = index + step;
        // Если выделено всё поле, то в завимости от направления перемещения, выделям крайний компонент
        if (type === InternalDateComponentType.All) {
            return step < 0 ? typesOrder[0] : typesOrder[2];
        }
        // Если текущий компонент "год", и он не пуст, то при перемещении выделения "восстанавливаем" значение года
        if (type === InternalDateComponentType.Year && this.iDate.getYear() !== null) {
            this.iDate.restore(type);
        }
        var shiftedType = typesOrder[nextIndex];
        return typeof shiftedType === 'number' ? shiftedType : type;
    };
    return InternalDateMediator;
}());
export { InternalDateMediator };
//# sourceMappingURL=InternalDateMediator.js.map