import { __awaiter, __decorate, __metadata } from "tslib";
import { Injector } from '@angular/core';
import { defineAssignedProp, defineSkipInitProp, RelationsChangeDetector, RelationsComponentManager, RelationsProcessor } from '@anglr/dynamic/relations';
import { RelationsEditorMetadata } from '@anglr/dynamic/relations-editor';
import { Subject } from 'rxjs';
import { ComponentOutputsRelationsMetadataLoader } from './componentOutputs.metadata';
/**
 * Relations used for connecting relations outputs with external relations
 */
let ComponentOutputsRelations = class ComponentOutputsRelations {
    //######################### constructor #########################
    constructor(injector) {
        this.injector = injector;
        //######################### protected properties #########################
        /**
         * Relations processor instance
         */
        this.relationsProcessor = this.injector.get(RelationsProcessor, null);
        /**
         * Relations component manager
         */
        this.componentManager = this.injector.get(RelationsComponentManager, null);
        /**
         * Id of component outputs relations
         */
        this.id = '';
    }
    //######################### public methods - implementation of RelationsComponent #########################
    /**
     * @inheritdoc
     */
    ngOnChanges(changes) {
        for (const key of Object.keys(changes)) {
            this.customComponent[key] = changes[key].currentValue;
        }
    }
    /**
     * @inheritdoc
     */
    invalidateVisuals() {
    }
    //######################### public methods - implementation of OnDestroy #########################
    /**
     * @inheritdoc
     */
    ngOnDestroy() {
        var _a, _b;
        if (this.id) {
            (_a = this.relationsProcessor) === null || _a === void 0 ? void 0 : _a.destroyComponent(this.id);
            (_b = this.componentManager) === null || _b === void 0 ? void 0 : _b.unregisterComponent(this.id);
        }
    }
    //######################### public methods #########################
    /**
     * Initialize outputs for component
     * @param outputRelations - Output relations metadata
     * @param id - Id of output relations
     */
    initOutputs(outputRelations, id, customComponent) {
        var _a, _b;
        return __awaiter(this, void 0, void 0, function* () {
            this.id = id;
            this.customComponent = customComponent;
            if (!this.componentManager || !this.relationsProcessor) {
                return;
            }
            for (const output of (_b = (_a = outputRelations.relationsOptions) === null || _a === void 0 ? void 0 : _a.outputs) !== null && _b !== void 0 ? _b : []) {
                Object.defineProperty(this.customComponent, output.name, {
                    get: function () {
                        return this[`ɵ${output.name}`];
                    },
                    set: function (value) {
                        this[`ɵ${output.name}`] = value;
                        defineAssignedProp(this, output.name);
                        const injector = this.ɵɵinjector;
                        if (!injector) {
                            return;
                        }
                        const componentManager = injector.get(RelationsComponentManager);
                        const changeDetector = injector.get(RelationsChangeDetector);
                        const id = componentManager.getId(this);
                        if (!id) {
                            return;
                        }
                        changeDetector.markForCheck({
                            componentId: id,
                            outputName: output.name,
                        });
                    }
                });
                Object.defineProperty(this.customComponent, `${output.name}Change`, {
                    value: new Subject()
                });
                //sets initial value
                if (output.defaultValue !== undefined) {
                    this[output.name] = output.defaultValue;
                }
                if (output.skipInit) {
                    defineSkipInitProp(this.customComponent, output.name);
                }
            }
            this.componentManager.registerComponent(this.id, this);
            yield this.relationsProcessor.initialized;
            this.relationsProcessor.updateRelations(this.id);
        });
    }
};
ComponentOutputsRelations = __decorate([
    RelationsEditorMetadata(ComponentOutputsRelationsMetadataLoader),
    __metadata("design:paramtypes", [Injector])
], ComponentOutputsRelations);
export { ComponentOutputsRelations };
//# sourceMappingURL=componentOutputs.relations.js.map