import * as i0 from '@angular/core';
import { EventEmitter, Directive, ViewChild, Input, Output, HostListener } from '@angular/core';
import { isNullOrUndefined, isString, isNumber, isObject } from '@ironsource/fusion-ui/utils';
import { FormControl } from '@angular/forms';
import '@ironsource/fusion-ui/components/input';
import { BehaviorSubject, Subject, fromEvent } from 'rxjs';
import * as i1 from '@angular/common';
import { takeUntil, filter } from 'rxjs/operators';

var InlineInputType;
(function (InlineInputType) {
    InlineInputType[InlineInputType["Text"] = 0] = "Text";
    InlineInputType[InlineInputType["Number"] = 1] = "Number";
    InlineInputType[InlineInputType["Currency"] = 2] = "Currency";
    InlineInputType[InlineInputType["Percent"] = 3] = "Percent";
})(InlineInputType || (InlineInputType = {}));

const _c0 = ["inputComponent"];
class InputInlineBaseComponent {
    get inputType() {
        return this.isType(InlineInputType.Text) ? 'text' : 'number';
    }
    get inputUnits() {
        return this.isType(InlineInputType.Currency) ? '$' : this.isType(InlineInputType.Percent) ? '%' : null;
    }
    get inputUnitsPosition() {
        return this.isType(InlineInputType.Currency) ? 'left' : this.isType(InlineInputType.Percent) ? 'right' : null;
    }
    get savedValueToString() {
        let value = this.savedValue;
        if (!this.isType(InlineInputType.Text)) {
            if (!this.savedValue) {
                value = '0';
            }
            else if (isNaN(this.savedValue)) {
                value = this.savedValue;
            }
            else if (this.isType(InlineInputType.Currency)) {
                value = this.currencyPipe
                    .transform(this.savedValue, this.currencyPipeCurrencyCode, this.currencyPipeDisplay, this.currencyPipeDigitsInfo)
                    .replace(/\.00$/, '');
            }
            else if (this.isType(InlineInputType.Percent)) {
                value = this.savedValue + ' %';
            }
        }
        return value;
    }
    get isTypeCurrency() {
        return this.isType(InlineInputType.Currency) && this.savedValue && !isNaN(this.savedValue);
    }
    get currencyPipeCurrencyCode() {
        return !isNullOrUndefined(this.currencyPipeParameters) ? this.currencyPipeParameters.currencyCode : undefined;
    }
    get currencyPipeDisplay() {
        return !isNullOrUndefined(this.currencyPipeParameters) ? this.currencyPipeParameters.display : undefined;
    }
    get currencyPipeDigitsInfo() {
        return !isNullOrUndefined(this.currencyPipeParameters) ? this.currencyPipeParameters.digitsInfo : undefined;
    }
    constructor(currencyPipe, elementRef, cdr) {
        this.currencyPipe = currencyPipe;
        this.elementRef = elementRef;
        this.cdr = cdr;
        this.type = InlineInputType.Text;
        // eslint-disable-next-line
        this.onSave = new EventEmitter();
        // eslint-disable-next-line
        this.onCancel = new EventEmitter();
        /** @internal */
        this.isEditMode$ = new BehaviorSubject(false);
        /** @internal */
        this.setEditMode$ = new Subject();
        /** @internal */
        this.inputControl = new FormControl();
        this.stayInEditMode = false;
        this.onDestroy$ = new Subject();
        /** @internal */
        this.propagateChange = (_) => { };
    }
    ngOnInit() {
        this.sanitationRegex = this.inputType === 'text' ? '' : '[0-9.]';
        this.addListeners();
    }
    ngOnDestroy() {
        this.onDestroy$.next();
        this.onDestroy$.complete();
    }
    ngOnChanges(changes) {
        if ((!changes.error || !changes.error.currentValue) &&
            changes.loading &&
            changes.loading.currentValue !== changes.loading.previousValue &&
            changes.loading.currentValue === false &&
            this.isEditMode$.getValue() &&
            !this.stayInEditMode) {
            this.isEditMode$.next(false);
        }
        if (this.inputComponent) {
            this.inputComponent.toggleErrorClass(!!changes.error && !!changes.error.currentValue);
        }
    }
    /** @internal */
    save() {
        if (this.isEditMode$.getValue() && this.inputControl.valid) {
            if (this.inputControl.value.toString() !== this.savedValue.toString()) {
                this.propagateChange(this.inputControl.value);
                this.onSave.emit({
                    currentValue: this.savedValue,
                    newValue: this.inputControl.value
                });
            }
            else {
                this.cancel();
            }
        }
    }
    /** @internal */
    cancel() {
        if (this.isEditMode$.getValue() && !this.loading) {
            if (!this.stayInEditMode) {
                this.inputControl.setValue(this.savedValue, { emitEvent: false });
                this.inputComponent.blur();
                this.isEditMode$.next(false);
                this.onCancel.emit();
            }
            else {
                this.stayInEditMode = false;
            }
        }
    }
    /** @internal */
    goToEditMode(withValue) {
        this.inputControl.setValue(!isNullOrUndefined(withValue) ? withValue : this.savedValue, { emitEvent: false });
        this.isEditMode$.next(true);
        setTimeout(() => {
            this.inputComponent.setFocus();
        }, 0);
    }
    /** @internal */
    writeValue(data) {
        let value;
        if (!isNullOrUndefined(data)) {
            if (isString(data) || isNumber(data)) {
                value = data;
                this.viewOnlyText = '';
            }
            else if (isObject(data)) {
                value = data.value;
                this.viewOnlyText = data.viewOnlyText;
            }
            this.savedValue = value;
            this.inputControl.setValue(value, { emitEvent: false });
        }
        else {
            this.savedValue = '';
            this.inputControl.setValue('', { emitEvent: false });
        }
        this.isEditMode$.next(false);
    }
    /** @internal */
    registerOnChange(fn) {
        this.propagateChange = fn;
    }
    /** @internal */
    registerOnTouched() { }
    /** @internal */
    setDisabledState(isDisabled) {
        const status = isDisabled ? 'disable' : 'enable';
        this.inputControl[status]();
        this.readOnly = this.readOnly || isDisabled;
        this.disable = isDisabled;
    }
    addListeners() {
        this.setEditMode$.pipe(takeUntil(this.onDestroy$)).subscribe(this.setEditMode.bind(this));
        this.isEditMode$
            .asObservable()
            .pipe(takeUntil(this.onDestroy$), filter(val => val))
            .subscribe(this.handleClickOutSideListener.bind(this));
        this.inputControl.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(this.clearErrorOnValueChange.bind(this));
    }
    handleClickOutSideListener(value, $event) {
        if (value && !this.error) {
            this.clickOutSideSubscription = fromEvent(document, 'click').subscribe((event) => {
                const clickedInside = this.isClickInsideByCoordinates(event);
                if (!clickedInside && !this.stayInEditMode) {
                    this.cancel();
                    this.cdr.markForCheck();
                }
            });
        }
        else {
            if (this.clickOutSideSubscription && typeof this.clickOutSideSubscription.unsubscribe === 'function') {
                this.clickOutSideSubscription.unsubscribe();
            }
        }
    }
    isClickInsideByCoordinates(event) {
        const parentRect = this.elementRef.nativeElement.getBoundingClientRect();
        return (parentRect.left <= event.clientX &&
            parentRect.right >= event.clientX &&
            parentRect.top <= event.clientY &&
            parentRect.bottom >= event.clientY);
    }
    setEditMode(val) {
        if (!!val) {
            this.goToEditMode(val);
            this.stayInEditMode = true;
        }
    }
    clearErrorOnValueChange(value) {
        if (!!value && this.error) {
            this.error = '';
        }
    }
    isType(type) {
        return this.type === type;
    }
    static { this.ɵfac = function InputInlineBaseComponent_Factory(t) { return new (t || InputInlineBaseComponent)(i0.ɵɵdirectiveInject(i1.CurrencyPipe), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: InputInlineBaseComponent, viewQuery: function InputInlineBaseComponent_Query(rf, ctx) { if (rf & 1) {
            i0.ɵɵviewQuery(_c0, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputComponent = _t.first);
        } }, hostBindings: function InputInlineBaseComponent_HostBindings(rf, ctx) { if (rf & 1) {
            i0.ɵɵlistener("keydown.enter", function InputInlineBaseComponent_keydown_enter_HostBindingHandler() { return ctx.save(); });
        } }, inputs: { textClass: "textClass", type: "type", loading: "loading", readOnly: "readOnly", error: "error", currencyPipeParameters: "currencyPipeParameters", inputOptions: "inputOptions" }, outputs: { onSave: "onSave", onCancel: "onCancel" }, features: [i0.ɵɵNgOnChangesFeature] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(InputInlineBaseComponent, [{
        type: Directive
    }], () => [{ type: i1.CurrencyPipe }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], { inputComponent: [{
            type: ViewChild,
            args: ['inputComponent']
        }], textClass: [{
            type: Input
        }], type: [{
            type: Input
        }], loading: [{
            type: Input
        }], readOnly: [{
            type: Input
        }], error: [{
            type: Input
        }], currencyPipeParameters: [{
            type: Input
        }], inputOptions: [{
            type: Input
        }], onSave: [{
            type: Output
        }], onCancel: [{
            type: Output
        }], save: [{
            type: HostListener,
            args: ['keydown.enter']
        }] }); })();

/*
 * Created on 2020.4.19 By Andy Kononenko (andyk@ironsrc.com)
 */
const CONFIG_INPUT_INLINE_BY_UI_STYLE = {
    style_v1: {
        iconEdit: { iconName: 'edit', iconVersion: 'v1' },
        iconSave: { iconName: 'check-v-2', iconVersion: 'v1' },
        loadingSize: 'small'
    },
    style_v2: {
        iconEdit: { iconName: 'pen', iconVersion: 'v2' },
        iconSave: { iconName: 'check', iconVersion: 'v2' },
        loadingSize: 'inline'
    },
    style_v3: {
        iconSave: { iconName: 'check-bold', iconVersion: 'v3' },
        iconError: { iconName: 'error', iconVersion: 'v3' },
        loadingSize: 'inline'
    }
};

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

export { CONFIG_INPUT_INLINE_BY_UI_STYLE, InlineInputType, InputInlineBaseComponent };
//# sourceMappingURL=ironsource-fusion-ui-components-input-inline-common-base.mjs.map
