import { Directive, TemplateRef, EventEmitter, Component, ChangeDetectionStrategy, ChangeDetectorRef, Inject, Optional, Input, Output, ViewChild, ContentChild, Pipe, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { __classPrivateFieldGet, __awaiter, __classPrivateFieldSet } 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, SdLabelDefDirective, SdViewDefDirective, SdCommonModule } from '@sd-angular/core/common';
import { SdUtilityService } from '@sd-angular/core/utility';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { SdTranslateModule } from '@sd-angular/core/translate';
import { MatButtonModule } from '@angular/material/button';
import { SdPopoverModule } from '@sd-angular/core/popover';

class SdInputSuffixDirective {
    constructor(templateRef) {
        this.templateRef = templateRef;
    }
}
SdInputSuffixDirective.decorators = [
    { type: Directive, args: [{
                selector: '[sdInputSuffix]'
            },] }
];
SdInputSuffixDirective.ctorParameters = () => [
    { type: TemplateRef }
];

var _name, _form, _blurOnEnter_1, _model, _pattern, _validator, _subscription, _updateValidator, _onChange, _customValidator;
class SdInput {
    constructor(ref, formConfig, utilityService) {
        this.ref = ref;
        this.formConfig = formConfig;
        this.utilityService = utilityService;
        this.id = `I${v4()}`;
        _name.set(this, v4());
        _form.set(this, void 0);
        this.type = 'text';
        this.disableErrorMessage = false;
        _blurOnEnter_1.set(this, false);
        _model.set(this, void 0);
        this.modelChange = new EventEmitter();
        // Validator
        this.isRequired = false;
        this.isReadonly = false;
        _pattern.set(this, void 0);
        _validator.set(this, void 0);
        this.icon = 'search';
        this.hideIcon = false;
        this.sdClickIcon = new EventEmitter();
        this.sdChange = new EventEmitter();
        this.sdFocus = new EventEmitter();
        this.sdBlur = new EventEmitter();
        this.sdFocusForceBlur = new EventEmitter();
        this.keyupEnter = new EventEmitter();
        this.formControl = new SdFormControl();
        _subscription.set(this, new Subscription());
        this.isFocused = false;
        this.copyable = false;
        this.copied = false;
        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.minlength > 0) {
                validators.push(Validators.minLength(this.minlength));
            }
            if (this.maxlength > 0) {
                validators.push(Validators.maxLength(this.maxlength));
            }
            if (__classPrivateFieldGet(this, _pattern)) {
                validators.push(Validators.pattern(__classPrivateFieldGet(this, _pattern)));
            }
            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) => {
            this.modelChange.emit(this.formControl.value);
            this.sdChange.emit(this.formControl.value);
        });
        this.onKeyupEnter = () => {
            var _a;
            const val = ((_a = this.formControl.value) !== null && _a !== void 0 ? _a : '').toString();
            if (val.length > val.trim().length) {
                this.formControl.setValue(val.trim());
            }
            this.keyupEnter.emit(this.formControl.value);
            if (__classPrivateFieldGet(this, _blurOnEnter_1)) {
                this.blur();
            }
        };
        this.onClickIcon = (event) => {
            event === null || event === void 0 ? void 0 : event.preventDefault();
            event === null || event === void 0 ? void 0 : event.stopPropagation();
            this.sdClickIcon.emit(this.formControl.value);
        };
        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.formControl.value) !== null && _a !== void 0 ? _a : '').toString();
            if (val.length > val.trim().length) {
                this.formControl.setValue(val.trim());
            }
            this.sdBlur.emit(this.formControl.value);
        };
        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* () {
                const value = c.value || 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',
            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(value, {
                emitEvent: false
            });
        }
    }
    set required(val) {
        this.isRequired = (val === '') || val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set readonly(val) {
        this.isReadonly = (val === '') || val;
    }
    set pMinlength(val) {
        this.minlength = +val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set pMaxlength(val) {
        this.maxlength = +val;
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set pattern(val) {
        __classPrivateFieldSet(this, _pattern, val);
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    set validator(validator) {
        __classPrivateFieldSet(this, _validator, validator);
        __classPrivateFieldGet(this, _updateValidator).call(this);
    }
    // Optional
    set disabled(val) {
        val = (val === '') || val;
        if (val) {
            this.formControl.disable();
        }
        else {
            this.formControl.enable();
        }
    }
    set _hideIcon(val) {
        this.hideIcon = (val === '') || val;
        val = (val === '') || val;
    }
    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.formControl.sdChanges.subscribe(() => {
            this.ref.markForCheck();
        }));
    }
    ngAfterViewInit() {
        var _a;
        __classPrivateFieldGet(this, _subscription).add(this.formControl.valueChanges.subscribe(__classPrivateFieldGet(this, _onChange)));
        (_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();
    }
    onCopyText() {
        SdUtility.copyToClipboard(__classPrivateFieldGet(this, _model));
        this.copied = true;
        setTimeout(() => {
            this.copied = false;
        }, 2000);
    }
}
_name = new WeakMap(), _form = new WeakMap(), _blurOnEnter_1 = new WeakMap(), _model = new WeakMap(), _pattern = new WeakMap(), _validator = new WeakMap(), _subscription = new WeakMap(), _updateValidator = new WeakMap(), _onChange = new WeakMap(), _customValidator = new WeakMap();
SdInput.decorators = [
    { type: Component, args: [{
                selector: 'sd-input',
                template: "<ng-container *ngIf=\"!appearance && sdLabelDef?.templateRef\">\r\n  <ng-container *ngTemplateOutlet=\"sdLabelDef.templateRef\">\r\n  </ng-container>\r\n</ng-container>\r\n<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<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\"\r\n      [ngClass]=\"{'sd-form-tooltip':tooltip, '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]=\"formControl\" [type]=\"type\" #control matInput\r\n        [placeholder]=\"placeholder || (appearance ? label : '')\" (keyup.enter)=\"onKeyupEnter()\" (focus)=\"onFocus()\"\r\n        (blur)=\"onBlur()\" [required]=\"isRequired\" [readonly]=\"isReadonly\" [autocomplete]=\"id\" autocorrect=\"off\"\r\n        [step]=\"1\" [attr.data-qclabel]=\"label\" [attr.data-qcid]=\"qcId\" [sdPopoverTriggerFor]=\"null\"\r\n        [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\">\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      <span class=\"mr-1\" *ngIf=\"maxlength && !formControl.disabled\" matSuffix>{{formControl.value?.length || 0}}/{{maxlength}}</span>\r\n      <ng-container *ngIf=\"sdInputSuffix?.templateRef\" matSuffix>\r\n        <ng-container *ngTemplateOutlet=\"sdInputSuffix.templateRef\">\r\n        </ng-container>\r\n      </ng-container>\r\n      <mat-icon *ngIf=\"!hideIcon && sdClickIcon?.observers?.length\" (click)=\"onClickIcon($event)\"\r\n        class=\"pointer sd-suffix-icon\" matSuffix>\r\n        {{icon}}\r\n      </mat-icon>\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?.maxlength\">\r\n        <ng-container *ngIf=\"!disableErrorMessage\">{{'Max length' | sdTranslate}} {{maxlength}}\r\n        </ng-container>\r\n      </mat-error>\r\n      <mat-error *ngIf=\"formControl.errors?.pattern\">\r\n        <ng-container *ngIf=\"!disableErrorMessage\">{{'Pattern error' | sdTranslate}}</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    <div *ngIf=\"tooltip\" class=\"sd-tooltip\">\r\n      <mat-icon (click)=\"sdTooltip.toggle()\" [matTooltip]=\"formControl.value | sdInputTooltipPipe:tooltip\" matSuffix\r\n        #sdTooltip=\"matTooltip\">info</mat-icon>\r\n    </div>\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?.maxlength\">\r\n    {{'Max length' | sdTranslate}} <strong>{{maxlength}}</strong>\r\n  </span>\r\n  <span *ngIf=\"formControl.errors?.pattern\">\r\n    {{'Pattern error' | 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}"]
            },] }
];
SdInput.ctorParameters = () => [
    { type: ChangeDetectorRef },
    { type: undefined, decorators: [{ type: Inject, args: [FORM_CONFIG,] }, { type: Optional }] },
    { type: SdUtilityService }
];
SdInput.propDecorators = {
    name: [{ type: Input }],
    appearance: [{ type: Input }],
    size: [{ type: Input }],
    form: [{ type: Input }],
    _label: [{ type: Input, args: ['label',] }],
    placeholder: [{ type: Input }],
    type: [{ type: Input }],
    _disableErrorMessage: [{ type: Input, args: ['disableErrorMessage',] }],
    _blurOnEnter: [{ type: Input, args: ['blurOnEnter',] }],
    model: [{ type: Input }],
    modelChange: [{ type: Output }],
    required: [{ type: Input }],
    readonly: [{ type: Input }],
    pMinlength: [{ type: Input, args: ['minlength',] }],
    pMaxlength: [{ type: Input, args: ['maxlength',] }],
    pattern: [{ type: Input }],
    validator: [{ type: Input }],
    disabled: [{ type: Input }],
    icon: [{ type: Input }],
    _hideIcon: [{ type: Input, args: ['hideIcon',] }],
    sdClickIcon: [{ type: Output }],
    tooltip: [{ type: Input }],
    sdChange: [{ type: Output }],
    sdFocus: [{ type: Output }],
    sdBlur: [{ type: Output }],
    sdFocusForceBlur: [{ type: Output }],
    keyupEnter: [{ type: Output }],
    control: [{ type: ViewChild, args: ['control',] }],
    sdInputSuffix: [{ type: ContentChild, args: [SdInputSuffixDirective,] }],
    sdLabelDef: [{ type: ContentChild, args: [SdLabelDefDirective,] }],
    sdView: [{ type: ContentChild, args: [SdViewDefDirective,] }],
    copyTooltip: [{ type: ViewChild, args: ['copyTooltip',] }],
    _copyable: [{ type: Input, args: ['copyable',] }]
};

class SdInputTooltipPipe {
    transform(value, tooltip) {
        if (typeof (tooltip) === 'string') {
            return tooltip;
        }
        return tooltip(value);
    }
}
SdInputTooltipPipe.decorators = [
    { type: Pipe, args: [{
                name: 'sdInputTooltipPipe'
            },] }
];

class TouchDirective {
    ngOnChanges(changes) {
        if (changes.touch) {
            this.ref.markForCheck();
        }
    }
}
TouchDirective.decorators = [
    { type: Directive, args: [{
                selector: '[touch]'
            },] }
];
TouchDirective.propDecorators = {
    touch: [{ type: Input }],
    ref: [{ type: Input }]
};

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

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

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

export { SdInput, SdInputModule, SdInputSuffixDirective, SdInputTooltipPipe, TouchDirective as ɵa };
//# sourceMappingURL=sd-angular-core-input.js.map
