import { __decorate, __extends } from "tslib";
import Component from 'vue-class-component';
import { Emit, Model, Prop, Ref, Watch } from 'vue-property-decorator';
import { InputLabel } from '../../mixins/input-label/input-label';
import { InputManagement } from '../../mixins/input-management/input-management';
import { InputState } from '../../mixins/input-state/input-state';
import { InputWidth } from '../../mixins/input-width/input-width';
import { MediaQueries } from '../../mixins/media-queries/media-queries';
import { MFocusTrap } from '../../mixins/window-focus-trap/window-focus-trap';
import { REGEX_CSS_NUMBER_VALUE } from '../../utils/props-validation/props-validation';
import uuid from '../../utils/uuid/uuid';
import { ModulVue } from '../../utils/vue/vue';
import { TYPEAHEAD_NAME } from '../component-names';
import { MIconButton } from '../icon-button/icon-button';
import { MBaseSelect } from '../select/base-select/base-select';
import { MSpinner } from '../spinner/spinner';
import { MTextfield } from '../textfield/textfield';
import { MValidationMessage } from '../validation-message/validation-message';
import WithRender from './typeahead.html?style=./typeahead.scss';
var MTypeahead = /** @class */ (function (_super) {
    __extends(MTypeahead, _super);
    function MTypeahead() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.validationMessageId = uuid.generate();
        _this.inputLabelId = uuid.generate();
        _this.isResultsPopupOpen = false;
        _this.textfieldValue = '';
        _this.initialFocusElement = null;
        _this.filteredResults = [];
        _this.throttleTimeoutActive = false;
        _this.throttleTimeout = 0;
        _this.firstSelection = false;
        return _this;
    }
    MTypeahead.prototype.emitInput = function (_event) { };
    MTypeahead.prototype.emitFilterResults = function () { };
    MTypeahead.prototype.emitClick = function () {
        if (this.as().isMqMaxS) {
            this.isResultsPopupOpen = true;
            this.initialFocusElement = this.refResearchInput;
        }
    };
    MTypeahead.prototype.onResultsChange = function () {
        this.onFilterResults();
    };
    MTypeahead.prototype.onValueChange = function (value) {
        if (this.value !== this.textfieldValue) {
            this.textfieldValue = value;
        }
    };
    MTypeahead.prototype.onFocusChanged = function (newValue) {
        if (!newValue) {
            return;
        }
        this.onFilterResults();
    };
    Object.defineProperty(MTypeahead.prototype, "hasResults", {
        get: function () {
            return this.results && this.results.length > 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "hasFilteredResults", {
        get: function () {
            return this.filteredResults && this.filteredResults.length > 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "hasTextfieldValue", {
        get: function () {
            return Boolean(this.textfieldValue) && this.textfieldValue.length > 0;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "resultsCouldBeDisplay", {
        get: function () {
            return this.hasFilteredResults && this.hasTextfieldValue && this.as().active && this.isResultsPopupOpen;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "hasSomeAResultSelected", {
        get: function () {
            var _this = this;
            return this.filteredResults.some(function (e, index) { return _this.isSelected(index); });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "sortedResult", {
        get: function () {
            if (this.resultsAreStringArray) {
                return this.results.sort(function (a, b) { return a.localeCompare(b); });
            }
            return this.results.sort(function (a, b) { return a.value.localeCompare(b.value); });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "resultsAreStringArray", {
        get: function () {
            if (this.results.length === 0) {
                return false;
            }
            return typeof this.results[0] === 'string';
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "isWaitingResults", {
        get: function () {
            return (this.waitingResults || this.throttleTimeoutActive)
                && this.textfieldValue.length > 0
                && !this.as().isWaiting;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MTypeahead.prototype, "focusManagement", {
        get: function () {
            return this.as().isMqMaxS;
        },
        enumerable: false,
        configurable: true
    });
    MTypeahead.prototype.onOpen = function () {
        this.firstSelection = true;
    };
    MTypeahead.prototype.onPortalAfterClose = function () {
        var _a, _b;
        var refInput = (_b = (_a = this.refMTextfield) === null || _a === void 0 ? void 0 : _a.refInput) !== null && _b !== void 0 ? _b : undefined;
        if (refInput && document.activeElement !== refInput) {
            this.as().focusInput();
        }
    };
    MTypeahead.prototype.openResultsPopup = function () {
        if (this.isResultsPopupOpen) {
            return;
        }
        this.isResultsPopupOpen = true;
    };
    MTypeahead.prototype.closeResultsPopup = function () {
        this.isResultsPopupOpen = false;
    };
    MTypeahead.prototype.onSelect = function (_option, index) {
        if (this.resultsAreStringArray) {
            this.textfieldValue = this.filteredResults[index];
        }
        else {
            this.textfieldValue = this.filteredResults[index].value;
        }
        this.emitInput(this.textfieldValue);
    };
    MTypeahead.prototype.isSelected = function (index) {
        return this.isResultsPopupOpen && this.textfieldValue.indexOf(this.resultsAreStringArray ?
            this.filteredResults[index] :
            this.filteredResults[index].value) > -1;
    };
    MTypeahead.prototype.focusOnResearchInput = function () {
        this.refResearchInput.focus();
    };
    MTypeahead.prototype.onFilterResults = function () {
        var _this = this;
        var filteredResults = [];
        if (this.filterResultsManually) {
            filteredResults = this.results;
        }
        else {
            if (this.resultsAreStringArray) {
                filteredResults = this.sortedResult
                    .filter(function (r) {
                    return _this.hasTextfieldValue
                        && r.toLowerCase().includes(_this.textfieldValue.toLowerCase());
                });
            }
            else {
                filteredResults = this.sortedResult
                    .filter(function (r) {
                    return _this.hasTextfieldValue
                        && r.value.toLowerCase().includes(_this.textfieldValue.toLowerCase());
                });
            }
        }
        this.filteredResults = filteredResults.slice(0, this.maxResults);
    };
    MTypeahead.prototype.getTextHighlight = function (item) {
        var regex = RegExp(this.textfieldValue, 'i');
        if (this.resultsAreStringArray) {
            return item.replace(regex, '<b>$&</b>');
        }
        return item.value.replace(regex, '<b>$&</b>');
    };
    MTypeahead.prototype.onInput = function (event) {
        if (this.value === event) {
            return;
        }
        this.textfieldValue = event;
        this.emitInput(event);
        if (this.throttleTimeoutActive) {
            clearTimeout(this.throttleTimeout);
            this.createThrottleTimeout();
        }
        else {
            if (this.as().isMqMaxS) {
                this.isResultsPopupOpen = true;
                this.initialFocusElement = this.refResearchInput;
            }
            else {
                this.isResultsPopupOpen = false;
            }
            this.throttleTimeoutActive = true;
            this.createThrottleTimeout();
        }
    };
    MTypeahead.prototype.onKeydownEnter = function ($event) {
        if (this.resultsCouldBeDisplay && this.as().isMqMinS) {
            this.refBaseSelect.selectFocusedItem($event);
        }
        this.refBaseSelect.closePopup();
    };
    MTypeahead.prototype.onKeydownDown = function ($event) {
        if (this.resultsCouldBeDisplay) {
            if (this.firstSelection) {
                if (this.refBaseSelect.focusedIndex === -1) {
                    this.refBaseSelect.focusedIndex = 0;
                }
                this.refBaseSelect.focusFirstSelected();
                this.onSelect({}, this.refBaseSelect.focusedIndex);
                this.firstSelection = false;
            }
            else {
                this.refBaseSelect.onKeydownDown($event);
            }
        }
    };
    MTypeahead.prototype.onKeydownUp = function ($event) {
        if (this.resultsCouldBeDisplay) {
            this.refBaseSelect.onKeydownUp($event);
        }
    };
    MTypeahead.prototype.onKeydownTab = function ($event) {
        if (this.resultsCouldBeDisplay) {
            this.refBaseSelect.onKeydownTab($event);
        }
    };
    MTypeahead.prototype.onKeydownEsc = function ($event) {
        this.refBaseSelect.onKeydownEsc($event);
    };
    MTypeahead.prototype.onKeydownHome = function ($event) {
        if (this.resultsCouldBeDisplay) {
            this.refBaseSelect.onKeydownHome($event);
        }
    };
    MTypeahead.prototype.onKeydownEnd = function ($event) {
        if (this.resultsCouldBeDisplay) {
            this.refBaseSelect.onKeydownEnd($event);
        }
    };
    MTypeahead.prototype.createThrottleTimeout = function () {
        var _this = this;
        if (this.throttle > 0) {
            this.throttleTimeout = window.setTimeout(function () {
                _this.throttleTimeoutActive = false;
                _this.updateResults();
            }, this.throttle);
        }
        else {
            this.throttleTimeoutActive = false;
            this.updateResults();
        }
    };
    MTypeahead.prototype.updateResults = function () {
        this.onFilterResults();
        if (!this.isResultsPopupOpen) {
            this.openResultsPopup();
        }
        this.refBaseSelect.focusedIndex = -1;
        this.emitFilterResults();
    };
    __decorate([
        Model('input'),
        Prop({
            required: true
        })
    ], MTypeahead.prototype, "value", void 0);
    __decorate([
        Prop()
    ], MTypeahead.prototype, "results", void 0);
    __decorate([
        Prop({ default: false })
    ], MTypeahead.prototype, "waitingResults", void 0);
    __decorate([
        Prop()
    ], MTypeahead.prototype, "filterResultsManually", void 0);
    __decorate([
        Prop({ default: 0 })
    ], MTypeahead.prototype, "throttle", void 0);
    __decorate([
        Prop({ default: 0 })
    ], MTypeahead.prototype, "maxLength", void 0);
    __decorate([
        Prop({ default: true })
    ], MTypeahead.prototype, "lengthOverflow", void 0);
    __decorate([
        Prop()
    ], MTypeahead.prototype, "characterCount", void 0);
    __decorate([
        Prop({ default: 0 })
    ], MTypeahead.prototype, "characterCountThreshold", void 0);
    __decorate([
        Prop({ default: 20 })
    ], MTypeahead.prototype, "maxResults", void 0);
    __decorate([
        Prop({ default: function () { return TYPEAHEAD_NAME + "-" + uuid.generate(); } })
    ], MTypeahead.prototype, "id", void 0);
    __decorate([
        Prop({
            validator: function (value) {
                return REGEX_CSS_NUMBER_VALUE.test(value);
            }
        })
    ], MTypeahead.prototype, "listMaxHeight", void 0);
    __decorate([
        Ref('mBaseSelect')
    ], MTypeahead.prototype, "refBaseSelect", void 0);
    __decorate([
        Ref('researchInput')
    ], MTypeahead.prototype, "refResearchInput", void 0);
    __decorate([
        Ref('mTextfield')
    ], MTypeahead.prototype, "refMTextfield", void 0);
    __decorate([
        Emit('input')
    ], MTypeahead.prototype, "emitInput", null);
    __decorate([
        Emit('filter-results')
    ], MTypeahead.prototype, "emitFilterResults", null);
    __decorate([
        Emit('click')
    ], MTypeahead.prototype, "emitClick", null);
    __decorate([
        Watch('results', { immediate: true })
    ], MTypeahead.prototype, "onResultsChange", null);
    __decorate([
        Watch('value', { immediate: true })
    ], MTypeahead.prototype, "onValueChange", null);
    __decorate([
        Watch('internalIsFocus')
    ], MTypeahead.prototype, "onFocusChanged", null);
    MTypeahead = __decorate([
        WithRender,
        Component({
            components: {
                MBaseSelect: MBaseSelect,
                MTextfield: MTextfield,
                MValidationMessage: MValidationMessage,
                MIconButton: MIconButton,
                MSpinner: MSpinner
            },
            mixins: [
                InputLabel,
                InputState,
                InputWidth,
                InputManagement,
                MediaQueries,
                MFocusTrap
            ]
        })
    ], MTypeahead);
    return MTypeahead;
}(ModulVue));
export { MTypeahead };
var TypeaheadPlugin = {
    install: function (v, options) {
        v.component(TYPEAHEAD_NAME, MTypeahead);
    }
};
export default TypeaheadPlugin;
//# sourceMappingURL=typeahead.js.map