
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profile-combo-box-type';
import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style';
import { DatasetProfileInternalDmpEntitiesType } from '@app/core/common/enum/dataset-profile-internal-dmp-entities-type';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DatasetExternalAutocompleteCriteria } from '@app/core/query/dataset/daatset-external-autocomplete-criteria';
import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria';
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
import { RequestItem } from '@app/core/query/request-item';
import { ResearcherCriteria } from '@app/core/query/researcher/researcher-criteria';
import { DatasetExternalAutocompleteService } from '@app/core/services/dataset/dataset-external-autocomplete.service';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service';
import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators';

@Component({
	selector: 'app-form-field',
	templateUrl: './form-field.component.html',
	styleUrls: ['./form-field.component.scss']
})
export class FormFieldComponent extends BaseComponent implements OnInit {

	// @Input() field: Field;
	@Input() form: FormGroup;
	@Input() datasetProfileId: String;
	@Input() isChild: Boolean = false;

	// change: Subscription;
	// trackByFn = (index, item) => item ? item['id'] : null;

	public singleAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
	public multipleAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
	datasetProfileFieldViewStyleEnum = DatasetProfileFieldViewStyle;
	datasetProfileComboBoxTypeEnum = DatasetProfileComboBoxType;
	datasetProfileInternalDmpEntitiesTypeEnum = DatasetProfileInternalDmpEntitiesType;

	constructor(
		public visibilityRulesService: VisibilityRulesService,
		private datasetExternalAutocompleteService: DatasetExternalAutocompleteService,
		private externalSourcesService: ExternalSourcesService,
		private language: TranslateService,
		private datasetService: DatasetService,
		private dmpService: DmpService
	) { super(); }

	ngOnInit() {
		if (this.form.get('value').value) {
			this.visibilityRulesService.updateValueAndVisibility(this.form.get('id').value, this.form.get('value').value);
		}

		// Setup autocomplete configuration if needed
		if (this.form.get('viewStyle').value.renderStyle === DatasetProfileFieldViewStyle.ComboBox && this.form.get('data').value.type === DatasetProfileComboBoxType.Autocomplete) {
			if (!(this.form.controls['data'].value.multiAutoComplete)) {
				this.singleAutoCompleteConfiguration = {
					filterFn: this.searchFromAutocomplete.bind(this),
					initialItems: () => this.searchFromAutocomplete(''),
					displayFn: (item) => (item != null && item.length > 1) ? JSON.parse(item).label : item['label'],
					titleFn: (item) => item['label'],
					valueAssign: (item) => JSON.stringify(item),
					subtitleFn: (item) => item['source'] ? this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-SUBTITLE') + item['source'] : this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-NO-SOURCE')
				};
			}
			else {
				this.multipleAutoCompleteConfiguration = {
					filterFn: this.searchFromAutocomplete.bind(this),
					initialItems: () => this.searchFromAutocomplete(''),
					displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['label'] : item['label'],
					titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['label'] : item['label'],
					valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item),
					subtitleFn: (item) => item['source'] ? this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-SUBTITLE') + item['source'] : this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-NO-SOURCE')
				}
			}
		}

		if (this.form.get('viewStyle').value.renderStyle === DatasetProfileFieldViewStyle.InternalDmpEntities) {
			if (this.form.get('data').value.type === DatasetProfileInternalDmpEntitiesType.Researchers) {
				this.makeAutocompleteConfiguration(this.searchResearchers.bind(this), "name", "tag");
			}
			else if (this.form.get('data').value.type === DatasetProfileInternalDmpEntitiesType.Datasets) {
				this.makeAutocompleteConfiguration(this.searchDatasets.bind(this), "label");
			}
			else if (this.form.get('data').value.type === DatasetProfileInternalDmpEntitiesType.Dmps) {
				this.makeAutocompleteConfiguration(this.searchDmps.bind(this), "label");
			}
		}

		// this.form = this.visibilityRulesService.getFormGroup(this.field.id);
		this.form.get('value').valueChanges
			.pipe(takeUntil(this._destroyed))
			.subscribe(item => {
				this.visibilityRulesService.updateValueAndVisibility(this.form.get('id').value, item);
			});
	}

	// _optionRemove(event) {
	// 	const array = JSON.parse(this.form.get('value').value);
	// 	if (array) {
	// 		const index = array.map(x => x.id).indexOf(event.id);
	// 		if (index >= 0) {
	// 			array.splice(index, 1);
	// 		}
	// 		this.form.get('value').patchValue(JSON.stringify(array));
	// 	}
	// }

	searchFromAutocomplete(query: string) {
		const autocompleteRequestItem: RequestItem<DatasetExternalAutocompleteCriteria> = new RequestItem();
		autocompleteRequestItem.criteria = new DatasetExternalAutocompleteCriteria();

		autocompleteRequestItem.criteria.fieldID = this.form.get('id').value;
		autocompleteRequestItem.criteria.profileID = this.datasetProfileId;
		autocompleteRequestItem.criteria.like = query;
		return this.datasetExternalAutocompleteService.queryAutocomplete(autocompleteRequestItem);
	}

	searchResearchers(query: string) {
		const reasearcherAutocompleteRequestItem: RequestItem<ResearcherCriteria> = new RequestItem();
		reasearcherAutocompleteRequestItem.criteria = new ResearcherCriteria;
		reasearcherAutocompleteRequestItem.criteria.name = query;
		return this.externalSourcesService.searchDMPResearchers(reasearcherAutocompleteRequestItem);
	}

	searchDatasets(query: string) {
		let fields: Array<string> = new Array();
		const datasetsAutocompleteRequestItem: DataTableRequest<DatasetCriteria> = new DataTableRequest(0, 25, { fields: fields });
		datasetsAutocompleteRequestItem.criteria = new DatasetCriteria();
		datasetsAutocompleteRequestItem.criteria.like = query;
		return this.datasetService.getPaged(datasetsAutocompleteRequestItem).pipe(map(item => item.data));
	}

	searchDmps(query: string) {
		let fields: Array<string> = new Array();
		const dmpsAutocompleteRequestItem: DataTableRequest<DmpCriteria> = new DataTableRequest(0, 25, { fields: fields });
		dmpsAutocompleteRequestItem.criteria = new DmpCriteria();
		dmpsAutocompleteRequestItem.criteria.like = query;
		return this.dmpService.getPaged(dmpsAutocompleteRequestItem).pipe(map(item => item.data));
	}

	makeAutocompleteConfiguration(myfunc: Function, title: string, subtitle?: string): void {
		if (!(this.form.controls['data'].value.multiAutoComplete)) {
			this.singleAutoCompleteConfiguration = {
				filterFn: myfunc.bind(this),
				initialItems: (extraData) => myfunc(''),
				displayFn: (item) => (item != null && item.length > 1) ? JSON.parse(item)[title] : item[title],
				titleFn: (item) => item[title],
				valueAssign: (item) => JSON.stringify(item),
				subtitleFn: (item) => item[subtitle]
			};
		}
		else {
			this.multipleAutoCompleteConfiguration = {
				filterFn: myfunc.bind(this),
				initialItems: (extraData) => myfunc(''),
				displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['label'] : item['label'],
				titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['label'] : item['label'],
				valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item),
				subtitleFn: (item) => item[subtitle]
			}
		}
	}
}
