
import { SelectionModel } from '@angular/cdk/collections';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatListOption, MatSelectionList } from '@angular/material/list';
import { BaseComponent } from '@common/base/base.component';
import { Observable, of as observableOf } from 'rxjs';
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';


@Component({
	selector: 'app-explore-dmp-filter-item-component',
	templateUrl: './explore-dmp-filter-item.component.html',
	styleUrls: ['./explore-dmp-filter-item.component.scss']
})
export class ExploreDmpFilterItemComponent extends BaseComponent implements OnInit {
	@Input()
	searchEnabled = false;
	@Input()
	requestDelay = 200;
	@Input()
	multipleSelect = true;
	@Input()
	filterOptions: (value) => Observable<any[]>;
	@Input()
	options: Observable<any[]> = observableOf([]);
	@Input()
	displayTitleFunc: (value) => string;
	@Input()
	displayValueFunc: (value) => string;
	@Output()
	selectedChanged = new EventEmitter();
	@Output()
	optionRemoved = new EventEmitter();


	optionSearchControl = new FormControl('');
	public selectedOptions: any[] = [];

	@ViewChild('optionsList', { static: true }) selectionList: MatSelectionList;

	constructor() { super(); }

	ngOnInit(): void {
		if (!this.multipleSelect) { this.selectionList.selectedOptions = new SelectionModel<MatListOption>(this.multipleSelect); }
		this.optionSearchControl.valueChanges.pipe(debounceTime(this.requestDelay),
			distinctUntilChanged())
			.pipe(takeUntil(this._destroyed))
			.subscribe(x => { if (this.filterOptions) { this.options = this.filterOptions(x); } });
	}

	public selectionChanged(event: any) {
		const eventValue = event.option.value;
		if (event.option.selected) { this.selectedOptions.push(eventValue); }
		if (!event.option.selected) {
			const index = this.selectedOptions.map(x => this.displayValue(x)).indexOf(this.displayValue(eventValue));
			this.selectedOptions.splice(index, 1);
		}
		this.selectedChanged.emit(event);
	}

	public removeOption(grant) {
		const list = this.selectionList.selectedOptions.selected.map(x => x.value);
		const indexOfGrant = list.indexOf(grant);
		if (this.selectionList.selectedOptions.selected[indexOfGrant]) {
			this.selectionList.selectedOptions.selected[indexOfGrant].selected = false;
			this.selectionList.selectedOptions.selected.splice(indexOfGrant, 1);
		}
		this.selectedOptions.splice(this.selectedOptions.map(x => this.displayValue(x)).indexOf(this.displayValue(grant)), 1);
		this.optionRemoved.emit(grant);
	}

	public isOptionSelected(value) {
		return this.selectedOptions.map(x => this.displayValue(x)).indexOf(this.displayValue(value)) !== -1;
	}

	displayLabel(value) {
		return this.displayTitleFunc ? this.displayTitleFunc(value) : value;
	}

	displayValue(value) {
		return this.displayValueFunc ? this.displayValueFunc(value) : value;
	}
}
