var _a;
import { __awaiter, __decorate, __extends, __generator } from "tslib";
import { Component, Emit, Prop, Ref, Watch } from 'vue-property-decorator';
import { POPUP_NAME as DIRECTIVE_POPUP_NAME } from '../../../directives/directive-names';
import { MPopupDirective } from '../../../directives/popup/popup';
import { InputWidth } from '../../../mixins/input-width/input-width';
import { MediaQueries } from '../../../mixins/media-queries/media-queries';
import { REGEX_CSS_NUMBER_VALUE } from '../../../utils/props-validation/props-validation';
import uuid from '../../../utils/uuid/uuid';
import { ModulVue } from '../../../utils/vue/vue';
import { MPopup } from '../../popup/popup';
import { MSelectItem } from '../../select/select-item/select-item';
import WithRender from './base-select.html';
import './base-select.scss';
var BASE_SELECT_STYLE_TRANSITION = 'max-height 0.3s ease';
var MBaseSelect = /** @class */ (function (_super) {
    __extends(MBaseSelect, _super);
    function MBaseSelect() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.popupId = "popup-" + uuid.generate();
        _this.listboxId = "listbox-" + uuid.generate();
        _this.focusedIndex = -1;
        _this.internalOpen = false;
        _this.letterTap = '';
        _this.timerLetterTap = 0;
        _this.timerLetterTapActive = false;
        return _this;
    }
    MBaseSelect.prototype.emitUpdateOpen = function (_open) { };
    MBaseSelect.prototype.emitClickOnItem = function (_event) { };
    MBaseSelect.prototype.emitOpen = function () {
        return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) {
            return [2 /*return*/];
        }); });
    };
    MBaseSelect.prototype.emitClose = function () { };
    MBaseSelect.prototype.emitPortalAfterClose = function () {
        this.focusedIndex = -1;
    };
    MBaseSelect.prototype.emitSelectItem = function (option, index, event) {
        this.$emit('select-item', option, index, event);
    };
    MBaseSelect.prototype.onOpenChange = function (open) {
        if (open === this.internalOpen) {
            return;
        }
        this.internalOpen = open;
        this.focusFirstSelected();
    };
    Object.defineProperty(MBaseSelect.prototype, "popupOpen", {
        get: function () {
            return this.internalOpen;
        },
        set: function (open) {
            this.internalOpen = open;
            this.emitUpdateOpen(open);
            this.focusFirstSelected();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseSelect.prototype, "listMaxHeightProps", {
        get: function () {
            if (this.as().isMqMinS) {
                return this.listMaxHeight;
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseSelect.prototype, "itemIds", {
        get: function () {
            var _a, _b;
            return (_b = (_a = this.items) === null || _a === void 0 ? void 0 : _a.map(function () { return uuid.generate(); })) !== null && _b !== void 0 ? _b : [];
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseSelect.prototype, "ariaActivedescendantId", {
        get: function () {
            if (this.focusedIndex < 0) {
                return '';
            }
            return this.itemIds[this.focusedIndex];
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseSelect.prototype, "itemsAreStringArray", {
        get: function () {
            if (!this.items || this.items.length === 0) {
                return false;
            }
            return typeof this.items[0] === 'string';
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MBaseSelect.prototype, "focusValue", {
        get: function () {
            if (this.focusedIndex < 0) {
                return '';
            }
            return this.itemsAreStringArray
                ? this.items[this.focusedIndex]
                : this.items[this.focusedIndex].value;
        },
        enumerable: false,
        configurable: true
    });
    MBaseSelect.prototype.getItemProps = function (item, index) {
        return {
            id: this.itemIds[index],
            value: this.itemsAreStringArray ? item : item.value,
            focused: index === this.focusedIndex,
            selected: this.isSelected(item),
            multiselect: this.multiselect,
            disabled: this.itemsAreStringArray ? undefined : item.disabled,
            hideRadioButtonMobile: this.hideRadioButtonMobile || this.itemsAreStringArray ? false : item.hideRadioButtonMobile
        };
    };
    MBaseSelect.prototype.getItemHandlers = function (item, index) {
        var _this = this;
        return {
            click: function (event) {
                _this.focusedIndex = index;
                _this.emitSelectItem(item, index, event);
                _this.emitClickOnItem(event);
                if (!_this.multiselect) {
                    _this.closePopup();
                }
            }
        };
    };
    MBaseSelect.prototype.togglePopup = function () {
        if (this.active) {
            this.popupOpen = !this.popupOpen;
        }
    };
    MBaseSelect.prototype.closePopup = function () {
        this.popupOpen = false;
    };
    MBaseSelect.prototype.selectFocusedItem = function ($event) {
        this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, $event);
    };
    MBaseSelect.prototype.focusFirstSelected = function () {
        this.setCurrentFocusedIndex();
        if (!this.popupOpen || this.focusedIndex === -1) {
            return;
        }
        if (this.items && this.items.length > 0 && this.items[this.focusedIndex].disabled) {
            this.focusNextItem();
            return;
        }
        this.scrollToFocused();
    };
    MBaseSelect.prototype.focusNextItem = function () {
        if (this.focusedIndex >= this.items.length - 1) {
            return;
        }
        if (this.itemsAreStringArray) {
            this.focusedIndex++;
        }
        else {
            var items = this.items;
            if (this.focusedIndex + 1 === items.length - 1 && items[items.length - 1].disabled) {
                return;
            }
            else {
                this.focusedIndex++;
                if (items[this.focusedIndex].disabled) {
                    this.focusNextItem();
                }
            }
        }
        this.scrollToFocused();
    };
    MBaseSelect.prototype.focusPreviousItem = function () {
        if (this.focusedIndex <= 0) {
            return;
        }
        if (this.itemsAreStringArray) {
            this.focusedIndex--;
        }
        else {
            var items = this.items;
            if (this.focusedIndex - 1 === 0 && items[0].disabled) {
                return;
            }
            else {
                this.focusedIndex--;
                if (items[this.focusedIndex].disabled) {
                    this.focusPreviousItem();
                }
            }
        }
        this.scrollToFocused();
    };
    MBaseSelect.prototype.update = function () {
        this.refPopup.update();
    };
    MBaseSelect.prototype.transitionEnter = function (el, done) {
        var _this = this;
        this.$nextTick(function () {
            if (_this.as().isMqMinS) {
                var height_1 = el.clientHeight;
                el.style.transition = BASE_SELECT_STYLE_TRANSITION;
                el.style.overflowY = 'hidden';
                el.style.width = _this.$el.clientWidth + 'px';
                if (_this.listMinWidth) {
                    el.style.minWidth = _this.listMinWidth;
                }
                if (_this.enableAnimation) {
                    el.style.maxHeight = '0';
                    requestAnimationFrame(function () {
                        el.style.maxHeight = height_1 + 'px';
                        done();
                    });
                }
                else {
                    done();
                }
            }
            else {
                done();
            }
        });
    };
    MBaseSelect.prototype.transitionLeave = function (el, done) {
        var _this = this;
        if (this.enableAnimation) {
            this.$nextTick(function () {
                if (_this.as().isMqMinS) {
                    var height = el.clientHeight;
                    el.style.maxHeight = height + 'px';
                    el.style.maxHeight = '0';
                    setTimeout(function () {
                        el.style.maxHeight = 'none';
                        done();
                    }, 300);
                }
                else {
                    done();
                }
            });
        }
        else {
            done();
        }
    };
    // keyboard navigation of a drowdown
    // tab or esc : close the popup
    // up and down : change the focused option
    // enter : select the focused option and close popup
    // space : open the popup
    MBaseSelect.prototype.onKeydownDown = function ($event) {
        if (!this.popupOpen) {
            this.togglePopup();
        }
        this.focusNextItem();
        if (!this.multiselect && this.items) {
            this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, $event);
        }
    };
    MBaseSelect.prototype.onKeydownUp = function ($event) {
        if (!this.popupOpen) {
            return;
        }
        this.focusPreviousItem();
        if (!this.multiselect && this.items) {
            this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, $event);
        }
    };
    MBaseSelect.prototype.onKeydownSpace = function ($event) {
        if (this.focusedIndex > -1) {
            this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, $event);
            this.closePopup();
        }
        else {
            this.togglePopup();
        }
    };
    MBaseSelect.prototype.onKeydownTab = function ($event) {
        this.closePopup();
    };
    MBaseSelect.prototype.onKeydownEsc = function ($event) {
        this.closePopup();
    };
    MBaseSelect.prototype.onKeydownEnter = function ($event) {
        if (this.focusedIndex > -1) {
            this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, $event);
            this.closePopup();
        }
        else {
            this.togglePopup();
        }
    };
    MBaseSelect.prototype.onKeydownHome = function ($event) {
        if (!this.popupOpen) {
            return;
        }
        this.focusedIndex = 0;
        if (!this.itemsAreStringArray
            && this.items.length > 0
            && this.items[this.focusedIndex].disabled) {
            this.focusNextItem();
        }
        else {
            this.scrollToFocused();
        }
        if (!this.multiselect) {
            this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, $event);
        }
    };
    MBaseSelect.prototype.onKeydownEnd = function ($event) {
        if (!this.popupOpen) {
            return;
        }
        this.focusedIndex = this.items.length - 1;
        if (!this.itemsAreStringArray
            && this.items.length > 0
            && this.items[this.focusedIndex].disabled) {
            this.focusPreviousItem();
        }
        else {
            this.scrollToFocused();
        }
        if (!this.multiselect) {
            this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, $event);
        }
    };
    MBaseSelect.prototype.onKeydownLetter = function ($event) {
        if (/^[a-z0-9]$/i.test($event.key)) {
            this.findFirstItemWithLetter($event.key, $event);
        }
    };
    MBaseSelect.prototype.scrollToFocused = function () {
        return __awaiter(this, void 0, void 0, function () {
            var sidebarBody, refUl, container, element, top_1, bottom, viewRectTop, viewRectBottom;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (this.focusedIndex < 0) {
                            return [2 /*return*/];
                        }
                        return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        sidebarBody = this.as().isMqMaxS ?
                            document.querySelector("#" + this.popupId + " .m-sidebar__body")
                            : undefined;
                        refUl = this.refItems;
                        container = sidebarBody || refUl;
                        if (container) {
                            element = refUl.children[this.focusedIndex];
                            if (element) {
                                top_1 = element.offsetTop;
                                bottom = element.offsetTop + element.offsetHeight;
                                viewRectTop = container.scrollTop;
                                viewRectBottom = viewRectTop + container.clientHeight;
                                if (top_1 < viewRectTop) {
                                    container.scrollTop = top_1;
                                }
                                else if (bottom > viewRectBottom) {
                                    container.scrollTop = bottom - container.clientHeight;
                                }
                            }
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    MBaseSelect.prototype.createTimeoutLetterTap = function () {
        var _this = this;
        this.timerLetterTap = setTimeout(function () {
            _this.timerLetterTapActive = false;
            _this.letterTap = '';
        }, 400);
    };
    MBaseSelect.prototype.findFirstItemWithLetter = function (key, event) {
        var _this = this;
        if (this.timerLetterTapActive) {
            clearTimeout(this.timerLetterTap);
            this.createTimeoutLetterTap();
        }
        else {
            this.timerLetterTapActive = true;
            this.createTimeoutLetterTap();
        }
        this.letterTap += key;
        if (this.itemsAreStringArray) {
            var items = this.items;
            var findItem = items.find(function (items) { return items.toUpperCase().startsWith(_this.letterTap.toUpperCase()); });
            if (findItem) {
                var index = findItem ? items.indexOf(findItem) : -1;
                this.focusedIndex = index;
                this.scrollToFocused();
                if (!this.multiselect) {
                    this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, event);
                }
            }
        }
        else if (this.items.length > 0) {
            var items = this.items;
            var findItem = items.find(function (items) { return items.value.toUpperCase().startsWith(_this.letterTap.toUpperCase()); });
            if (findItem) {
                var index = findItem ? items.indexOf(findItem) : -1;
                if (items[index].disabled) {
                    return;
                }
                this.focusedIndex = index;
                this.scrollToFocused();
                if (!this.multiselect) {
                    this.emitSelectItem(this.items[this.focusedIndex], this.focusedIndex, event);
                }
            }
        }
    };
    MBaseSelect.prototype.isSelected = function (item) {
        if (this.selectedItems && this.selectedItems.length > 0) {
            if (this.itemsAreStringArray) {
                return this.selectedItems.some(function (i) { return i === item; });
            }
            item = item;
            return item.disabled ? false : this.selectedItems.some(function (i) { return i === item; });
        }
        return false;
    };
    MBaseSelect.prototype.setCurrentFocusedIndex = function () {
        var _this = this;
        if (!(this.items && this.items.length > 0 && this.selectedItems && this.selectedItems.length > 0 && this.popupOpen)) {
            return;
        }
        if (this.itemsAreStringArray) {
            this.focusedIndex = this.items.indexOf(this.selectedItems[0]);
            return;
        }
        var items = this.items;
        var findSelectedItem = items.find(function (items) { return items.value === _this.selectedItems[0]; });
        this.focusedIndex = findSelectedItem ? items.indexOf(findSelectedItem) : 0;
    };
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "items", void 0);
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "selectedItems", void 0);
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "multiselect", void 0);
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "active", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "open", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "hideRadioButtonMobile", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "sidebarFullHeight", void 0);
    __decorate([
        Prop({ default: true })
    ], MBaseSelect.prototype, "enableAnimation", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "virtualScroll", void 0);
    __decorate([
        Prop({
            validator: function (value) {
                return REGEX_CSS_NUMBER_VALUE.test(value);
            }
        })
    ], MBaseSelect.prototype, "listMinWidth", void 0);
    __decorate([
        Prop({
            validator: function (value) {
                return REGEX_CSS_NUMBER_VALUE.test(value);
            }
        })
    ], MBaseSelect.prototype, "listMaxHeight", void 0);
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "listboxAriaLabelledby", void 0);
    __decorate([
        Ref('items')
    ], MBaseSelect.prototype, "refItems", void 0);
    __decorate([
        Ref('popup')
    ], MBaseSelect.prototype, "refPopup", void 0);
    __decorate([
        Emit('update:open')
    ], MBaseSelect.prototype, "emitUpdateOpen", null);
    __decorate([
        Emit('click-on-item')
    ], MBaseSelect.prototype, "emitClickOnItem", null);
    __decorate([
        Emit('open')
    ], MBaseSelect.prototype, "emitOpen", null);
    __decorate([
        Emit('close')
    ], MBaseSelect.prototype, "emitClose", null);
    __decorate([
        Emit('portal-after-close')
    ], MBaseSelect.prototype, "emitPortalAfterClose", null);
    __decorate([
        Watch('open', { immediate: true })
    ], MBaseSelect.prototype, "onOpenChange", null);
    MBaseSelect = __decorate([
        WithRender,
        Component({
            components: {
                MSelectItem: MSelectItem,
                MPopup: MPopup
            },
            directives: (_a = {},
                _a[DIRECTIVE_POPUP_NAME] = MPopupDirective,
                _a),
            mixins: [InputWidth, MediaQueries]
        })
    ], MBaseSelect);
    return MBaseSelect;
}(ModulVue));
export { MBaseSelect };
//# sourceMappingURL=base-select.js.map