import { OverlayRef } from '@angular/cdk/overlay';
import {
	Component,
	ElementRef,
	Inject,
	OnDestroy,
	Renderer2
} from '@angular/core';

// Токены
import { POWER_SELECT_DATA } from '../../tokens';

// Сервисы
import { CrmHelperService } from '../../services/crm-helper.service';

// Всплывающее окно селектора
@Component({
	selector: 'crm-power-select-popup',
	templateUrl: './crm-power-select-popup.component.html',
	styleUrls: ['./crm-power-select-popup.component.scss']
})
export class CrmPowerSelectPopupComponent implements OnDestroy {

	constructor(
		private readonly renderer: Renderer2,
		private readonly el: ElementRef,
		private readonly overlayRef: OverlayRef,
		@Inject(POWER_SELECT_DATA) public readonly data: any
	) {
		this.addListener();
		this.subscribeLoaded();
		this.onSearch(null);
	}

	// Флаг, загружено
	public isLoaded: boolean = false;

	// Функция для отключения прослушивания события
	private clickListen: () => void;

	// Обработчик клика кнопки
	public onButtonClick(): void {
		if (this.data.buttonClick) {
			this.data.buttonClick.emit();
			this.close();
		}
	}

	// Обработчик выбора элемента из списка
	public onSelect(item: any): void {
		if (this.data.selectItem) {
			this.data.selectItem.emit(item);
			this.close();
		}
	}

	// Обработчик поиска
	public onSearch(term: string): void {
		if (this.data.searchTerms) {
			this.data.searchTerms.emit(term);
			this.isLoaded = false;
		}
	}

	// Обработчик проверки клика
	private onCheckClick(event: MouseEvent): void {
		const target = (
			event.target ||
			event.srcElement ||
			event.currentTarget
		) as Element;

		const overlayEl = this.el && this.el.nativeElement;

		if (
			target &&
			overlayEl && !CrmHelperService.hasParent(overlayEl, target)
		) {
			this.close();
		}
	}

	// Закрыть всплывающее окно
	private close(): void {
		this.overlayRef.dispose();
	}

	// Подписка на событие окончания загрузки
	private subscribeLoaded(): void {
		this.data.loaded.subscribe((): void => {
			this.isLoaded = true;
		});
	}

	// Добавить слушателя
	private addListener(): void {
		// Игнорируем нажатие которое вызвало всплывающее окно
		setTimeout(() => {
			this.clickListen = this.renderer.listen(
				document,
				'click',
				this.onCheckClick.bind(this)
			);
		});
	}

	// Удалить слушателя
	private removeListener(): void {
		if (this.clickListen) { this.clickListen(); }
	}

	// --------------------------------------------------------------------------
	// HOOKS
	// Уничтожение
	public ngOnDestroy(): void {
		this.removeListener();
	}
}
