var _form, _validator, _subscription, _customValidator, _filterValue, _getSelected, _updateValidator, _setSelectedItems, _setFilterItems, _setSize;
import { __awaiter, __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';
import { FormControl, NgForm, Validators } from '@angular/forms';
import { ZuiB, ZuiFR, ZuiO } from '@material-zui/core';
import * as $ from 'jquery';
import { Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { DEFAULT_DELAY, NO_DATA, REQUIRED } from '../constants';
import { MAX_WIDTH, MIN_WIDTH } from './data';
export class ZuiSelectComponent {
    constructor() {
        /** default "200px", eg: "300px", "400em", "500rem" */
        this.width = '200px';
        this.items = [];
        this.delay = 0;
        this.noDataText = NO_DATA;
        this.name = ZuiFR.datatype.uuid();
        this.panelWidth = '';
        this.panelHeight = '300px';
        this.tooltipPosition = 'above';
        _form.set(this, void 0);
        _validator.set(this, void 0);
        this.fullWidth = false;
        this.disabledValidateVal = false;
        this.validatorMessageDefault = { required: REQUIRED };
        this.validatorMessageVal = this.validatorMessageDefault;
        this.modelChange = new EventEmitter();
        _subscription.set(this, new Subscription());
        this.formControl = new FormControl();
        this.inputFormControl = new FormControl();
        this.loading = false;
        this.searchTerm = '';
        _customValidator.set(this, () => (c) => __awaiter(this, void 0, void 0, function* () {
            const value = c === null || c === void 0 ? void 0 : c.value;
            __classPrivateFieldGet(this, _setSelectedItems).call(this, this.filteredItems, value);
            const validator = __classPrivateFieldGet(this, _validator).call(this, value, __classPrivateFieldGet(this, _getSelected).call(this));
            let validatorMsg = null;
            let validatorError = !!validator;
            if (typeof validator === 'string') {
                validatorMsg = validator;
            }
            else if (typeof validator === 'boolean') {
                validatorError = !validator;
            }
            else if (validator instanceof Promise) {
                const resultValidator = yield validator;
                if (typeof resultValidator === 'string') {
                    validatorMsg = resultValidator;
                }
                else if (typeof resultValidator === 'boolean') {
                    validatorError = !resultValidator;
                }
            }
            return validatorError ? { validatorError, validatorMsg } : null;
        }));
        _filterValue.set(this, (items) => (searchTerm) => {
            const searchText = searchTerm.toLowerCase();
            const filteredItems = this.caseSensitiveVal
                ? items.filter(item => item[this.displayField].includes(searchTerm))
                : items.filter(item => item[this.displayField].toLowerCase().includes(searchText));
            const filteredValues = filteredItems.map(item => item[this.valueField]);
            const selectedItems = this.selectedItems.filter(item => !filteredValues.includes(item[this.valueField]));
            return [...filteredItems, ...selectedItems];
        });
        _getSelected.set(this, () => { var _a; return (this.multipleVal ? this.selectedItems : (_a = this.selectedItems) === null || _a === void 0 ? void 0 : _a[0]); });
        _updateValidator.set(this, () => {
            this.formControl.clearValidators();
            const validators = [];
            if (this.required)
                validators.push(Validators.required);
            this.formControl.setValidators(validators);
            this.formControl.clearAsyncValidators();
            const asyncValidators = [];
            if (__classPrivateFieldGet(this, _validator))
                asyncValidators.push(__classPrivateFieldGet(this, _customValidator).call(this));
            this.formControl.setAsyncValidators(asyncValidators);
            this.formControl.updateValueAndValidity();
        });
        _setSelectedItems.set(this, (filteredItems, value) => {
            this.selectedItems = this.multipleVal ? filteredItems.filter(item => value === null || value === void 0 ? void 0 : value.includes(item[this.valueField])) : filteredItems.find(item => item[this.valueField] === value);
            if (this.multipleVal) {
                this.selectedItems = filteredItems.filter(item => value === null || value === void 0 ? void 0 : value.includes(item[this.valueField]));
            }
            else {
                const selectedValue = filteredItems.find(item => item[this.valueField] === value);
                this.selectedItems = selectedValue ? [selectedValue] : [];
            }
        });
        _setFilterItems.set(this, () => __awaiter(this, void 0, void 0, function* () {
            var _a;
            try {
                if (Array.isArray(this.items)) {
                    this.filteredItems = __classPrivateFieldGet(this, _filterValue).call(this, this.items)(this.searchTerm);
                }
                else if (typeof this.items === 'function') {
                    const items = yield this.items(this.searchTerm);
                    this.filteredItems = __classPrivateFieldGet(this, _filterValue).call(this, items)(this.searchTerm);
                }
            }
            catch (_b) {
                this.filteredItems = (_a = this.selectedItems) !== null && _a !== void 0 ? _a : [];
            }
        }));
        _setSize.set(this, () => {
            if (this.panelWidth) {
                $('body').css('--zs_dc7d3b11_min-width', this.panelWidth);
                $('body').css('--zs_dc7d3b11_max-width', this.panelWidth);
            }
            else {
                $('body').css('--zs_dc7d3b11_min-width', MIN_WIDTH);
                $('body').css('--zs_dc7d3b11_max-width', MAX_WIDTH);
            }
            if (this.panelHeight)
                $('body').css('--zs_dc7d3b11_height', this.panelHeight);
        });
        this.clear = (event) => {
            event === null || event === void 0 ? void 0 : event.stopPropagation();
            if (this.existValue) {
                this.formControl.reset();
                this.formControl.markAsTouched();
            }
        };
        this.clearText = (event) => {
            event === null || event === void 0 ? void 0 : event.stopPropagation();
            if (this.existInputValue)
                this.inputFormControl.setValue('');
        };
        this.mouseenter = (_) => __classPrivateFieldGet(this, _setSize).call(this);
    }
    set model(values) {
        this.formControl.setValue(values);
    }
    set form(val) {
        if (val) {
            if (val instanceof NgForm) {
                __classPrivateFieldSet(this, _form, val.form);
            }
            else {
                __classPrivateFieldSet(this, _form, val);
            }
        }
    }
    set validator(validator) {
        __classPrivateFieldSet(this, _validator, validator);
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set multiple(val) {
        this.multipleVal = ZuiB.toBool(val);
    }
    set validateFirst(val) {
        this.validateFirstVal = ZuiB.toBool(val);
    }
    set disabled(val) {
        this.disabledVal = ZuiB.toBool(val);
    }
    set fullWidthVal(val) {
        this.fullWidth = ZuiB.toBool(val);
    }
    set wrap(val) {
        this.wrapVal = ZuiB.toBool(val);
    }
    set filter(val) {
        this.filterVal = ZuiB.toBool(val);
    }
    set caseSensitive(val) {
        this.caseSensitiveVal = ZuiB.toBool(val);
    }
    set disabledValidate(val) {
        this.disabledValidateVal = ZuiB.toBool(val);
    }
    ngOnInit() {
        __classPrivateFieldGet(this, _subscription).add(this.inputFormControl.valueChanges.pipe(debounceTime(this.delay), distinctUntilChanged()).subscribe((searchTerm) => __awaiter(this, void 0, void 0, function* () {
            this.searchTerm = searchTerm;
            if (this.delay)
                this.loading = true;
            yield __classPrivateFieldGet(this, _setFilterItems).call(this);
            this.loading = false;
        })))
            .add(this.formControl.valueChanges.subscribe(value => {
            this.modelChange.emit(value);
            __classPrivateFieldGet(this, _setSelectedItems).call(this, this.filteredItems, value);
        }));
    }
    ngOnDestroy() {
        __classPrivateFieldGet(this, _subscription).unsubscribe();
    }
    ngOnChanges() {
        return __awaiter(this, void 0, void 0, function* () {
            const isFuncItems = typeof this.items === 'function';
            if (!this.filteredItems)
                this.filteredItems = Array.isArray(this.items) ? this.items : [];
            if (!this.selectedItems)
                __classPrivateFieldGet(this, _setSelectedItems).call(this, this.filteredItems, this.formControl.value);
            if (isFuncItems && !this.delay)
                this.delay = DEFAULT_DELAY;
            if (this.disabledVal)
                this.formControl.disable();
            this.validatorMessageVal = Object.assign(Object.assign({}, this.validatorMessageDefault), this.validatorMessage);
            if (this.validateFirstVal)
                this.formControl.markAllAsTouched();
        });
    }
    ngAfterViewInit() {
        var _a;
        (_a = __classPrivateFieldGet(this, _form)) === null || _a === void 0 ? void 0 : _a.addControl(this.name, this.formControl);
        __classPrivateFieldGet(this, _setSize).call(this);
        if (this.default)
            setTimeout(() => this.formControl.setValue(this.default));
    }
    get existValue() {
        return !!this.formControl.value;
    }
    get existInputValue() {
        return !!this.inputFormControl.value;
    }
    get showCancel() {
        return !this.disabled && this.existValue;
    }
    get showInputCancel() {
        return !this.loading && this.existInputValue;
    }
    get displaySelected() {
        return this.multipleVal
            ? this.filteredItems
                .filter(item => { var _a; return (_a = this.formControl.value) === null || _a === void 0 ? void 0 : _a.includes(item[this.valueField]); })
                .map(item => item[this.displayField])
                .join(', ')
            : ZuiO.find(this.valueField, this.displayField)(this.formControl.value)(this.filteredItems);
    }
    get error() {
        var _a, _b, _c, _d;
        if (!this.disabledValidateVal) {
            if ((_a = this.formControl) === null || _a === void 0 ? void 0 : _a.hasError('required'))
                return this.validatorMessageVal.required;
            if (((_b = this.formControl) === null || _b === void 0 ? void 0 : _b.hasError('validatorError')) || ((_c = this.formControl) === null || _c === void 0 ? void 0 : _c.hasError('validatorMsg')))
                return (_d = this.formControl.errors) === null || _d === void 0 ? void 0 : _d.validatorMsg;
        }
        return false;
    }
}
_form = new WeakMap(), _validator = new WeakMap(), _subscription = new WeakMap(), _customValidator = new WeakMap(), _filterValue = new WeakMap(), _getSelected = new WeakMap(), _updateValidator = new WeakMap(), _setSelectedItems = new WeakMap(), _setFilterItems = new WeakMap(), _setSize = new WeakMap();
ZuiSelectComponent.decorators = [
    { type: Component, args: [{
                selector: 'zui-select',
                template: "<mat-form-field\n  appearance=\"outline\"\n  class=\"zui-select\"\n  [class.w-100]=\"fullWidth\"\n  [matTooltip]=\"displaySelected\"\n  [matTooltipDisabled]=\"tooltipDisabled\"\n  [matTooltipPosition]=\"tooltipPosition\"\n  [ngStyle]=\"{width: width}\"\n  (mouseenter)=\"mouseenter($event)\"\n>\n  <mat-label>{{ label }}</mat-label>\n  <mat-select\n    [formControl]=\"formControl\"\n    [required]=\"!disabledValidateVal && required\"\n    [multiple]=\"multipleVal\"\n    [class.hide-arrow]=\"showCancel\"\n    [class.zui-select-wrap]=\"wrapVal\"\n    panelClass=\"zui-select-dc7d3b11__container\"\n  >\n    <!-- <mat-select-trigger> text select-trigger </mat-select-trigger> -->\n    <mat-option *ngIf=\"filterVal\" class=\"zui-select-dc7d3b11__filter zui-select-dc7d3b11__no-checkbox\" (keyup.Space)=\"$event.stopPropagation()\" disabled>\n      <mat-form-field appearance=\"outline\">\n        <mat-icon matPrefix class=\"mr-5\">search</mat-icon>\n        <input matInput class=\"mb-3\" autocomplete=\"off\" [formControl]=\"inputFormControl\" (keydown)=\"$event.stopPropagation()\" />\n        <mat-spinner matSuffix *ngIf=\"loading\" strokeWidth=\"2\" mode=\"indeterminate\" diameter=\"18\" value=\"100\"></mat-spinner>\n        <mat-icon *ngIf=\"showInputCancel\" matSuffix class=\"zui-pointer zui-select-dc7d3b11__clear-icon m-0\" (click)=\"clearText($event)\">cancel</mat-icon>\n      </mat-form-field>\n    </mat-option>\n    <div class=\"zui-select-dc7d3b11__items\">\n      <mat-option *ngFor=\"let item of filteredItems\" [value]=\"item[valueField]\" [matTooltip]=\"item[displayField]\" [matTooltipDisabled]=\"tooltipDisabled\" [matTooltipPosition]=\"tooltipPosition\">\n        {{ item[displayField] }}\n      </mat-option>\n    </div>\n    <mat-option *ngIf=\"filteredItems.length === 0\" disabled class=\"text-center zui-select-dc7d3b11__no-checkbox\">\n      {{ noDataText }}\n    </mat-option>\n  </mat-select>\n  <mat-error *ngIf=\"error\">{{ error }}</mat-error>\n  <mat-icon *ngIf=\"showCancel\" matSuffix class=\"zui-select-dc7d3b11__clear-icon\" (click)=\"clear($event)\">cancel</mat-icon>\n</mat-form-field>\n",
                styles: [":host{display:inline-block}:host ::ng-deep .zui-select .hide-arrow .mat-select-arrow{opacity:0}:host ::ng-deep .zui-select-wrap .mat-select-value,:host ::ng-deep .zui-select-wrap .mat-select-value-text{white-space:unset}::ng-deep .zui-select-dc7d3b11__container{display:flex;flex-direction:column;max-height:var(--zs_dc7d3b11_height)!important;min-width:var(--zs_dc7d3b11_min-width)!important;max-width:var(--zs_dc7d3b11_max-width)!important}::ng-deep .zui-select-dc7d3b11__items{flex:1;overflow:auto}::ng-deep .zui-select-dc7d3b11__no-checkbox mat-pseudo-checkbox.mat-pseudo-checkbox{display:none}::ng-deep .zui-select-dc7d3b11__clear-icon{opacity:.5}::ng-deep .zui-select-dc7d3b11__clear-icon:hover{opacity:1}::ng-deep .zui-select-dc7d3b11__filter.mat-option[disabled]{min-height:80px!important}::ng-deep .zui-select-dc7d3b11__filter.mat-option[disabled] mat-form-field{width:100%}::ng-deep .zui-select-dc7d3b11__filter.mat-option[disabled] mat-form-field>div{margin:0;padding:0}"]
            },] }
];
ZuiSelectComponent.propDecorators = {
    width: [{ type: Input }],
    items: [{ type: Input }],
    selectedItems: [{ type: Input }],
    delay: [{ type: Input }],
    label: [{ type: Input }],
    valueField: [{ type: Input }],
    displayField: [{ type: Input }],
    noDataText: [{ type: Input }],
    name: [{ type: Input }],
    panelWidth: [{ type: Input }],
    panelHeight: [{ type: Input }],
    tooltipDisabled: [{ type: Input }],
    tooltipPosition: [{ type: Input }],
    required: [{ type: Input }],
    default: [{ type: Input }],
    model: [{ type: Input }],
    form: [{ type: Input }],
    validator: [{ type: Input }],
    multiple: [{ type: Input }],
    validateFirst: [{ type: Input }],
    disabled: [{ type: Input }],
    fullWidthVal: [{ type: Input, args: ['fullWidth',] }],
    fullWidth: [{ type: HostBinding, args: ['class.d-block',] }],
    wrap: [{ type: Input }],
    filter: [{ type: Input }],
    caseSensitive: [{ type: Input }],
    disabledValidate: [{ type: Input }],
    validatorMessage: [{ type: Input }],
    modelChange: [{ type: Output }]
};
//# sourceMappingURL=index.component.js.map