import {Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
import {AbstractControl, FormArray, FormControl, FormGroup} from '@angular/forms';
import {FieldEditorModel} from '../../../admin/field-editor-model';
import {Guid} from '@common/types/guid';
import {RuleEditorModel} from '../../../admin/rule-editor-model';
import {ValidationType} from '@app/core/common/enum/validation-type';
import {MatCheckboxChange} from '@angular/material/checkbox';
import {
	DatasetDescriptionCompositeFieldEditorModel,
	DatasetDescriptionFieldEditorModel,
	DatasetDescriptionSectionEditorModel
} from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
import {DatasetProfileFieldViewStyle} from '@app/core/common/enum/dataset-profile-field-view-style';
import {MatDialog} from '@angular/material/dialog';
import {ConfirmationDialogComponent} from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import {TranslateService} from '@ngx-translate/core';
import {ViewStyleType} from '../field/view-style-enum';
import {EnumUtils} from '@app/core/services/utilities/enum-utils.service';
import {DatasetProfileService} from '@app/core/services/dataset-profile/dataset-profile.service';
import {EditorCustomValidators} from '../../custom-validators/editor-custom-validators';
import {Field, FieldSet} from '@app/core/model/admin/dataset-profile/dataset-profile';
import {DatasetProfileComboBoxType} from '@app/core/common/enum/dataset-profile-combo-box-type';
import {DatasetProfileInternalDmpEntitiesType} from '@app/core/common/enum/dataset-profile-internal-dmp-entities-type';
import {
	AutoCompleteFieldData,
	BooleanDecisionFieldData,
	CheckBoxFieldData,
	CurrencyFieldData,
	DataRepositoriesFieldData,
	DatasetIdentifierFieldData,
	DatePickerFieldData,
	DmpsAutoCompleteFieldData,
	ExternalDatasetsFieldData,
	FieldDataOption,
	FreeTextFieldData,
	OrganizationsFieldData,
	RadioBoxFieldData,
	RegistriesFieldData,
	ResearchersAutoCompleteFieldData,
	ServicesFieldData,
	TagsFieldData,
	TextAreaFieldData,
	RichTextAreaFieldData,
	UploadFieldData,
	ValidationFieldData,
	WordListFieldData,
	TaxonomiesFieldData,
	LicensesFieldData,
	PublicationsFieldData
} from '@app/core/model/dataset-profile-definition/field-data/field-data';
import {CompositeField} from '@app/core/model/dataset-profile-definition/composite-field';
import {Field as FieldDefinition} from '@app/core/model/dataset-profile-definition/field';
import {Subject} from 'rxjs';
import {debounceTime, delay, map, takeUntil, tap} from 'rxjs/operators';
import {GENERAL_ANIMATIONS} from '../../animations/animations';
import {BaseComponent} from '@common/base/base.component';
import {TransitionGroupComponent} from "@app/ui/transition-group/transition-group.component";
import {ConfigurationService} from "@app/core/services/configuration/configuration.service";

@Component({
	selector: 'app-dataset-profile-editor-composite-field-component',
	templateUrl: './dataset-profile-editor-composite-field.component.html',
	styleUrls: ['./dataset-profile-editor-composite-field.component.scss'],
	animations:[GENERAL_ANIMATIONS]
})
export class DatasetProfileEditorCompositeFieldComponent extends BaseComponent implements OnInit, OnChanges {

	@Input() form: FormGroup;
	@Input() indexPath: string;
	@Input() viewOnly: boolean;

	@Input() numbering: string;
	@Input() hasFocus: boolean = false;
	@ViewChild("inputs") inputs: TransitionGroupComponent;

	showPreview: boolean  = true;
	previewDirty: boolean = false;


	showDescription: boolean = true;
	showAdditionalInfo: boolean = false;
	showExtendedDescription: boolean = false;

	previewForm: FormGroup = null;
	// isComposite = false;
	// isMultiplicityEnabled = false;
	viewStyleEnum = DatasetProfileFieldViewStyle;

	viewTypeEnum =  ViewStyleType;

	private myCustomValidators:EditorCustomValidators = new EditorCustomValidators();

	isMultiplicityEnabled = false;
	constructor(
		private dialog: MatDialog,
		private language: TranslateService,
		public enumUtils: EnumUtils,
		public datasetProfileService: DatasetProfileService,
		private configurationService: ConfigurationService
	) {
			super();
		}

	ngOnChanges(changes: SimpleChanges){
		// this.setTargetField(null);
		// this.showExtendedDescription = !!this.form.get('extendedDescription').value;
		// this.showAdditionalInfo = !!this.form.get('additionalInformation').value;
		// console.log(this.form.get('fields')['controls'])
		if( changes['form']){

			try{
				const multiplicity = this.form.get('multiplicity').value;
				this.isMultiplicityEnabled = multiplicity.min > 0 || multiplicity.max >0;
			} catch{
				this.isMultiplicityEnabled = false;
			}
		}

	}

	get firstField(){
		try{
			return (this.form.get('fields') as FormArray).at(0);
		}catch{
			return null;
		}
	}




	ngOnInit() {
		//this.addNewField();
		// if (this.form.get('multiplicity')) {
		// 	if (this.form.get('multiplicity').value.min > 1 || this.form.get('multiplicity').value.max > 1) {
		// 		this.isMultiplicityEnabled = true;
		// 	}
		// }
		// this.isComposite = (this.form.get('fields') as FormArray).length > 1;

		if (this.viewOnly) {
			this.form.get('hasCommentField').disable();
		}

		//SET UP TARGET FIELD
		// if((this.form.get('fields') as FormArray).length>0){
		// 	//get the first field in list
		// 	this.targetField = (this.form.get('fields') as FormArray).at(0) as FormGroup;
		// }

		this.showExtendedDescription = !!this.form.get('extendedDescription').value;
		this.showAdditionalInfo = !!this.form.get('additionalInformation').value;

		this.form.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(changes=>{
			// this.previewForm = null;
			this.previewDirty = true;
			this.generatePreviewForm();

		});
		this.previewSubject$
		.pipe(debounceTime(600))
		.pipe(
			takeUntil(this._destroyed),
			map(model => model.buildForm()),
			map(updatedForm =>{
				const previewContainer = document.getElementById('preview_container'+ this.form.get('id').value);
				// let clientHeight = -1;
				if(previewContainer){
					// console.log(previewContainer);
					const clientHeight = previewContainer.clientHeight;
					// console.log(clientHeight);

					if(clientHeight){
						previewContainer.style.height = clientHeight.toString() + 'px';

						// console.log('height:' ,previewContainer.style.height);
					}
				}
				this.showPreview = false;
				this.previewDirty = true;
				this.previewForm = updatedForm;
				return previewContainer;
				}),
			delay(100),
			tap( previewContainer =>{
				this.showPreview = true;
				this.previewDirty = false;
			}),
			delay(100)
		)
		.subscribe(previewContainer=>{

			if(previewContainer){
				previewContainer.style.height = 'auto';
			}

			// const updatedForm = model.buildForm();
			// this.reloadPreview(updatedForm)
		});


		this.generatePreviewForm();
	}


	get updatedClass(){
		if(this.previewDirty) return '';
		else return 'updated';
	}
	private reloadPreview(updatedForm: FormGroup){
		setTimeout(() => {

			const previewContainer = document.getElementById('preview_container'+ this.form.get('id').value);
			// let clientHeight = -1;
			if(previewContainer){
				// console.log(previewContainer);
				const clientHeight = previewContainer.clientHeight;
				// console.log(clientHeight);

				if(clientHeight){
					previewContainer.style.height = clientHeight.toString() + 'px';

					// console.log('height:' ,previewContainer.style.height);
				}
			}
			this.showPreview = false;
			this.previewDirty = true;
			this.previewForm = updatedForm;

			setTimeout(() => {


				this.showPreview = true;
				this.previewDirty = false;

				if(previewContainer){
					setTimeout(() => {
						if(previewContainer){
							previewContainer.style.height = 'auto';
						}
					});
				}
			});
		});
	}

	previewSubject$: Subject<DatasetDescriptionSectionEditorModel> = new Subject<DatasetDescriptionSectionEditorModel>();

	private generatePreviewForm(){
		const formValue:FieldSet = this.form.getRawValue();
			const fields:FieldDefinition[] = formValue.fields.map(editorField=>this._fieldToFieldDefinition(editorField));


			const compositeField: CompositeField = {
				id: formValue.id,
				additionalInformation: formValue.additionalInformation,
				extendedDescription: formValue.extendedDescription,
				numbering:'',
				title: formValue.title,
				ordinal: formValue.ordinal,
				description: formValue.description,
				hasCommentField: formValue.hasCommentField,
				commentFieldValue: '',
				multiplicity: {max: formValue.multiplicity.max, min: formValue.multiplicity.min, placeholder: formValue.multiplicity.placeholder},
				multiplicityItems:null,
				fields: fields.map(editorField=>{
					const model = new DatasetDescriptionFieldEditorModel().fromModel(editorField);
					if(model.viewStyle.renderStyle === this.viewStyleEnum.CheckBox){
						model.value  = model.value?"true":"false";//patch
					}
					return  model;
				})
			}


			const section = new  DatasetDescriptionSectionEditorModel();
			section.title = '';
			section.numbering = '';

			const compositeForm = new DatasetDescriptionCompositeFieldEditorModel().fromModel(compositeField)
			section.compositeFields = [compositeForm];

			this.previewSubject$.next(section);
	}


	private _fieldToFieldDefinition(editorField: Field): FieldDefinition{
		const field = {
			id: editorField.id,
			title: '',
			page: editorField.page,
			numbering:'',
			multiplicity:null,
			multiplicityItems: null,
			viewStyle: editorField.viewStyle,
			defaultValue:editorField.defaultValue,
			value: null,
			validations: editorField.validations,
		} as FieldDefinition;

		field.data = editorField.data;

		// return new DatasetDescriptionFieldEditorModel().fromModel(field);
		return field;
	}


	// generatePreview(){
	// 	const editorModel = new DatasetDescriptionCompositeFieldEditorModel();
	// 	editorModel.title = this.form.get('title').value;
	// 	editorModel.description = this.form.get('description').value;
	// 	editorModel.extendedDescription = this.form.get('extendedDescription').value;
	// 	editorModel.additionalInformation = this.form.get('additionalInformation').value;
	// 	editorModel.hasCommentField = this.form.get('hasCommentField').value;
	// 	editorModel.fields = [];

	// 	(this.form.get('fields') as FormArray).controls.forEach(field=>{
	// 		const fieldEditorModel = new DatasetDescriptionFieldEditorModel();

	// 		fieldEditorModel.viewStyle= {
	// 				renderStyle: field.get('viewStyle').get('renderStyle').value,
	// 				cssClass: null
	// 			};
	// 		fieldEditorModel.defaultValue = field.get('defaultValue').value;
	// 		switch (field.get('viewStyle').get('renderStyle').value) {
	// 			case DatasetProfileFieldViewStyle.TextArea:
	// 				fieldEditorModel.data = {
	// 					label: field.get('data').get('label').value
	// 				};
	// 				break;

	// 			default:
	// 				break;
	// 		}


	// 		editorModel.fields.push(fieldEditorModel);
	// 	});


	// 	this.previewForm = editorModel.buildForm();
	// }

	onIsCompositeChange(isComposite: boolean) {
		if (!isComposite && (<FormArray>this.form.get('fields')).length > 1) {
			for (let i = 0; i < (<FormArray>this.form.get('fields')).length - 1; i++) {
				(<FormArray>this.form.get('fields')).removeAt(1);
			}
			(this.form.get('fields') as FormArray).controls.splice(1);
		}
		if ((<FormArray>this.form.get('fields')).length === 0) {
			const field: FieldEditorModel = new FieldEditorModel();
			(<FormArray>this.form.get('fields')).push(field.buildForm());
		}
	}

	onIsMultiplicityEnabledChange(isMultiplicityEnabled: MatCheckboxChange) {
		const multiplicity = this.form.get('multiplicity') as FormGroup;

		const minControl = multiplicity.get('min');
		const maxControl = multiplicity.get('max');

		if (isMultiplicityEnabled.checked) {
			minControl.setValue(0);
			maxControl.setValue(1);
		}else{
			minControl.setValue(0);
			maxControl.setValue(0);
		}

		this.isMultiplicityEnabled = isMultiplicityEnabled.checked;
		minControl.updateValueAndValidity();
		maxControl.updateValueAndValidity();

	}

	addNewField() {
		const field: FieldEditorModel = new FieldEditorModel();
		field.id=Guid.create().toString();

		field.ordinal = (this.form.get('fields') as FormArray).length;

		const fieldForm = field.buildForm();
		// fieldForm.setValidators(this.customFieldValidator());

		// fieldForm.get('viewStyle').get('renderStyle').setValidators(Validators.required);

		(<FormArray>this.form.get('fields')).push(fieldForm);

		this.setTargetField(fieldForm);
		fieldForm.updateValueAndValidity();
	}

	DeleteField(index) {

		const fieldsForm = <FormArray>this.form.get('fields');
		fieldsForm.removeAt(index);
		this.inputs.init();
		// calculate ordinals
		fieldsForm.controls.forEach((field, idx)=>{
			field.get('ordinal').setValue(idx);
			field.updateValueAndValidity();
		});
		this.form.markAsDirty();//deactivate guard
	}

	getFieldTile(formGroup: FormGroup, index: number) {
		if (formGroup.get('title') && formGroup.get('title').value && formGroup.get('title').value.length > 0) { return formGroup.get('title').value; }
		return "Field " + (index + 1);
	}


	targetField:FormGroup;
	validationTypeEnum = ValidationType;


	addVisibilityRule(targetField: FormGroup){
		const rule: RuleEditorModel = new RuleEditorModel();
		(<FormArray>targetField.get('visible').get('rules')).push(rule.buildForm());
	}
	toggleRequired(targetField: FormGroup, event:MatCheckboxChange){

		let validationsControl = targetField.get('validations') as FormControl;
		let validations: Array<ValidationType> = validationsControl.value;

		if(event.checked){
			if(!validations.includes(ValidationType.Required)){//IS ALREADY REQUIRED
				// validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
				// validationsControl.updateValueAndValidity();
				validations.push(ValidationType.Required);
				// validationsControl.setValue(validations);
				validationsControl.updateValueAndValidity();
			}
		}else{
			validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
			validationsControl.updateValueAndValidity();
		}


		// if(validations.includes(ValidationType.Required)){//IS ALREADY REQUIRED
		// 	validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
		// 	validationsControl.updateValueAndValidity();
		// }else{
		// 	//SET REQUIRED VALIDATOR
		// 	console.log('setting required validator');
		// 	validations.push(ValidationType.Required);
		// 	validationsControl.setValue(validations);
		// 	validationsControl.updateValueAndValidity();
		// }
	}
	setTargetField(field:AbstractControl){
		this.targetField = <FormGroup>field;
	}


	deleteTargetField(){

		const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
			restoreFocus: false,
			data: {
				message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
				confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
				cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
				isDeleteConfirmation: true
			}
		});
		dialogRef.afterClosed().subscribe(result => {
			if (result) {
				this._deleteTargetField();
			}
		});

	}


	private _deleteTargetField(){
		if(!this.targetField) return;

		let index = -1;

		const fields = this.form.get('fields') as FormArray;

		for(let i=0;i< fields.length; i++){
			let field = fields.at(i);
			if(field.get('id').value === this.targetField.get('id').value){//index found
				index = i;
				break;
			}
		}

		if(index>=0){//target found in fields
			this.DeleteField(index);
			this.targetField = null;
		}

	}

	deleteField(index: number){

		const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
			restoreFocus: false,
			data: {
				message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
				confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
				cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
				isDeleteConfirmation: true
			}
		});
		dialogRef.afterClosed().subscribe(result => {
			if (result) {
				this.DeleteField(index);
			}
		});

	}




	addNewInput(type: ViewStyleType){

		const fieldsArray = this.form.get('fields') as FormArray;

		let targetOrdinal = fieldsArray.length;
		try{
			targetOrdinal = fieldsArray.controls.map(control=> control.get('ordinal').value).reduce((a,b)=>Math.max(a,b)) +1;
		}catch{

		}



		const field = {
			id: Guid.create().toString(),
			ordinal: targetOrdinal,
			visible:{rules:[],style:null},
			validations:[],
			viewStyle:{},
			export: true

		} as Field;


		// const field: FieldEditorModel = new FieldEditorModel();
		// field.id=Guid.create().toString();

		// field.ordinal = (this.form.get('fields') as FormArray).length;

		// const fieldForm = field.buildForm();
		// fieldForm.setValidators(this.customFieldValidator());
		// fieldForm.get('viewStyle').get('renderStyle').setValidators(Validators.required);



		// if (fieldForm.get('data')) {
		// 	fieldForm.removeControl('data');
		// }

		switch (type) {
			case this.viewTypeEnum.BooleanDecision:{
				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.BooleanDecision)
				// fieldForm.addControl('data', new BooleanDecisionFieldDataEditorModel().buildForm());

				const data: BooleanDecisionFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.BooleanDecision;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.CheckBox:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.CheckBox)
				// fieldForm.addControl('data', new CheckBoxFieldDataEditorModel().buildForm());
				const data: CheckBoxFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.CheckBox;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Select:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.ComboBox)
				// fieldForm.addControl('data', new WordListFieldDataEditorModel().buildForm());

				// fieldForm.get('data').setValidators(EditorCustomValidators.atLeastOneElementListValidator('options'));
				// fieldForm.get('data').updateValueAndValidity();

				const firstOption = {label:'', value:''} as FieldDataOption;

				const data:WordListFieldData = {
					label:'',
					multiList:false,
					options:[firstOption],
					type:DatasetProfileComboBoxType.WordList
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.ComboBox;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Other:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.ComboBox)
				// fieldForm.addControl('data', new AutoCompleteFieldDataEditorModel().buildForm()); //TODO SEE

				// fieldForm.get('data').setValidators(EditorCustomValidators.atLeastOneElementListValidator('autoCompleteSingleDataList'));
				// fieldForm.get('data').updateValueAndValidity();

				const data: AutoCompleteFieldData = {
					autoCompleteSingleDataList:[],
					multiAutoComplete: false,
					label:'',
					type: DatasetProfileComboBoxType.Autocomplete
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.ComboBox;
				field.data = data;

				break;
			}case this.viewTypeEnum.InternalDmpEntities:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.InternalDmpEntities)
				// fieldForm.addControl('data', new ResearchersAutoCompleteFieldDataEditorModel().buildForm());//TODO TO SEE

				const data: DmpsAutoCompleteFieldData = {
					label:'',
					multiAutoComplete: false,
					type: DatasetProfileInternalDmpEntitiesType.Dmps
				}


				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.InternalDmpEntities;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.FreeText:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.FreeText)
				// fieldForm.addControl('data', new FreeTextFieldDataEditorModel().buildForm());

				const data: FreeTextFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.FreeText;
				field.data = data;
				break;
			}
			case this.viewTypeEnum.RadioBox:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.RadioBox)
				// fieldForm.addControl('data', new RadioBoxFieldDataEditorModel().buildForm());
				// fieldForm.get('data').setValidators(EditorCustomValidators.atLeastOneElementListValidator('options'));
				// fieldForm.get('data').updateValueAndValidity();
				const data: RadioBoxFieldData= {
					label:'',
					options: []
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.RadioBox;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.TextArea:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.TextArea)
				// fieldForm.addControl('data', new TextAreaFieldDataEditorModel().buildForm());

				const data: TextAreaFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.TextArea;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.RichTextArea:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.TextArea)
				// fieldForm.addControl('data', new TextAreaFieldDataEditorModel().buildForm());

				const data: RichTextAreaFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.RichTextArea;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Upload:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.TextArea)
				// fieldForm.addControl('data', new TextAreaFieldDataEditorModel().buildForm());

				const data: UploadFieldData = {
					label:'',
					types: [],
					maxFileSizeInMB: this.configurationService.maxFileSizeInMB
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Upload;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.DatePicker:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.DatePicker)
				// fieldForm.addControl('data', new DatePickerDataEditorModel().buildForm());
				const data: DatePickerFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.DatePicker;

				break;
			}
			case this.viewTypeEnum.ExternalDatasets:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.ExternalDatasets)
				// fieldForm.addControl('data', new ExternalDatasetsDataEditorModel().buildForm());
				const data: ExternalDatasetsFieldData = {
					label:'',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.ExternalDatasets;
				field.data = data;
				break;
			}
			case this.viewTypeEnum.DataRepositories:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.DataRepositories)
				// fieldForm.addControl('data', new DataRepositoriesDataEditorModel().buildForm());

				const data: DataRepositoriesFieldData = {
					label: '',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.DataRepositories;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.PubRepositories:{


				const data: DataRepositoriesFieldData = {
					label: '',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.DataRepositories;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.JournalRepositories:{

				const data: DataRepositoriesFieldData = {
					label: '',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.DataRepositories;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Taxonomies:{

				const data: TaxonomiesFieldData = {
					label: '',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Taxonomies;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Licenses:{

				const data: LicensesFieldData = {
					label: '',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Licenses;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Publications:{

				const data: PublicationsFieldData = {
					label: '',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Publications;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Registries:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.Registries)
				// fieldForm.addControl('data', new RegistriesDataEditorModel().buildForm());

				const data:RegistriesFieldData = {
					label: '',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Registries;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Services:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.Services)
				// fieldForm.addControl('data', new ServicesDataEditorModel().buildForm());

				const data:ServicesFieldData = {
					label:'',
					multiAutoComplete: false
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Services;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Tags:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.Tags)
				// fieldForm.addControl('data', new TagsDataEditorModel().buildForm());

				const data: TagsFieldData = {
					label:''
				}
				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Tags;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Researchers:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.Researchers)
				// this.form.addControl('data', new ResearchersDataEditorModel().buildForm()); //TODO TO ASK
				// fieldForm.addControl('data', new ResearchersAutoCompleteFieldDataEditorModel().buildForm());

				// field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Researchers;

				const data : ResearchersAutoCompleteFieldData = {
					label:'',
					multiAutoComplete: false,
					type: DatasetProfileInternalDmpEntitiesType.Researchers
				}

				// field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.InternalDmpEntities;
				// field.data = {label:''}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Researchers;
				field.data  = data;




				break;
			}
			case this.viewTypeEnum.Organizations:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.Organizations)
				// fieldForm.addControl('data', new OrganizationsDataEditorModel().buildForm());
				// this.form.addControl('data', new OrganizationsDataEditorModel().buildForm())
				// fieldForm.addControl('data', new DatasetsAutoCompleteFieldDataEditorModel().buildForm());  //TODO

				const data = {
					autoCompleteSingleDataList:[],
					label:'',
					multiAutoComplete: false,

				} as OrganizationsFieldData; //TODO

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Organizations;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.DatasetIdentifier:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.DatasetIdentifier)
				// fieldForm.addControl('data', new DatasetIdentifierDataEditorModel().buildForm());

				const data : DatasetIdentifierFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.DatasetIdentifier;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Currency:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.Currency)
				// fieldForm.addControl('data', new CurrencyDataEditorModel().buildForm());

				const data: CurrencyFieldData = {
					label:''
				}
				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Currency;
				field.data = data;

				break;
			}
			case this.viewTypeEnum.Validation:{


				// fieldForm.get('viewStyle').get('renderStyle').setValue(DatasetProfileFieldViewStyle.Validation)
				// fieldForm.addControl('data', new ValidationDataEditorModel().buildForm());

				const data:ValidationFieldData = {
					label:''
				}

				field.viewStyle.renderStyle = DatasetProfileFieldViewStyle.Validation;
				field.data = data;

				break;
			}
		}

		(<FormArray>this.form.get('fields')).push(new FieldEditorModel().fromModel(field).buildForm());
		this.inputs.init();
		// fieldForm.get('viewStyle').get('renderStyle').updateValueAndValidity();
		// fieldForm.get('data').updateValueAndValidity();


	}

	// private customFieldValidator(): ValidatorFn{
	// 	return (control):ValidationErrors | null=>{
	// 		DatasetProfileFieldViewStyle
	// 		switch(control.get('viewStyle').get('renderStyle').value){

	// 			case DatasetProfileFieldViewStyle.TextArea:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.BooleanDecision:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.ComboBox:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.CheckBox:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.FreeText:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.RadioBox:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.DatePicker:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.InternalDmpEntities:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.ExternalDatasets:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.DataRepositories:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.Registries:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.Services:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.Tags:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.Researchers:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.Organizations:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.DatasetIdentifier:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.Currency:
	// 				return null;
	// 			case DatasetProfileFieldViewStyle.Validation:
	// 				return null;
	// 			default:
	// 				return {inputTypeNotValid: true}
	// 		}
	// 	}
	// }


	// private _atLeastOneElementListValidator(arrayToCheck): ValidatorFn{
	// 	return (control: AbstractControl): ValidationErrors | null=>{

	// 		const fa = control.get(arrayToCheck) as FormArray;

	// 		if(fa.length  === 0){
	// 			return {emptyArray: true};
	// 		}
	// 		return null;
	// 	}
	// }


	calculateLabelWidth(numbering: string){

		const width = numbering.split('.').reduce((acc,item)=> item+acc,'').length;


		return {'width':width+'em'}
	}

	get fieldsArray(): FormArray {
		if(this.form && this.form.get('fields')) {
			return this.form.get('fields') as FormArray;
		}
		return null;
	}

	move(index, direction: "up" | "down" = "up") {
		this.inputs.init();
		if (direction === "up" && this.canGoUp(index)) {
			let temp = this.fieldsArray.at(index);
			this.fieldsArray.removeAt(index);
			this.fieldsArray.insert(index-1, temp);
		} else if (direction === "down" && this.canGoDown(index)) {
			let temp = this.fieldsArray.at(index+1);
			this.fieldsArray.removeAt(index+1);
			this.fieldsArray.insert(index, temp);
		}
		this.fieldsArray.controls.forEach((field, index) => {
			field.get('ordinal').setValue(index);
		});
	}

	canGoUp(index: number): boolean {
		return index > 0 && !this.viewOnly;
	}

	canGoDown(index: number): boolean {
		return index < (this.fieldsArray.length - 1) && !this.viewOnly;
	}
}


