<form [formGroup]="form">

    @for (f of config.fields; track f) {

    <ng-container *ngIf="f.type !== 'array' && f.type !== 'hidden'">
        @if (f.type === 'text') {
        <mat-form-field appearance="outline" class="full-width">
            <mat-label>{{ f.label }}</mat-label>
            <input matInput [id]="f.name" [formControlName]="f.name" />
            <mat-hint *ngIf="f.placeholder">{{ f.placeholder }}</mat-hint>
            <mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
                This field is required.
            </mat-error>
        </mat-form-field>
        }

        @if (f.type === 'textarea') {
        <mat-form-field appearance="outline" class="full-width">
            <mat-label>{{ f.label }}</mat-label>
            <textarea matInput [id]="f.name" cdkTextareaAutosize cdkAutosizeMinRows="3" cdkAutosizeMaxRows="6" [formControlName]="f.name"></textarea>
            <mat-hint *ngIf="f.placeholder">{{ f.placeholder }}</mat-hint>
            <mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
                This field is required.
            </mat-error>
        </mat-form-field>
        }

        @if (f.type === 'number') {
        <mat-form-field appearance="outline" class="full-width">
            <mat-label>{{ f.label }}</mat-label>
            <input matInput [id]="f.name" type="number" [formControlName]="f.name" />
            <mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
                Please enter a valid number.
            </mat-error>
        </mat-form-field>
        }

        @if (f.type === 'select') {
        <mat-form-field appearance="outline" class="full-width">
            <mat-label>{{ f.label }}</mat-label>
            <mat-select [id]="f.name" [formControlName]="f.name">
                @for (opt of f.options; track opt) {
                <mat-option [value]="opt.value">{{ opt.label }}</mat-option>
                }
            </mat-select>
            <mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
                Please select a value.
            </mat-error>
        </mat-form-field>
        }

        @if (f.type === 'year') {
        <mat-form-field appearance="outline" class="full-width">
            <mat-label>{{ f.label }}</mat-label>
            <mat-select [id]="f.name" [formControlName]="f.name" [compareWith]="compareYearValues">
                @if (f.yearRange?.allowPresent) {
                <mat-option value="Present">Present</mat-option>
                }
                @for (yr of getYearOptions(f); track yr) {
                <mat-option [value]="yr">{{ yr }}</mat-option>
                }
            </mat-select>
            <mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
                Please select a year.
            </mat-error>
        </mat-form-field>
        }

        @if (f.type === 'date') {
        <mat-form-field appearance="outline" class="full-width">
            <mat-label>{{ f.label }}</mat-label>
            <input matInput [matDatepicker]="picker" [id]="f.name" [formControlName]="f.name" [placeholder]="f.placeholder || ''" />
            <mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
            <mat-datepicker #picker></mat-datepicker>
            <mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
                Please select a date.
            </mat-error>
        </mat-form-field>
        }

        @if (f.type === 'file') {
        <div>
            <label [for]="f.name">{{ f.label }}</label>
            <input [id]="f.name" type="file" (change)="onFileChange($event, f.name)" />
        </div>
        }
    </ng-container>

    <ng-container *ngIf="f.type === 'array'">
        <div>
            <h3>{{ f.label }}</h3>
            <div [formArrayName]="f.name">
                @for (item of getArrayControls(f.name); track item; let i = $index) {
                <div [formGroupName]="i" class="array-item">
                    <div class="array-item-fields">
                    @for (sub of f.itemConfig; track sub) {
                    @if (sub.type !== 'hidden') {
                    @if (sub.type === 'date') {
                    <mat-form-field appearance="outline" class="full-width">
                        <mat-label>{{ sub.label }}</mat-label>
                        <input matInput [matDatepicker]="subPicker" [id]="sub.name + '_' + i" [formControlName]="sub.name" [placeholder]="sub.placeholder || ''" />
                        <mat-datepicker-toggle matIconSuffix [for]="subPicker"></mat-datepicker-toggle>
                        <mat-datepicker #subPicker></mat-datepicker>
                    </mat-form-field>
                    } @else if (sub.type === 'year') {
                    <mat-form-field appearance="outline" class="full-width">
                        <mat-label>{{ sub.label }}</mat-label>
                        <mat-select [id]="sub.name + '_' + i" [formControlName]="sub.name" [compareWith]="compareYearValues">
                            @if (sub.yearRange?.allowPresent) {
                            <mat-option value="Present">Present</mat-option>
                            }
                            @for (yr of getYearOptions(sub); track yr) {
                            <mat-option [value]="yr">{{ yr }}</mat-option>
                            }
                        </mat-select>
                    </mat-form-field>
                    } @else {
                    <mat-form-field appearance="outline" class="full-width">
                        <mat-label>{{ sub.label }}</mat-label>
                        <input matInput [id]="sub.name + '_' + i" [formControlName]="sub.name" [placeholder]="sub.placeholder || ''" />
                    </mat-form-field>
                    }
                    }
                    }
                    </div>
                    <div class="array-item-actions">
                        <button type="button" class="remove-link" (click)="removeArrayItem(f, i)">
                            <i class="fa-solid fa-trash-can"></i> Remove
                        </button>
                    </div>
                </div>
                }
            </div>
            <button type="button" class="add-btn" (click)="addArrayItem(f)">
                <i class="fa-solid fa-plus"></i> Add Item
            </button>
        </div>
    </ng-container>
    }

</form>