import { DOCUMENT } from '@angular/common';
import { Component, EventEmitter, Inject, OnInit, Output, Input } from '@angular/core';
import { BaseComponent } from '@common/base/base.component';
import { interval, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { type } from 'os';
import { SimpleChanges } from '@angular/core';

interface Link {
	/* id of the section*/
	id: string;
	/* header type h3/h4 */
	type: string;
	/* If the anchor is in view of the page */
	active: boolean;
	/* name of the anchor */
	name: string;
	/* top offset px of the anchor */
	top: number;
	page: number;
	section: number;
	show: boolean;
	selected: boolean;
}

@Component({
	selector: 'table-of-contents',
	styleUrls: ['./table-of-contents.scss'],
	templateUrl: './table-of-contents.html'
})
export class TableOfContents extends BaseComponent implements OnInit {

	links: Link[] = [];
	container: string;
	headerSelectors = '.toc-page-header, .toc-section-header, .toc-copositeField-header';
	@Output() stepFound = new EventEmitter<LinkToScroll>();
	subscription: Subscription;
	linksSubject: Subject<HTMLElement[]> = new Subject<HTMLElement[]>();

	@Input() isActive: boolean;
	show: boolean = false;

	constructor(
		@Inject(DOCUMENT) private _document: Document) {
		super();
	}


	ngOnInit(): void {
		//emit value every 500ms
		const source = interval(500);
		this.subscription = source.subscribe(val => {
			const headers = Array.from(this._document.querySelectorAll(this.headerSelectors)) as HTMLElement[];
			this.linksSubject.next(headers);
		});

		this.linksSubject.asObservable()
			.pipe(distinctUntilChanged((p: HTMLElement[], q: HTMLElement[]) => JSON.stringify(p) == JSON.stringify(q)))
			.subscribe(headers => {
				const links: Array<Link> = [];

				if (headers.length) {
					let page;
					let section;
					let show
					for (const header of headers) {
						let name;
						let id;
						if (header.classList.contains('toc-page-header')) {  // deprecated after removing stepper
							name = header.innerText.trim().replace(/^link/, '');
							id = header.id;
							page = header.id.split('_')[1];
							section = undefined;
							show = true;
						} else if (header.classList.contains('toc-section-header')) {
							name = header.childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].nodeValue.trim().replace(/^link/, '');
							id = header.id;
							page = header.id.split('.')[1];
							section = header.id;
							if (header.id.split('.')[4]) { show = false; }
							else { show = true; }
						} else if (header.classList.contains('toc-copositeField-header')) {
							name = (header.childNodes[0]).nodeValue.trim().replace(/^link/, '');
							id = header.id;
							// id = header.parentElement.parentElement.parentElement.id;
							show = false;
						}
						const { top } = header.getBoundingClientRect();
						links.push({
							name,
							id,
							type: header.tagName.toLowerCase(),
							top: top,
							active: false,
							page: page,
							section: section,
							show: show,
							selected: false
						});
					}
				}
				this.links = links;
				// Initialize selected for button next on dataset wizard component editor
				this.links.length > 0 ? this.links[0].selected = true : null;
			})
	}

	ngOnChanges(changes: SimpleChanges) {
		if (!this.isActive && this.links && this.links.length > 0) {
			this.links.forEach(link => {
				link.selected = false;
			})
			this.links[0].selected = true;
		}
	}

	goToStep(link: Link) {
		// this.selectedLinkId = link.id;
		this.stepFound.emit({
			page: link.page,
			section: link.section
		});

		setTimeout(() => {
			const target = document.getElementById(link.id);
			target.scrollIntoView(true);

			var scrolledY = window.scrollY;
			if (scrolledY) {
				window.scroll(0, scrolledY - 70);
			}
		}, 500);
	}

	toggle(headerLink: Link) {
		const headerPage = +headerLink.name.split(" ",1);
		let innerPage;
		for (const link of this.links) {
			link.selected = false;
			if (link.type === 'mat-expansion-panel') {
				innerPage = +link.name.split(".",1)[0];
				if(isNaN(innerPage)) { innerPage = +link.name.split(" ",1) }
			} else if (link.type === 'h5') {
			    innerPage = +link.name.split(".",1)[0];
			}
			if (headerPage === innerPage && (link.type !== 'mat-expansion-panel' || (link.type === 'mat-expansion-panel' && link.id.split(".")[4]))) {
				link.show = !link.show;
			}
		}
		headerLink.selected = true;
	}

	// getIndex(link: Link): number {
	// 	return +link.id.split("_", 2)[1];
	// }

}

export interface LinkToScroll {
	page: number;
	section: number;
}
