import { __asyncValues, __awaiter, __decorate } from "tslib";
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { LayoutComponentBase, LayoutComponentRendererSADirective, LAYOUT_METADATA_STORAGE } from '@anglr/dynamic/layout';
import { DescendantsGetter, LayoutComponentsIteratorService, LayoutEditorDesignerType, LayoutEditorMetadata } from '@anglr/dynamic/layout-editor';
import { provideRelationsDebugger, RelationsChangeDetector, RelationsComponentManager, RelationsManager, RelationsProcessor, RELATIONS_METADATA_STORAGE } from '@anglr/dynamic/relations';
import { RelationsEditorMetadata } from '@anglr/dynamic/relations-editor';
import { HostDisplayBlockStyle } from '@anglr/common';
import { extend } from '@jscrpt/common';
import { CustomComponentLayoutDesignerTypeLoader, CustomComponentLayoutMetadataLoader, CustomComponentRelationsMetadataLoader } from './customComponent.metadata';
import { ComponentInputsRelations } from '../componentInputs/componentInputs.relations';
import { ComponentOutputsRelations } from '../componentOutputs/componentOutputs.relations';
import { getInputs, getOutputs } from './customComponent.utils';
import { PlaceholderHandler } from '../../services/placeholderHandler/placeholderHandler.service';
import * as i0 from "@angular/core";
/**
 * Component used for displaying custom component
 */
