import { __asyncValues, __awaiter } from "tslib";
import { Injectable } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
import { LayoutComponentsIteratorService } from '@anglr/dynamic/layout-editor';
import { FormComponentControlType } from '../../misc/enums';
import * as i0 from "@angular/core";
import * as i1 from "@anglr/dynamic/layout-editor";
export class FormComponentControlBuilder {
    //######################### constructor #########################
    constructor(_iteratorsSvc) {
        this._iteratorsSvc = _iteratorsSvc;
    }
    //######################### public methods #########################
    /**
     * Build form group from layout metadata
     * @param layoutMetadata
     * @returns
     */
    build(layoutMetadata) {
        var _a, e_1, _b, _c;
        return __awaiter(this, void 0, void 0, function* () {
            const formGroup = new FormGroup({});
            let activeGroup = formGroup;
            try {
                for (var _d = true, _e = __asyncValues(this._iteratorsSvc.getIteratorFor(layoutMetadata)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
                    _c = _f.value;
                    _d = false;
                    const iteratorItem = _c;
                    const controlName = this._getControlName(iteratorItem.metadata);
                    if (controlName) {
                        const control = this._getControlForMetadata(iteratorItem.metadata);
                        this._getActiveGroup(iteratorItem.parent, activeGroup).addControl(controlName, control);
                        if (control instanceof FormGroup) {
                            activeGroup = control;
                        }
                    }
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
                }
                finally { if (e_1) throw e_1.error; }
            }
            return formGroup;
        });
    }
    //######################### private methods #########################
    /**
     * Get active form group for specific layout component
     * @param parentIterator parent layout component iterator item
     * @param group active form group
     * @returns
     */
    _getActiveGroup(parentIterator, group) {
        //Already on root FormGroup
        if (!group.parent ||
            !parentIterator) {
            return group;
        }
        const parentControlName = this._getControlName(parentIterator.metadata);
        //Parent component is of Form Component control type
        if (parentControlName) {
            //Current group is parent component
            if (group.parent.get(parentControlName)) {
                return group;
            }
            //We have to find parent form group
            else {
                return this._getActiveGroup(parentIterator, group.parent);
            }
        }
        else if (!parentIterator.parent) {
            return this._getActiveGroup(parentIterator.parent, group.root);
        }
        //Parent component is not of Form Component control type
        return this._getActiveGroup(parentIterator.parent, group);
    }
    /**
     * Gets component control name
     * @param metadata component metadata
     * @returns
     */
    _getControlName(metadata) {
        var _a;
        if (!metadata) {
            return null;
        }
        return (_a = metadata.options) === null || _a === void 0 ? void 0 : _a.controlName;
    }
    /**
     * Gets specific control for layout component
     * @param metadata component metadata
     * @returns
     */
    _getControlForMetadata(metadata) {
        var _a;
        switch ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.options) === null || _a === void 0 ? void 0 : _a.controlType) {
            case FormComponentControlType.FormArray:
                return new FormArray([]);
            case FormComponentControlType.FormGroup:
                return new FormGroup({});
            default:
                return new FormControl();
        }
    }
}
FormComponentControlBuilder.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: FormComponentControlBuilder, deps: [{ token: i1.LayoutComponentsIteratorService }], target: i0.ɵɵFactoryTarget.Injectable });
FormComponentControlBuilder.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: FormComponentControlBuilder });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: FormComponentControlBuilder, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.LayoutComponentsIteratorService }] });
//# sourceMappingURL=formComponentControlBuilder.service.js.map