import { BaseComponent } from '@common/base/base.component';
import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormControl } 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 { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item';
import { Observable } from 'rxjs';
import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { MatDialog } from '@angular/material/dialog';
import { AddOrganizationComponent } from '../add-organization/add-organization.component';
import { AddResearcherComponent } from '../add-researcher/add-researcher.component';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { LanguageInfo } from '@app/core/model/language-info';
import { LanguageInfoService } from '@app/core/services/culture/language-info-service';
import { UserModel } from '@app/core/model/user/user';
import { AuthService } from '@app/core/services/auth/auth.service';
import { Principal } from '@app/core/model/auth/principal';
import { OrganisationService } from '@app/core/services/organisation/organisation.service';

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

	@Input() formGroup: FormGroup = null;
	// @Input() datasetFormGroup: FormGroup;
	@Input() isNewVersion: boolean;
	@Input() isUserOwner: boolean;
	@Input() isClone: boolean;

	@Output() onFormChanged: EventEmitter<any> = new EventEmitter();
	public formControl = new FormControl();

	private associates: UserModel[] = [];

	organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
		filterFn: this.filterOrganisations.bind(this),
		initialItems: (excludedItems: any[]) => this.filterOrganisations('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
		displayFn: (item) => item['name'],
		titleFn: (item) => item['name'],
		subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'))
	};
	researchersAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
		filterFn: this.filterResearchers.bind(this),
		initialItems: (excludedItems: any[]) => this.filterResearchers('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
		displayFn: (item) => item['name'],
		titleFn: (item) => item['name'],
		subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'))
	};

	dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
		filterFn: this.searchDmp.bind(this),
		initialItems: (extraData) => this.searchDmp(''),
		displayFn: (item) => this.getDatasetDisplay(item),
		titleFn: (item) => item['label'],
		subtitleFn: (item) => this.language.instant('DATASET-WIZARD.FIRST-STEP.SUB-TITLE') + new Date(item['creationTime']).toISOString()
	};

	constructor(
		private language: TranslateService,
		private configurationService: ConfigurationService,
		private externalSourcesService: ExternalSourcesService,
		private dmpService: DmpService,
		private dialog: MatDialog,
		private languageInfoService: LanguageInfoService,
		private authentication: AuthService,
		private organizationService: OrganisationService
	) {
		super();
	}

	ngOnInit() {
		if (this.isNewVersion) {
			this.formGroup.get('label').disable();
		}

		if (!this.isUserOwner && !this.isClone) {
			this.formGroup.disable();
		}
		if (isNullOrUndefined(this.formGroup.get('extraProperties').get('publicDate').value)) {
			this.formGroup.get('extraProperties').get('publicDate').patchValue(new Date());
		}

		const principal = this.authentication.current();
		let associate: UserModel = {
			id: principal.id,
			name: principal.name,
			appRoles: principal.authorities,
			email: principal.email
		};
		this.associates.push(associate);
		if (isNullOrUndefined(this.formGroup.get('extraProperties').get('contact').value)) {
			this.formGroup.get('extraProperties').get('contact').patchValue(associate.id);
		}
		if (isNullOrUndefined(this.formGroup.get('extraProperties').get('language').value)) {
			this.formGroup.get('extraProperties').get('language').patchValue('en');
		}
	}

	// Researchers
	filterResearchers(value: string): Observable<ExternalSourceItemModel[]> {
		return this.externalSourcesService.searchDMPResearchers({ criteria: { name: value, like: null } });
	}

	addResearcher(event: MouseEvent) {
		event.stopPropagation();
		const dialogRef = this.dialog.open(AddResearcherComponent, {
			data: this.formGroup.get('researchers')
		});
		dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
			if (result) {
				const fullName = result.firstName + " " + result.lastName;
				const newItem = {
					label: null,
					name: fullName,
					id: null,
					status: 0,
					key: "Internal",
					reference: result.reference
				};
				const researchersArray = this.formGroup.get('researchers').value || [];
				researchersArray.push(newItem);
				this.formGroup.get('researchers').setValue(researchersArray);
			}
		});
	}

	// Organizations
	showOrganizationCreator(): boolean {
		return this.configurationService.allowOrganizationCreator;
	}

	filterOrganisations(value: string): Observable<ExternalSourceItemModel[]> {
		return this.organizationService.searchGeneralOrganisations({ criteria: { labelLike: value } });
	}

	cantAddOrganizations(): boolean {
		if (!isNullOrUndefined(this.formGroup.get('organizations'))) {
			return this.formGroup.get('organiztions').disabled;
		} else {
			return false;
		}
	}

	addOrganization(event: MouseEvent) {
		event.stopPropagation();
		const dialogRef = this.dialog.open(AddOrganizationComponent, {
			data: this.formGroup.get('organisations')
		});
		dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
			if (result) {
				const fullName = result.name;
				const newItem = {
					label: null,
					name: fullName,
					id: null,
					status: 0,
					key: "Internal",
					reference: result.reference
				};
				const organizationsArray = this.formGroup.get('organisations').value || [];
				organizationsArray.push(newItem);
				this.formGroup.get('organisations').setValue(organizationsArray);
			}
		});
	}

	searchDmp(query: string): Observable<DmpListingModel[]> {
		const fields: Array<string> = new Array<string>();
		fields.push('-created');
		const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, null, { fields: fields });
		dmpDataTableRequest.criteria = new DmpCriteria();
		dmpDataTableRequest.criteria.like = query;
		dmpDataTableRequest.criteria.status = DmpStatus.Draft;
		return this.dmpService.getPaged(dmpDataTableRequest, "autocomplete").pipe(map(x => x.data));
	}

	getDatasetDisplay(item: any): string {
		// if (!this.isPublic) {
		// 	return (item['status'] ? this.language.instant('TYPES.DATASET-STATUS.FINALISED').toUpperCase() : this.language.instant('TYPES.DATASET-STATUS.DRAFT').toUpperCase()) + ': ' + item['label'];
		// }
		// else { return item['label']; }
		return item['label'] ? item['label'] : null;
	}

	getLanguageInfos(): LanguageInfo[] {
		return this.languageInfoService.getLanguageInfoValues();
	}

	getAssociates(): UserModel[] {
		let associates: UserModel[];
		if (this.formGroup.get('associatedUsers').value && this.formGroup.get('associatedUsers').value.length > 0) {
			associates = [];
		} else {
			associates = this.associates;
		}
		//associates = (this.formGroup.get('researchers').value as any[]);
		associates = associates.concat(this.formGroup.get('associatedUsers').value);
		return associates;
	}
}