let CustomComponentSAComponent = class CustomComponentSAComponent extends LayoutComponentBase {
    constructor() {
        super(...arguments);
        //######################### protected properties #########################
        /**
         * Storage for layout metadata
         */
        this.layoutMetadataStorage = inject(LAYOUT_METADATA_STORAGE);
        /**
         * Storage for relations metadata
         */
        this.relationsMetadataStorage = inject(RELATIONS_METADATA_STORAGE, { optional: true });
        /**
         * Instance of relations manager
         */
        this.relationsManager = inject(RelationsManager, { optional: true });
        /**
         * Parent relations processor instance
         */
        this.parentRelationsProcessor = inject(RelationsProcessor, { skipSelf: true, optional: true });
        /**
         * Parent relations component manager
         */
        this.parentComponentManager = inject(RelationsComponentManager, { skipSelf: true, optional: true });
        /**
         * Service used for obtaining iterators that goes over all components in metadata
         */
        this.layoutMetadataIterator = inject(LayoutComponentsIteratorService);
        /**
         * Instance of inputs relations if it exists
         */
        this.inputsRelations = null;
        /**
         * Instance of outputs relations if it exists
         */
        this.outputsRelations = null;
        //######################### protected properties - template bindings #########################
        /**
         * Instance of metadata to be displayed
         */
        this.metadata = null;
        //######################### public properties - implementation of RelationsComponent #########################
        /**
         * @inheritdoc
         */
        this.id = '';
    }
    //######################### public methods #########################
    /**
     * Method that allows processing of custom component data
     * @param _name - Name of custom component
     */
    processCustomComponentData(_name) {
    }
    /**
     * @inheritdoc
     */
    setId(id) {
        this.id = id;
    }
    //######################### protected methods - overrides #########################
    /**
     * @inheritdoc
     */
    afterInit() {
        var _a, e_1, _b, _c;
        var _d;
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.options) {
                return;
            }
            //get layout metadata and displays layout
            this.metadata = yield this.layoutMetadataStorage.getMetadata(this.options.name);
            if (this.metadata) {
                const iterator = this.layoutMetadataIterator.getIteratorFor(this.metadata);
                try {
                    for (var _e = true, iterator_1 = __asyncValues(iterator), iterator_1_1; iterator_1_1 = yield iterator_1.next(), _a = iterator_1_1.done, !_a; _e = true) {
                        _c = iterator_1_1.value;
                        _e = false;
                        const itm = _c;
                        const overrideOpts = (_d = this.options.contentOptions) === null || _d === void 0 ? void 0 : _d[itm.metadata.id];
                        //overide options of internal components for custom component from outside
                        if (overrideOpts) {
                            extend(itm.metadata.options, overrideOpts);
                        }
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (!_e && !_a && (_b = iterator_1.return)) yield _b.call(iterator_1);
                    }
                    finally { if (e_1) throw e_1.error; }
                }
            }
            let relations = null;
            //gets and initialize inner relations of custom component
            if (this.relationsManager && this.relationsMetadataStorage) {
                relations = yield this.relationsMetadataStorage.getMetadata(this.options.name);
                this.relationsManager.setRelations(relations !== null && relations !== void 0 ? relations : []);
            }
            //if relations available initialize custom component inputs
            if (relations) {
                const inputsMeta = getInputs(relations);
                if (inputsMeta) {
                    this.inputsRelations = new ComponentInputsRelations(this.injector);
                    this.inputsRelations.initInputs(inputsMeta, inputsMeta.id);
                }
                const outputsMeta = getOutputs(relations);
                if (outputsMeta) {
                    this.outputsRelations = new ComponentOutputsRelations(this.injector);
                    this.outputsRelations.initOutputs(outputsMeta, outputsMeta.id, this);
                }
            }
            //initialize and register relations from outside world to this custom component
            if (this.parentComponentManager && this.parentRelationsProcessor) {
                this.parentComponentManager.registerComponent(this.id, this);
                yield this.parentRelationsProcessor.initialized;
                this.parentRelationsProcessor.updateRelations(this.id);
            }
        });
    }
    /**
     * @inheritdoc
     */
    onChanges(changes) {
        var _a;
        (_a = this.inputsRelations) === null || _a === void 0 ? void 0 : _a.ngOnChanges(changes);
    }
    /**
     * @inheritdoc
     */
    onDestroy() {
        if (!this.parentRelationsProcessor || !this.parentComponentManager) {
            return;
        }
        this.parentRelationsProcessor.destroyComponent(this.id);
        this.parentComponentManager.unregisterComponent(this.id);
    }
};
CustomComponentSAComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: CustomComponentSAComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
CustomComponentSAComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.4", type: CustomComponentSAComponent, isStandalone: true, selector: "custom-component", providers: [
        RelationsComponentManager,
        RelationsManager,
        RelationsProcessor,
        RelationsChangeDetector,
        ...provideRelationsDebugger(),
        LayoutComponentsIteratorService,
        {
            provide: PlaceholderHandler,
            useFactory: () => {
                return new PlaceholderHandler(CustomComponentSAComponent, inject(CustomComponentSAComponent));
            }
        },
    ], usesInheritance: true, ngImport: i0, template: "<ng-container [layoutComponentRenderer]=\"metadata\"></ng-container>", styles: [":host{display: block;}"], dependencies: [{ kind: "directive", type: LayoutComponentRendererSADirective, selector: "[layoutComponentRenderer]", inputs: ["layoutComponentRenderer", "layoutComponentRendererInjector", "layoutComponentRendererDisableTransformer"], outputs: ["layoutComponentRendererComponentChange", "componentElementChange"], exportAs: ["layoutComponentRenderer"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
CustomComponentSAComponent = __decorate([
    DescendantsGetter(options => {
        if (!(options === null || options === void 0 ? void 0 : options.placeholderContainers)) {
            return [];
        }
        const result = [];
        for (const key in options.placeholderContainers) {
            if (options.placeholderContainers[key]) {
                result.push(options.placeholderContainers[key]);
            }
        }
        return result;
    }),
    LayoutEditorDesignerType(CustomComponentLayoutDesignerTypeLoader),
    RelationsEditorMetadata(CustomComponentRelationsMetadataLoader),
    LayoutEditorMetadata(CustomComponentLayoutMetadataLoader)
], CustomComponentSAComponent);
export { CustomComponentSAComponent };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: CustomComponentSAComponent, decorators: [{
            type: Component,
            args: [{ selector: 'custom-component', standalone: true, imports: [
                        LayoutComponentRendererSADirective,
                    ], providers: [
                        RelationsComponentManager,
                        RelationsManager,
                        RelationsProcessor,
                        RelationsChangeDetector,
                        ...provideRelationsDebugger(),
                        LayoutComponentsIteratorService,
                        {
                            provide: PlaceholderHandler,
                            useFactory: () => {
                                return new PlaceholderHandler(CustomComponentSAComponent, inject(CustomComponentSAComponent));
                            }
                        },
                    ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container [layoutComponentRenderer]=\"metadata\"></ng-container>", styles: [":host{display: block;}"] }]
        }] });
//# sourceMappingURL=customComponent.component.js.map