import { EventEmitter, Component, ChangeDetectionStrategy, ChangeDetectorRef, Inject, Optional, Input, Output, ViewChild, ContentChild, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { __classPrivateFieldGet, __classPrivateFieldSet, __awaiter } from 'tslib';
import { Validators, NgForm, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { v4 } from 'uuid';
import hash from 'object-hash';
import { Subscription } from 'rxjs';
import { SdFormControl, FORM_CONFIG, SdViewDefDirective, SdSuffixDirective, SdLabelDefDirective, SdCommonModule } from '@sd-angular/core/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { SdTranslateModule } from '@sd-angular/core/translate';
import { SdPopoverModule } from '@sd-angular/core/popover';

var _name, _form, _blurOnEnter_1, _model, _validator, _subscription, _getValueWithFormat, _formatNumber, _toNumber, _updateValidator, _onChange, _checkValue, _customValidator;
class SdInputNumberErrotStateMatcher {
    constructor(formControl) {
        this.formControl = formControl;
    }
    isErrorState(control, form) {
        var _a, _b, _c;
        const isSubmitted = form && form.submitted;
        return !!(((_a = this.formControl) === null || _a === void 0 ? void 0 : _a.invalid) && (((_b = this.formControl) === null || _b === void 0 ? void 0 : _b.dirty) || ((_c = this.formControl) === null || _c === void 0 ? void 0 : _c.touched) || isSubmitted));
    }
}
class SdInputNumber {
    constructor(ref, formConfig) {
        this.ref = ref;
        this.formConfig = formConfig;
        this.id = `I${v4()}`;
        _name.set(this, v4());
        _form.set(this, void 0);
        this.disableErrorMessage = false;
        _blurOnEnter_1.set(this, false);
        _model.set(this, void 0);
        this.modelChange = new EventEmitter();
        // Validator
        this.isRequired = false;
        this.precision = 3; //số chữ số thập phân 
        this.isReadonly = false;
        _validator.set(this, void 0);
        this.copyable = false;
        this.copied = false;
        this.sdChange = new EventEmitter();
        this.sdFocus = new EventEmitter();
        this.sdFocusForceBlur = new EventEmitter();
        this.keyupEnter = new EventEmitter();
        this.formControl = new SdFormControl();
        this.inputControl = new SdFormControl();
        _subscription.set(this, new Subscription());
        this.matcher = new SdInputNumberErrotStateMatcher(this.formControl);
        this.isFocused = false;
        _getValueWithFormat.set(this, (value) => {
            const arrayNext = value.split(',');
            if (arrayNext.length >= 2) {
                return `${__classPrivateFieldGet(this, _formatNumber).call(this, arrayNext[0])},${arrayNext[1]}`;
            }
            return __classPrivateFieldGet(this, _formatNumber).call(this, value);
        });
        _formatNumber.set(this, (text) => {
            return Number.toVNCurrency(((text === null || text === void 0 ? void 0 : text.toString()) || '').replace(/\./g, ''));
            // const arrs: string[] = (text?.toString() || '').replace(/\./g, '').split('');
            // return arrs.reverse().reduce((acc, num, index) => {
            //   return num + (num !== '-' && index && !(index % 3) ? '.' : '') + acc;
            // }, '');
        });
        _toNumber.set(this, (text) => +(((text === null || text === void 0 ? void 0 : text.toString()) || '').replace(/\./g, '').replace(/,/g, '.')));
        this.reValidate = () => {
            this.formControl.updateValueAndValidity();
        };
        _updateValidator.set(this, () => {
            this.formControl.clearValidators();
            this.formControl.clearAsyncValidators();
            const validators = [];
            const asyncValidators = [];
            if (this.isRequired) {
                validators.push(Validators.required);
            }
            if (this.minNumber || this.minNumber === 0) {
                validators.push(Validators.min(this.minNumber));
            }
            if (this.maxNumber || this.maxNumber === 0) {
                validators.push(Validators.max(this.maxNumber));
            }
            if (__classPrivateFieldGet(this, _validator)) {
                asyncValidators.push(__classPrivateFieldGet(this, _customValidator).call(this, __classPrivateFieldGet(this, _validator)));
            }
            this.formControl.setValidators(validators);
            this.formControl.setAsyncValidators(asyncValidators);
            this.formControl.updateValueAndValidity();
        });
        _onChange.set(this, (value) => {
            __classPrivateFieldSet(this, _model, value !== null && value !== void 0 ? value : null);
            this.modelChange.emit(__classPrivateFieldGet(this, _model));
            this.sdChange.emit(__classPrivateFieldGet(this, _model));
            this.formControl.setValue(__classPrivateFieldGet(this, _model));
        });
        this.onKeyupEnter = () => {
            var _a;
            const val = ((_a = this.inputControl.value) !== null && _a !== void 0 ? _a : '').toString();
            if (val.length > val.trim().length) {
                this.inputControl.setValue(val.trim());
            }
            this.keyupEnter.emit(this.inputControl.value);
            if (__classPrivateFieldGet(this, _blurOnEnter_1)) {
                this.blur();
            }
        };
        this.onKeydown = (event) => {
            if (event.ctrlKey && event.key == 'v') {
                __classPrivateFieldGet(this, _checkValue).call(this, event, '');
                return;
            }
            const key = event.keyCode || event.charCode;
            if (key == 8 || key == 46 || key == 37 || key == 39 || key == 35 || key == 36 || key == 9) {
                return;
            }
            if (event.ctrlKey && (event.key == 'c' || event.key == 'x' || event.key == 'a')) {
                return;
            }
            if (event.shiftKey && key == 9) {
                return;
            }
            __classPrivateFieldGet(this, _checkValue).call(this, event, event.key);
        };
        _checkValue.set(this, (event, nextKey) => {
            const current = event.target.value;
            // if(this.maxNumber === +current.toString().replace(/\./g, '').replace(/,/g, '.')){
            //   event.preventDefault();
            //   return;
            // }
            const curval_arr = current.split("");
            curval_arr.splice(event.target.selectionStart, (event.target.selectionEnd - event.target.selectionStart), nextKey);
            const newval = curval_arr.join("");
            if (this.type !== 'positive' && newval === '-') {
                return;
            }
            const regExp = new RegExp(`^${this.regex}`, 'g');
            if (newval && !String(newval).match(regExp)) {
                event.preventDefault();
                return;
            }
            // const value = (newval.toString().replace(/\./g, '').replace(/,/g, '.'));
            // if ((this.maxNumber || this.maxNumber === 0) && +value > this.maxNumber) {
            //   setTimeout(() => {
            //     this.inputControl.setValue(this.#getValueWithFormat(this.maxNumber.toString().replace(/\./g, ',')));
            //   }, 10);
            //   event.preventDefault();
            // }
        });
        this.onFocus = () => {
            var _a;
            this.isFocused = true;
            this.sdFocus.emit();
            if (((_a = this.sdFocusForceBlur.observers) === null || _a === void 0 ? void 0 : _a.length) > 0) {
                this.blur();
                this.sdFocusForceBlur.emit();
            }
        };
        this.onBlur = () => {
            var _a;
            this.isFocused = false;
            const val = ((_a = this.inputControl.value) !== null && _a !== void 0 ? _a : '').toString();
            const arrayValue = val.split(',');
            if (arrayValue.length >= 2 && arrayValue[1] == '') {
                this.inputControl.setValue(__classPrivateFieldGet(this, _formatNumber).call(this, arrayValue[0]));
                return;
            }
            if (val.length > val.trim().length) {
                this.inputControl.setValue(val.trim());
            }
        };
        this.onClick = () => {
            var _a;
            if ((_a = this.sdView) === null || _a === void 0 ? void 0 : _a.templateRef) {
                if (!this.formControl.disabled && !this.isFocused) {
                    this.focus();
                }
            }
        };
        this.blur = () => {
            var _a, _b;
            this.isFocused = false;
            (_b = (_a = this.control) === null || _a === void 0 ? void 0 : _a.nativeElement) === null || _b === void 0 ? void 0 : _b.blur();
        };
        this.focus = () => {
            this.isFocused = true;
            setTimeout(() => {
                var _a, _b;
                (_b = (_a = this.control) === null || _a === void 0 ? void 0 : _a.nativeElement) === null || _b === void 0 ? void 0 : _b.focus();
            }, 100);
        };
        _customValidator.set(this, (func) => {
            return (c) => __awaiter(this, void 0, void 0, function* () {
                var _a;
                const value = (_a = c.value) !== null && _a !== void 0 ? _a : null;
                if (func && typeof (func) === 'function') {
                    const result = func(value);
                    if (result instanceof Promise) {
                        const message = yield result;
                        if (message) {
                            return {
                                customValidator: message
                            };
                        }
                        return null;
                    }
                    if (result) {
                        return {
                            customValidator: result
                        };
                    }
                    return null;
                }
                return null;
            });
        });
    }
    set name(val) {
        if (val) {
            __classPrivateFieldSet(this, _name, val);
        }
    }
    set form(val) {
        if (val) {
            if (val instanceof NgForm) {
                __classPrivateFieldSet(this, _form, val.form);
            }
            else {
                __classPrivateFieldSet(this, _form, val);
            }
        }
    }
    set _label(val) {
        this.label = val;
        this.qcId = hash({
            selector: 'sd-input-number',
            label: val
        });
    }
    ;
    set _disableErrorMessage(val) {
        this.disableErrorMessage = (val === '') || val;
    }
    set _blurOnEnter(val) {
        __classPrivateFieldSet(this, _blurOnEnter_1, (val === '') || val);
    }
    set model(value) {
        if (__classPrivateFieldGet(this, _model) !== value) {
            __classPrivateFieldSet(this, _model, value);
            this.formControl.setValue(__classPrivateFieldGet(this, _model), {
                emitEvent: false
            });
            if (value || value === 0) {
                const val = value.toString().replace(/\./g, ',');
                this.inputControl.setValue(__classPrivateFieldGet(this, _getValueWithFormat).call(this, val), {
                    emitEvent: false
                });
            }
            else {
                this.inputControl.setValue('', {
                    emitEvent: false
                });
            }
        }
    }
    set required(val) {
        this.isRequired = (val === '') || val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set readonly(val) {
        this.isReadonly = (val === '') || val;
    }
    set min(val) {
        this.minNumber = val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set max(val) {
        this.maxNumber = val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set validator(validator) {
        __classPrivateFieldSet(this, _validator, validator);
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set disabled(val) {
        val = (val === '') || val;
        if (val) {
            this.inputControl.disable();
            this.formControl.disable();
        }
        else {
            this.inputControl.enable();
            this.formControl.enable();
        }
    }
    set _copyable(val) {
        this.copyable = (val === '') || val;
    }
    ngOnInit() {
        var _a;
        this.appearance = this.appearance || ((_a = this.formConfig) === null || _a === void 0 ? void 0 : _a.appearance);
        __classPrivateFieldGet(this, _subscription).add(this.inputControl.touchChanges.subscribe(() => {
            this.formControl.markAsTouched();
            this.ref.markForCheck();
        }));
        __classPrivateFieldGet(this, _subscription).add(this.formControl.sdChanges.subscribe(() => {
            this.ref.markForCheck();
        }));
        __classPrivateFieldGet(this, _subscription).add(this.inputControl.sdChanges.subscribe(() => {
            this.ref.markForCheck();
        }));
    }
    get regex() {
        let result = `(([0-9]+(\\.[0-9])?)+(\\,[0-9]{0,${this.precision}}){0,1})$`;
        if (this.precision === 0) {
            result = `(([0-9]+(\\.[0-9])?)+)$`;
        }
        if (this.type === 'negative') {
            result = `[-]${result}`;
        }
        if (!this.type) {
            result = `[-]?${result}`;
        }
        return result;
    }
    ngAfterViewInit() {
        var _a;
        __classPrivateFieldGet(this, _subscription).add(this.inputControl.valueChanges.subscribe(() => {
            const val = this.inputControl.value;
            if (!val) {
                __classPrivateFieldGet(this, _onChange).call(this, undefined);
                return;
            }
            const value = __classPrivateFieldGet(this, _toNumber).call(this, val);
            if (!isNaN(value)) {
                this.inputControl.setValue(__classPrivateFieldGet(this, _getValueWithFormat).call(this, val), {
                    emitEvent: false
                });
                __classPrivateFieldGet(this, _onChange).call(this, value);
            }
        }));
        (_a = __classPrivateFieldGet(this, _form)) === null || _a === void 0 ? void 0 : _a.addControl(__classPrivateFieldGet(this, _name), this.formControl);
        this.ref.detectChanges();
    }
    ngOnDestroy() {
        var _a;
        (_a = __classPrivateFieldGet(this, _form)) === null || _a === void 0 ? void 0 : _a.removeControl(__classPrivateFieldGet(this, _name));
        __classPrivateFieldGet(this, _subscription).unsubscribe();
    }
    onPaste(event) {
        const nextKey = event.clipboardData.getData('text');
        __classPrivateFieldGet(this, _checkValue).call(this, event, nextKey);
    }
    onCopyText() {
        SdUtility.copyToClipboard(this.inputControl.value);
        this.copied = true;
        setTimeout(() => {
            this.copied = false;
        }, 2000);
    }
}
_name = new WeakMap(), _form = new WeakMap(), _blurOnEnter_1 = new WeakMap(), _model = new WeakMap(), _validator = new WeakMap(), _subscription = new WeakMap(), _getValueWithFormat = new WeakMap(), _formatNumber = new WeakMap(), _toNumber = new WeakMap(), _updateValidator = new WeakMap(), _onChange = new WeakMap(), _checkValue = new WeakMap(), _customValidator = new WeakMap();
SdInputNumber.decorators = [
    { type: Component, args: [{
                selector: 'sd-input-number',
                template: "<label *ngIf=\"!appearance && label && !sdLabelDef?.templateRef\" class=\"d-block mb-0 T14M\">{{label}} <span class=\"text-danger mb-2\"\r\n    *ngIf=\"isRequired\">*</span></label>\r\n<ng-container *ngIf=\"sdLabelDef?.templateRef\" matSuffix>\r\n  <ng-container *ngTemplateOutlet=\"sdLabelDef.templateRef\">\r\n  </ng-container>\r\n</ng-container>\r\n<div class=\"d-flex align-items-center\" [class.sd-view]=\"sdView?.templateRef\" [class.c-focused]=\"isFocused\"\r\n  [class.c-disabled]=\"formControl.disabled\" (click)=\"onClick()\">\r\n  <ng-container *ngIf=\"sdView?.templateRef && !isFocused; else default\">\r\n    <ng-container *ngTemplateOutlet=\"sdView.templateRef;context: { value: formControl.value }\">\r\n    </ng-container>\r\n  </ng-container>\r\n  <ng-template #default>\r\n    <mat-form-field class=\"sd-md\" [ngClass]=\"{ 'sd-sm': size === 'sm', 'no-padding-wrapper': disableErrorMessage}\"\r\n      [appearance]=\"appearance || 'outline'\">\r\n      <mat-label *ngIf=\"appearance && label\">{{label}}</mat-label>\r\n      <input aria-hidden=\"true\" [id]=\"id\" [formControl]=\"inputControl\" #control matInput\r\n        [placeholder]=\"placeholder || (appearance ? label : '')\" [errorStateMatcher]=\"matcher\"\r\n        (keyup.enter)=\"onKeyupEnter()\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeydown($event)\"\r\n        [required]=\"isRequired\" [readonly]=\"isReadonly\" [autocomplete]=\"id\" (paste)=\"onPaste($event)\" autocorrect=\"off\"\r\n        [attr.data-qclabel]=\"label\" [attr.data-qcid]=\"qcId\"\r\n        [sdPopoverTriggerFor]=\"null\" [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\">\r\n      <ng-container *ngIf=\"sdSuffix?.templateRef\" matSuffix>\r\n        <ng-container *ngTemplateOutlet=\"sdSuffix.templateRef\">\r\n        </ng-container>\r\n      </ng-container>\r\n      <svg \r\n        #copyTooltip=\"matTooltip\" \r\n        *ngIf=\"copyable\" \r\n        matSuffix \r\n        [matTooltip]=\"copied ? 'Copied' : 'Copy'\" \r\n        class=\"icon-copy\" \r\n        focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\" \r\n        (click)=\"onCopyText()\">\r\n        <path d=\"M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z\"></path>\r\n      </svg>\r\n      <mat-error *ngIf=\"formControl?.errors?.required\">\r\n        <ng-container *ngIf=\"!disableErrorMessage\">{{ \"This field is required\" | sdTranslate }}</ng-container>\r\n      </mat-error>\r\n      <mat-error *ngIf=\"formControl.errors?.min\">        \r\n        <ng-container *ngIf=\"!disableErrorMessage\">{{'Kh\u00F4ng nh\u1EADp b\u00E9 h\u01A1n '}} <strong>{{minNumber}}</strong></ng-container>\r\n      </mat-error>\r\n      <mat-error *ngIf=\"formControl.errors?.max\">\r\n        <ng-container *ngIf=\"!disableErrorMessage\">{{'Kh\u00F4ng nh\u1EADp l\u1EDBn h\u01A1n '}} <strong>{{maxNumber}}</strong></ng-container>\r\n      </mat-error>\r\n      <mat-error *ngIf=\"formControl.errors?.customValidator\">\r\n        <ng-container *ngIf=\"!disableErrorMessage\">{{formControl.errors?.customValidator}}</ng-container>\r\n      </mat-error>\r\n    </mat-form-field>\r\n  </ng-template>\r\n</div>\r\n<!-- <sd-popover #error=\"sdPopover\" type=\"danger\" width=\"300px\">\r\n  <span *ngIf=\"formControl.errors?.required\">\r\n    {{ \"This field is required\" | sdTranslate }}\r\n  </span>\r\n  <span *ngIf=\"formControl.errors?.customValidator\">\r\n    {{formControl.errors?.customValidator}}\r\n  </span>\r\n</sd-popover> -->",
                changeDetection: ChangeDetectionStrategy.OnPush,
                styles: [":host ::ng-deep .mat-form-field.sd-form-tooltip{width:calc(100% - 30px)}:host ::ng-deep .mat-form-field.no-padding-wrapper .mat-form-field-wrapper{padding-bottom:0}:host ::ng-deep .mat-form-field.mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-outline{background:#f6f6f6;color:#e9e9e9}:host ::ng-deep .mat-form-field input.mat-input-element:disabled{color:#4d4d4d!important}:host ::ng-deep .mat-form-field .mat-placeholder-required{color:#f82c13}:host ::ng-deep .mat-form-field:hover .icon-copy{opacity:1}:host ::ng-deep .mat-form-field .icon-copy{cursor:pointer;fill:rgba(0,0,0,.5);height:.9em;opacity:0;transition:opacity .2s linear;width:.9em}.sd-view:not(.c-focused):not(.c-disabled):hover{background-color:#ebecf0}.sd-tooltip{display:inline-block;margin:auto;text-align:center;width:30px}:host{display:block;padding-top:5px}.sd-md:hover .btn-copy{visibility:visible}.btn-copy{background:#e9e9e9!important;font-size:12px;line-height:26px!important;margin-bottom:3px;visibility:hidden}"]
            },] }
];
SdInputNumber.ctorParameters = () => [
    { type: ChangeDetectorRef },
    { type: undefined, decorators: [{ type: Inject, args: [FORM_CONFIG,] }, { type: Optional }] }
];
SdInputNumber.propDecorators = {
    name: [{ type: Input }],
    size: [{ type: Input }],
    form: [{ type: Input }],
    _label: [{ type: Input, args: ['label',] }],
    placeholder: [{ type: Input }],
    _disableErrorMessage: [{ type: Input, args: ['disableErrorMessage',] }],
    _blurOnEnter: [{ type: Input, args: ['blurOnEnter',] }],
    model: [{ type: Input }],
    modelChange: [{ type: Output }],
    required: [{ type: Input }],
    type: [{ type: Input }],
    precision: [{ type: Input }],
    readonly: [{ type: Input }],
    min: [{ type: Input }],
    max: [{ type: Input }],
    validator: [{ type: Input }],
    disabled: [{ type: Input }],
    appearance: [{ type: Input }],
    copyTooltip: [{ type: ViewChild, args: ['copyTooltip',] }],
    _copyable: [{ type: Input, args: ['copyable',] }],
    sdChange: [{ type: Output }],
    sdFocus: [{ type: Output }],
    sdFocusForceBlur: [{ type: Output }],
    keyupEnter: [{ type: Output }],
    control: [{ type: ViewChild, args: ['control',] }],
    sdView: [{ type: ContentChild, args: [SdViewDefDirective,] }],
    sdSuffix: [{ type: ContentChild, args: [SdSuffixDirective,] }],
    sdLabelDef: [{ type: ContentChild, args: [SdLabelDefDirective,] }]
};

class SdInputNumberModule {
}
SdInputNumberModule.decorators = [
    { type: NgModule, args: [{
                declarations: [SdInputNumber],
                imports: [
                    CommonModule,
                    FormsModule,
                    ReactiveFormsModule,
                    MatFormFieldModule,
                    MatInputModule,
                    MatIconModule,
                    MatTooltipModule,
                    SdTranslateModule,
                    SdCommonModule,
                    SdPopoverModule,
                    MatButtonModule
                ],
                exports: [
                    SdInputNumber
                ]
            },] }
];

/*
 * Public API Surface of superdev-angular-core
 */

/**
 * Generated bundle index. Do not edit.
 */

export { SdInputNumber, SdInputNumberModule };
//# sourceMappingURL=sd-angular-core-input-number.js.map
