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

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;
}

@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[]>();

	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;
					for (const header of headers) {
						let name;
						let id;
						if (header.classList.contains('toc-page-header')) {
							name = header.innerText.trim().replace(/^link/, '');
							id = header.id;
							page = header.id.split('_')[1];
							section = undefined;
						} 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;
						} 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;
						}
						const { top } = header.getBoundingClientRect();
						links.push({
							name,
							id,
							type: header.tagName.toLowerCase(),
							top: top,
							active: false,
							page: page,
							section: section
						});
					}
				}
				this.links = links;
			})
	}

	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);
	}

}

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