import { EventEmitter, Component, ChangeDetectionStrategy, ChangeDetectorRef, Input, Output, ContentChild, ViewChild, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { SdTranslateModule } from '@sd-angular/core/translate';
import { NgForm, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SdFormControl, SdLabelDefDirective, SdCommonModule } from '@sd-angular/core/common';
import { MatButtonModule } from '@angular/material/button';
import { __classPrivateFieldGet, __classPrivateFieldSet } from 'tslib';
import { v4 } from 'uuid';
import { debounceTime, startWith } from 'rxjs/operators';
import { Subject, Subscription } from 'rxjs';
import JSONEditor from 'jsoneditor';

var _name, _form, _model, _container, _containerLoaded, _subscription, _reload, _onChange, _updateJson;
class SdJsonEditor {
    constructor(ref) {
        this.ref = ref;
        this.id = `I${v4()}`;
        _name.set(this, v4());
        this.height = '400px';
        _form.set(this, void 0);
        _model.set(this, void 0);
        this.modelChange = new EventEmitter();
        // Validator
        this.isRequired = false;
        this.sdChange = new EventEmitter();
        _container.set(this, void 0);
        _containerLoaded.set(this, new Subject());
        this.formControl = new SdFormControl();
        _subscription.set(this, new Subscription());
        _reload.set(this, () => {
            var _a;
            if (!__classPrivateFieldGet(this, _container)) {
                return;
            }
            const container = document.getElementById(this.id);
            const option = {
                mode: this.formControl.disabled ? 'view' : 'tree',
                modes: ['tree', 'form', 'text', 'view'],
                onChange: () => {
                    const text = this.editor.getText();
                    if (!text) {
                        this.editor.set(null);
                        __classPrivateFieldSet(this, _model, null);
                        this.formControl.setValue(__classPrivateFieldGet(this, _model));
                    }
                    else {
                        __classPrivateFieldSet(this, _model, this.editor.get());
                        this.formControl.setValue(__classPrivateFieldGet(this, _model));
                    }
                },
            };
            this.editor = new JSONEditor(container, option);
            __classPrivateFieldGet(this, _updateJson).call(this);
            __classPrivateFieldGet(this, _subscription).add(this.formControl.valueChanges.pipe(debounceTime(100)).subscribe(__classPrivateFieldGet(this, _onChange)));
            (_a = __classPrivateFieldGet(this, _form)) === null || _a === void 0 ? void 0 : _a.addControl(__classPrivateFieldGet(this, _name), this.formControl);
        });
        this.reValidate = () => {
            this.formControl.updateValueAndValidity();
        };
        _onChange.set(this, (value) => {
            this.modelChange.emit(value);
            this.sdChange.emit(value);
        });
        _updateJson.set(this, () => {
            var _a, _b;
            (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.set) === null || _b === void 0 ? void 0 : _b.call(_a, this.formControl.value);
        });
    }
    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 model(value) {
        if (__classPrivateFieldGet(this, _model) !== value) {
            __classPrivateFieldSet(this, _model, value);
            this.formControl.setValue(__classPrivateFieldGet(this, _model), {
                emitEvent: false
            });
            __classPrivateFieldGet(this, _updateJson).call(this);
        }
    }
    set required(val) {
        this.isRequired = (val === '') || val;
        // this.#updateValidator();
    }
    // Optional
    set disabled(val) {
        val = (val === '') || val;
        if (val) {
            this.formControl.disable();
        }
        else {
            this.formControl.enable();
        }
    }
    set container(container) {
        __classPrivateFieldSet(this, _container, container);
        __classPrivateFieldGet(this, _containerLoaded).next(container);
    }
    ngOnInit() {
        __classPrivateFieldGet(this, _subscription).add(this.formControl.sdChanges.subscribe(() => {
            this.ref.markForCheck();
        }));
    }
    ngAfterViewInit() {
        __classPrivateFieldGet(this, _subscription).add(__classPrivateFieldGet(this, _containerLoaded).pipe(startWith(__classPrivateFieldGet(this, _container))).subscribe(() => {
            __classPrivateFieldGet(this, _reload).call(this);
        }));
    }
    ngOnDestroy() {
        var _a;
        (_a = __classPrivateFieldGet(this, _form)) === null || _a === void 0 ? void 0 : _a.removeControl(__classPrivateFieldGet(this, _name));
        __classPrivateFieldGet(this, _subscription).unsubscribe();
    }
}
_name = new WeakMap(), _form = new WeakMap(), _model = new WeakMap(), _container = new WeakMap(), _containerLoaded = new WeakMap(), _subscription = new WeakMap(), _reload = new WeakMap(), _onChange = new WeakMap(), _updateJson = new WeakMap();
SdJsonEditor.decorators = [
    { type: Component, args: [{
                selector: 'sd-json-editor',
                template: "<ng-container *ngIf=\"sdLabelDef?.templateRef\">\r\n  <ng-container *ngTemplateOutlet=\"sdLabelDef.templateRef\">\r\n  </ng-container>\r\n</ng-container>\r\n<label *ngIf=\"label&&!sdLabelDef?.templateRef\" class=\"d-block T14M\">{{label}} <span class=\"text-danger mb-2\" *ngIf=\"required\">*</span></label>\r\n<div [id]=\"id\" [style.height]=\"height\" #container></div>\r\n",
                changeDetection: ChangeDetectionStrategy.OnPush,
                styles: [""]
            },] }
];
SdJsonEditor.ctorParameters = () => [
    { type: ChangeDetectorRef }
];
SdJsonEditor.propDecorators = {
    name: [{ type: Input }],
    height: [{ type: Input }],
    form: [{ type: Input }],
    label: [{ type: Input }],
    model: [{ type: Input }],
    modelChange: [{ type: Output }],
    required: [{ type: Input }],
    disabled: [{ type: Input }],
    tooltip: [{ type: Input }],
    sdChange: [{ type: Output }],
    sdLabelDef: [{ type: ContentChild, args: [SdLabelDefDirective,] }],
    container: [{ type: ViewChild, args: ['container',] }]
};

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

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

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

export { SdJsonEditor, SdJsonEditorModule };
//# sourceMappingURL=sd-angular-core-json-editor.js.map
