export default class ScrollBrowser {

	/**
	 * Kick things off
	 *
	 * @param {Node} _element The scrollbrowser root element
	 */
	constructor(_element) {
		this._element = _element;
		this._element.style.display = 'none';
		this._loadingIndicator = this._element.lastElementChild;
		if (!this._loadingIndicator) {
		    return;
		}

		this.url = document.querySelector('.tx-pagebrowse-next a').getAttribute('href');
		window.addEventListener('scroll', this.checkAndLoad.bind(this));

		// Initial check
		this.checkAndLoad();
    }

	/**
	 * Checks and loads the next page if required
	 */
    checkAndLoad() {
		const recordLockedOrNotInPosition = this.lock || !this.checkPosition();
		const urlIsInvalid = typeof this.url === 'undefined' || this.url === null || this.url === this.lastUrl;
		if (recordLockedOrNotInPosition || urlIsInvalid) {
			return;
		}

		this.lock = true;
		this.fetchContent().then(this.displayNewData.bind(this));
	}

	/**
	 * Fetches the content of the next page via Ajax
	 */
    fetchContent() {
		return new Promise((resolve) => {
		    const request = new XMLHttpRequest();
			request.onreadystatechange = () => {
				if (request.readyState === XMLHttpRequest.DONE) {
					if (request.status === 200) {
						resolve(request.responseText);
					}
				}
			};
			request.open(
				'GET',
				this.url
			);
			request.send();
		});
    }

	/**
	 * Adds fetched DOM nodes to the list
	 *
	 * @param {String} response The HTML of the AJAX response
	 */
    displayNewData(response) {
		const parser = new DOMParser();
		const doc = parser.parseFromString(response, 'text/html');
		const results = Array.from(doc.querySelectorAll('.tx-sgnews-list'));
		results.forEach((result) => {
			const children = Array.from(result.childNodes);
			if (!children.length) {
				return;
			}

			let resultList = document.querySelector(`.tx-sgnews-list-${result.dataset.record}`);
			if (!resultList) {
				resultList = document.querySelector('.tx-sgnews-list');
			}
			children.forEach((child) => {
				resultList.appendChild(child);
			});
			this._loadingIndicator = resultList.lastElementChild;
		});

		this.lastUrl = this.url;
		this.url = doc.querySelector('.tx-pagebrowse-next a').getAttribute('href');
		this.lock = false;
    }

	/**
	 * Checks the current position of the scrollbar in relation to the position of the load indicator.
	 *
	 * @return boolean
	 */

    checkPosition() {
		const loadingIndicatorPosition = this._loadingIndicator.getBoundingClientRect();
		const windowScrollPosition = window.scrollY;
		return (windowScrollPosition > (loadingIndicatorPosition.top - 6000));
    }
}