import { DataSource } from '@angular/cdk/table';
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
import { DatasetProfileService } from '@app/core/services/dataset-profile/dataset-profile.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { DatasetProfileCriteriaComponent } from '@app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component';
import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import { merge as observableMerge, Observable, of as observableOf } from 'rxjs';
import { map, startWith, switchMap, takeUntil } from 'rxjs/operators';

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

	@ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator;
	@ViewChild(MatSort, { static: true }) sort: MatSort;
	@ViewChild(DatasetProfileCriteriaComponent, { static: true }) criteria: DatasetProfileCriteriaComponent;

	breadCrumbs: Observable<BreadcrumbItem[]>;
	dataSource: DatasetDataSource | null;
	displayedColumns: String[] = ['label', 'description', 'created', 'actions'];
	pageEvent: PageEvent;
	titlePrefix: String;
	dmpId: String;
	itemId: string;

	constructor(
		private datasetService: DatasetProfileService,
		private router: Router,
		private route: ActivatedRoute,
		private dmpService: DmpService,
		private language: TranslateService,
		private uiNotificationService: UiNotificationService
	) {
		super();
	}

	ngOnInit() {
		this.route.params
			.pipe(takeUntil(this._destroyed))
			.subscribe((params: Params) => {
				if (params['dmpId']) {
					this.dmpId = params['dmpId'];
					if (this.dmpId != null) { this.setDmpTitle(this.dmpId); }
					this.criteria.setCriteria(this.getDefaultCriteria());
					this.refresh();
					this.criteria.setRefreshCallback(() => this.refresh());
					// this.breadCrumbs = Observable.of([{
					// 	parentComponentName: null,
					// 	label: this.language.instant('NAV-BAR.DATASET-TEMPLATES'),
					// 	url: 'plans/edit/' + this.dmpId
					// }]);
				} else {
					this.itemId = params['groupId'];
					if (this.itemId) {
						const datasetProfileLabel = this.route.snapshot.queryParams.groupLabel;
					}
					this.criteria.setCriteria(this.getDefaultCriteria());
					this.refresh();
					this.criteria.setRefreshCallback(() => this.refresh());
					this.breadCrumbs = observableOf([{
						parentComponentName: null,
						label: this.language.instant('NAV-BAR.DATASET-TEMPLATES'),
						url: '/dataset-profiles'
					}]);
				}
			});
	}

	setDmpTitle(dmpId: String) {
		this.dmpService.getSingle(dmpId).pipe(map(data => data as DmpModel))
			.pipe(takeUntil(this._destroyed))
			.subscribe(data => {
				this.titlePrefix = data.label;
			}
			);
	}

	refresh() {
		this.dataSource = new DatasetDataSource(this.datasetService, this._paginator, this.sort, this.criteria, this.itemId);
	}

	rowClick(rowId: String) {
		this.router.navigate(['dataset-profiles/' + rowId]);
	}

	getDefaultCriteria(): DatasetProfileCriteria {
		const defaultCriteria = new DatasetProfileCriteria();
		return defaultCriteria;
	}

	clone(id: string) {
		this.router.navigate(['dataset-profiles/clone/' + id]);
	}

	newVersion(id: string, label: string) {
		this.router.navigate(['dataset-profiles/newversion/' + id]);
	}

	viewVersions(rowId, rowLabel) {
		this.router.navigate(['/dataset-profiles/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
	}

	// makeItPublic(id: String) {
	//   debugger;
	//   this.datasetService.makeDatasetPublic(id).pipe(takeUntil(this._destroyed)).subscribe();
	// }
}

export class DatasetDataSource extends DataSource<DatasetListingModel> {

	totalCount = 0;

	constructor(
		private _service: DatasetProfileService,
		private _paginator: MatPaginator,
		private _sort: MatSort,
		private _criteria: DatasetProfileCriteriaComponent,
		private itemId
	) {
		super();

	}

	connect(): Observable<DatasetListingModel[]> {
		const displayDataChanges = [
			this._paginator.page
			//this._sort.matSortChange
		];

		return observableMerge(...displayDataChanges).pipe(
			startWith(null),
			switchMap(() => {
				const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
				let fields: Array<string> = new Array();
				if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; }
				const request = new DataTableRequest<DatasetProfileCriteria>(startIndex, this._paginator.pageSize, { fields: fields });
				request.criteria = this._criteria.criteria;
				request.criteria.finalized = false;
				if (this.itemId) {
					request.criteria.groupIds = [this.itemId];
					request.criteria.allVersions = true;
				}
				return this._service.getPaged(request);
			}),
			/*.catch((error: any) => {
			  this._snackBar.openFromComponent(SnackBarNotificationComponent, {
				data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService },
				duration: 3000,
				extraClasses: ['snackbar-warning']
			  });
			  //this._criteria.criteria.onCallbackError(error);
			  return Observable.of(null);
			})*/
			map(result => {
				return result;
			}),
			map(result => {
				if (!result) { return []; }
				if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
				return result.data;
			}));
	}

	disconnect() {
		// No-op
	}
}
