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
     */
    async build(layoutMetadata) {
        const formGroup = new FormGroup({});
        let activeGroup = formGroup;
        for await (const iteratorItem of this._iteratorsSvc.getIteratorFor(layoutMetadata)) {
            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;
                }
            }
        }
        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) {
        if (!metadata) {
            return null;
        }
        return metadata.options?.controlName;
    }
    /**
     * Gets specific control for layout component
     * @param metadata component metadata
     * @returns
     */
    _getControlForMetadata(metadata) {
        switch (metadata?.options?.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