import { Component, OnInit } from '@angular/core';
import { FieldType, FieldTypeConfig, FormlyFieldConfig } from '@ngx-formly/core';
import { FormGroup } from "@angular/forms";
import {DictionaryService} from "./dictionary.service";
import {JSONSchema7} from "json-schema";
import {FormlyJsonschema} from "@ngx-formly/core/json-schema";

@Component({
    selector: 'formly-dictionary-type',
    template: `
        <div class="mb-3">
            <ngb-accordion #acc="ngbAccordion" activeIds="ngb-panel-0">
                <ngb-panel>
                    <ng-template ngbPanelTitle>
                        <label *ngIf="props.label && props['hideLabel'] !== true" [attr.for]="id"
                               class="form-label">{{ props.label }}
                            <span *ngIf="props.required && props['hideRequiredMarker'] !== true" aria-hidden="true">*</span>
                        </label>
                    </ng-template>
                    <ng-template ngbPanelContent>
                        <div class="alert alert-danger" role="alert" *ngIf="showError && formControl.errors">
                            <formly-validation-message [field]="field"></formly-validation-message>
                        </div>
                        <formly-form [model]="parameterModel" [fields]="parameterFields" [form]="parameterForm"></formly-form>
                    </ng-template>
                </ngb-panel>
            </ngb-accordion>
        </div>
    `,
})
export class DictionaryTypeComponent extends FieldType<FieldTypeConfig> implements OnInit
{
    public errorMsg: string = "";

    parameterForm: FormGroup = new FormGroup({});
    parameterList: string[] = [];
    parameterModel: {[field_id: string]: string} = {};
    parameterFields: FormlyFieldConfig[] = [];

    constructor(protected service: DictionaryService,
                private formlyJsonschema: FormlyJsonschema) {
        super();
    }

    ngOnInit() {
        for (const entry of this.formControl.value) {
            this.parameterModel[entry.key] = entry.value;
        }

        this.service.parameters$.subscribe((parameters) => {
            this.parameterList = parameters;
            for (const pname of parameters) {
                if (Object.keys(this.parameterModel).indexOf(pname) == -1) {
                    this.parameterModel[pname] = "";
                }
            }

            this.parameterFields = [this.formlyJsonschema.toFieldConfig(
                this.getFormSchema(parameters)
            )];

            if (Object.keys(this.parameterForm.controls).length) {
                this.parameterForm.setValue(this.parameterModel, {emitEvent: false});
            }
        });

        this.parameterForm.valueChanges.subscribe((values) => {
            this.parameterModel = values;

            const formValue: { key :string, value: string }[] = []
            for (const [key, value] of Object.entries(this.parameterModel)) {
                formValue.push({key, value});
            }
            this.formControl.setValue(formValue)
        })

        this.formControl.valueChanges.subscribe((values) => {
            for (const entry of values) {
                this.parameterModel[entry.key] = entry.value;
            }
        })
    }

    getFormSchema(properties: string[]) {
        const schema: JSONSchema7 = {
            type: "object",
            properties: {
            },
        };
        let required: string[] = []
        for (const pname of properties) {
            schema.properties![pname] = {
                type: "string",
                title: pname
            }
            if (this.field.props.required) {
                required.push(pname)
            }
        }
        schema.required = required

        return schema
    }
}
