import { BaseComponent } from '@common/base/base.component';
import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormArray } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { map, takeUntil } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service';
import { MatDialog } from '@angular/material/dialog';
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile';
import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service';
import { AvailableProfilesComponent } from '../available-profiles/available-profiles.component';
import { DmpEditorModel } from '../dmp-editor.model';
import { Router, Params, ActivatedRoute } from '@angular/router';
import { RequestItem } from '@app/core/query/request-item';
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { DatasetDescriptionFormEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
import { DatasetPreviewDialogComponent } from '../../dataset-preview/dataset-preview-dialog.component';

@Component({
	selector: 'dataset-info',
	templateUrl: './dataset-info.component.html',
	styleUrls: ['./dataset-info.component.scss']
})
export class DatasetInfoComponent extends BaseComponent implements OnInit {

	@Input() formGroup: FormGroup = null;
	// @Input() datasetFormGroup: FormGroup = null;
	@Input() isUserOwner: boolean;
	@Input() dmp: DmpEditorModel;
	@Input() hasDmpId: boolean;
	@Input() isPublic: boolean;
	@Input() isFinalized: boolean;
	@Input() isNewVersion: boolean;
	@Input() isClone: boolean;
	@Output() onFormChanged: EventEmitter<any> = new EventEmitter();

	availableProfiles: DatasetProfileModel[] = [];

	selectedDmpProfileDefinition: DmpProfileDefinition;
	profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;

	datasetProfileDefinitionModel: DatasetDescriptionFormEditorModel;
	datasetProfileDefinitionFormGroup: FormGroup;

	constructor(
		private language: TranslateService,
		private configurationService: ConfigurationService,
		private externalSourcesService: ExternalSourcesService,
		private datasetWizardService: DatasetWizardService,
		private dialog: MatDialog,
		private _service: DmpService,
		private dmpProfileService: DmpProfileService,
		private router: Router,
		private route: ActivatedRoute,
		private uiNotificationService: UiNotificationService
	) {
		super();
	}

	ngOnInit() {

		try{
			const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[];
			profiles.sort((a,b)=>a.label.localeCompare(b.label));
		}catch{
			console.info('Could not sort profiles');
		}




		this.profilesAutoCompleteConfiguration = {
			filterFn: this.filterProfiles.bind(this),
			initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
			displayFn: (item) => item['label'],
			titleFn: (item) => item['label'],
			subtitleFn: (item) => item['description'],
			popupItemActionIcon: 'visibility'
		};

		if (this.formGroup.get('definition')) { this.selectedDmpProfileDefinition = this.formGroup.get('definition').value; }
		this.registerFormEventsForDmpProfile();

		if (this.hasDmpId) {
			this.loadDatasetProfiles();
			this.profilesAutoCompleteConfiguration = {
				filterFn: this.filterProfiles.bind(this),
				initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
				displayFn: (item) => item['label'],
				titleFn: (item) => item['label'],
				subtitleFn: (item) => item['description'],
				popupItemActionIcon: 'visibility'
			};
		}
	}

	// Researchers
	filterProfiles(value: string): Observable<DatasetProfileModel[]> {
		const request = new DataTableRequest<DatasetProfileCriteria>(null, null, { fields: ['+label'] });
		const criteria = new DatasetProfileCriteria();
		criteria.like = value;
		request.criteria = criteria;
		return this._service.searchDMPProfiles(request);
	}

	registerFormEventsForDmpProfile(definitionProperties?: DmpProfileDefinition): void {
		this.formGroup.get('profile').valueChanges
			.pipe(
				takeUntil(this._destroyed))
			.subscribe(Option => {
				if (Option instanceof Object) {
					this.selectedDmpProfileDefinition = null;
					this.dmpProfileService.getSingle(Option.id)
						.pipe(takeUntil(this._destroyed))
						.subscribe(result => {
							this.selectedDmpProfileDefinition = result.definition;
						});
				} else {
					this.selectedDmpProfileDefinition = null;
				}
				this.selectedDmpProfileDefinition = definitionProperties;
			})
	}

	loadDatasetProfiles() {
		const datasetProfileRequestItem: RequestItem<DatasetProfileCriteria> = new RequestItem();
		datasetProfileRequestItem.criteria = new DatasetProfileCriteria();
		this.formGroup.get('id').value ? datasetProfileRequestItem.criteria.id = this.formGroup.get('id').value : datasetProfileRequestItem.criteria.id = this.formGroup.get('datasets')['controls'][0].get('dmp').value.id;
		if (datasetProfileRequestItem.criteria.id) {
			this.datasetWizardService.getAvailableProfiles(datasetProfileRequestItem)
				.pipe(takeUntil(this._destroyed))
				.subscribe(items => {
					this.availableProfiles = items;
				});
		}
	}

	allAvailableProfiles(event: MouseEvent) {
		event.stopPropagation();
		const dialogRef = this.dialog.open(AvailableProfilesComponent, {
			data: {
				profiles: this.formGroup.get('profiles')
			}
		});

		return false;
	}

	// dmpValueChanged(dmp: DmpListingModel) {
	// 	if (dmp) {
	// 		this.formGroup.get('profile').enable();
	// 		this.loadDatasetProfiles();
	// 	}
	// 	else {
	// 		this.availableProfiles = [];
	// 		this.formGroup.get('profile').reset();
	// 		this.formGroup.get('profile').disable();
	// 		this.formGroup.removeControl('datasetProfileDefinition');
	// 	}
	// }

	// registerFormListeners() {
	// 	this.formGroup.get('datasets')['controls'][0].get('dmp').valueChanges
	// 		.pipe(takeUntil(this._destroyed))
	// 		.subscribe(x => {
	// 			this.dmpValueChanged(x);
	// 		});
	// 	this.formGroup.get('profile').valueChanges
	// 		.pipe(takeUntil(this._destroyed))
	// 		.subscribe(x => {
	// 			//this.datasetProfileValueChanged(x);
	// 		});
	// }

	// datasetProfileValueChanged(profiledId: string) {
	// 	if (profiledId && profiledId.length > 0) {
	// 		this.formGroup.removeControl('datasetProfileDefinition');
	// 		this.getDefinition();
	// 	}
	// }

	// getDefinition() {
	// 	this.datasetWizardService.getDefinition(this.formGroup.get('profile').value)
	// 		.pipe(takeUntil(this._destroyed))
	// 		.subscribe(item => {
	// 			this.formGroup.get('datasets')['controls'][0].datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item);
	// 			this.datasetProfileDefinitionModel = this.formGroup.get('datasets')['controls'][0].datasetProfileDefinition;
	// 			this.formGroup.addControl('datasetProfileDefinition', this.datasetProfileDefinitionModel.buildForm());
	// 		});
	// }

	onRemoveTemplate(event) {
		let found = false;
		const profiles = this.formGroup.get('profiles').value;
		this.formGroup.get('datasets')['controls'].forEach(element => {
			if (element.get('profile').value.id === event.id) {
				found = true;
				this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success);
			}
		});
		if (found) {
			this.formGroup.get('profiles').setValue(profiles);
			this.profilesAutoCompleteConfiguration = {
				filterFn: this.filterProfiles.bind(this),
				initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
				displayFn: (item) => item['label'],
				titleFn: (item) => item['label'],
				subtitleFn: (item) => item['description'],
				popupItemActionIcon: 'visibility'
			};

		}
	}

	onPreviewTemplate(event) {
		const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, {
			width: '590px',
			minHeight: '200px',
			restoreFocus: false,
			data: {
				template: event
			},
			panelClass: 'custom-modalbox'
		});
		dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
			if (result) {
				let profiles = this.formGroup.get('profiles').value;
				profiles.push(event);
				this.formGroup.get('profiles').setValue(profiles);
				this.profilesAutoCompleteConfiguration = {
					filterFn: this.filterProfiles.bind(this),
					initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
					displayFn: (item) => item['label'],
					titleFn: (item) => item['label'],
					subtitleFn: (item) => item['description'],
					popupItemActionIcon: 'visibility'
				};
			}
		});
	}
	onOptionSelected(){
		try{
			const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[];
			const profileCounts: Map<String, number> = new Map<String, number>();
			profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1));
			const duplicateProfiles = profiles.filter((value) => {
				let isOk = profileCounts.get(value.id) > 1;
				if (isOk) {
					profileCounts.set(value.id, 0);
				}
				return isOk;
			});
			duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1));
			profiles.sort((a,b)=> a.label.localeCompare(b.label));
		}catch{
			console.info('Could not sort Dataset Templates')
		}
	}
}
