import PhotoSwipeLightbox from 'photoswipe/lightbox'; // eslint-disable-line import/no-unresolved
import PhotoSwipe from 'photoswipe'; // eslint-disable-line import/no-extraneous-dependencies
import Masonry from 'masonry-layout'; // eslint-disable-line import/no-extraneous-dependencies

const masonryOptions = {
	columnWidth: '.gallery__item--sizer',
	itemSelector: '.gallery__item:not(.gallery__item--hidden)',
	horizontalOrder: true,
	percentPosition: true,
	resizeDelay: 200,
	transitionDuration: 0,
};
let lightboxActive = false;

class Gallery {
	constructor(domNode) {
		this.rootEl = domNode;
		for (let i = 0; i < this.rootEl.children.length; i++) {
			const child = this.rootEl.children[i];
			child.style = null;
			if (child.classList.contains('gallery__sorting')) {
				this.sortEl = child;
				this.sortButtons = [];
				for (let j = 0; j < this.sortEl.children.length; j++) {
					if (this.sortEl.children[j].classList.contains('btn')) {
						this.sortButtons.push(this.sortEl.children[j]);
					}
				}
			} else if (child.classList.contains('gallery')) {
				this.blockEl = child;
			} else if (child.classList.contains('gallery__pagination')) {
				this.pageEl = child;
				for (let j = 0; j < this.pageEl.children.length; j++) {
					if (this.pageEl.children[j].classList.contains('btn')) {
						this.pageButtonEl = this.pageEl.children[j];
					}
				}
			}
		}

		this.pageSize = 12;
		this.sortCategory = 'none';
		this.layout = this.blockEl.classList.contains('gallery--masonry') ? 'masonry' : 'grid';
		if (this.layout === 'masonry') {
			this.initMasonry();
		} else {
			this.initGrid();
		}

		this.nextIndex = this.validItems.length < this.pageSize ? 0 : this.pageSize;
		if (this.nextIndex > 0) {
			for (let i = this.nextIndex; i < this.validItems.length; i++) {
				this.hideItem(this.validItems[i]);
			}
		} else if (this.pageEl) {
			this.hidePagination();
		}

		if (this.pageButtonEl) {
			this.pageButtonEl.addEventListener('click', this.onShowMore.bind(this));
		}
		if (this.sortButtons) {
			for (let i = 0; i < this.sortButtons.length; i++) {
				this.sortButtons[i].addEventListener('click', this.onCategoryChange.bind(this));
			}
		}
	}

	initMasonry() {
		const galleryItems = [];
		const validItems = [];
		this.totalItems = this.blockEl.children.length - 1;

		for (let i = 0; i < this.totalItems; i++) {
			const el = this.blockEl.children[i + 1];
			galleryItems.push(el);
			validItems.push(el);
		}

		this.galleryItems = galleryItems;
		this.validItems = validItems;

		this.nextIndex = this.validItems.length < this.pageSize ? 0 : this.pageSize;

		// hide beyond first page before Masonry scans the DOM
		if (this.nextIndex > 0) {
			for (let i = this.nextIndex; i < this.validItems.length; i++) {
				this.hideItem(this.validItems[i]); // adds display: none
			}
		} else if (this.pageEl) {
			this.hidePagination();
		}

		this.masonry = new Masonry(this.blockEl, masonryOptions);
		this.masonry.layout();
	}

	initGrid() {
		this.masonry = null;
		const galleryItems = [];
		const validItems = [];
		this.totalItems = this.blockEl.children.length;
		for (let i = 0; i < this.totalItems; i++) {
			this.blockEl.children[i].style = null;
			galleryItems.push(this.blockEl.children[i]);
			validItems.push(this.blockEl.children[i]);
		}
		this.galleryItems = galleryItems;
		this.validItems = validItems;
		this.blockEl.style = null;
	}

	hideItem(item) {
		if (!item.classList.contains('gallery__item--hidden')) {
			item.classList.add('gallery__item--hidden');
		}
	}

	showItem(item) {
		if (item.classList.contains('gallery__item--hidden')) {
			item.classList.remove('gallery__item--hidden');
		}
	}

	hidePagination() {
		if (this.pageEl) {
			this.pageEl.style.display = 'none';
		}
	}

	showPagination() {
		if (this.pageEl) {
			this.pageEl.style.display = null;
		}
	}

	showMore() {
		let newItems = 0;
		for (let i = this.nextIndex; i < this.validItems.length; i++) {
			this.showItem(this.validItems[i]);
			newItems++;
			if (newItems >= this.pageSize) {
				break;
			}
		}
		this.nextIndex += newItems;
		if (this.nextIndex >= this.validItems.length) {
			this.hidePagination();
			this.nextIndex = 0;
		}

		if (this.layout === 'masonry' && this.masonry) {
			requestAnimationFrame(() => this.refreshMasonry());
		}
	}

	categoryChange(filter, category) {
		if (this.sortCategory === category) {
			this.sortCategory = 'none';
			this.validItems = this.galleryItems;
			filter.classList.remove('active-filter');
		} else {
			this.sortCategory = category;
			this.validItems = [];
			for (let i = 0; i < this.totalItems; i++) {
				if (this.galleryItems[i].classList.contains(`category-${this.sortCategory}`)) {
					this.validItems.push(this.galleryItems[i]);
				}
				this.hideItem(this.galleryItems[i]);
			}

			for (let i = 0; i < this.sortButtons.length; i++) {
				this.sortButtons[i].classList.remove('active-filter');
			}
			filter.classList.add('active-filter');
		}

		for (let i = 0; i < this.validItems.length; i++) {
			if (i < this.pageSize) {
				this.showItem(this.validItems[i]);
			} else {
				this.hideItem(this.validItems[i]);
			}
		}

		this.nextIndex = this.validItems.length < this.pageSize ? 0 : this.pageSize;
		if (this.nextIndex > 0) {
			this.showPagination();
		} else {
			this.hidePagination();
		}

		if (this.layout === 'masonry' && this.masonry) {
			requestAnimationFrame(() => this.refreshMasonry());
		}
	}

	refreshMasonry() {
		if (this.masonry) {
			this.masonry.reloadItems();
			this.masonry.layout();
		}
	}

	onCategoryChange(event) {
		this.categoryChange(event.target, event.target.dataset.category);
	}

	onShowMore() {
		if (this.nextIndex > 0) {
			this.showMore();
		} else {
			this.hidePagination();
		}
	}
}

function initGalleries() {
	if (!lightboxActive) {
		const lightbox = new PhotoSwipeLightbox({
			gallery: '.gallery.gallery--lightbox',
			children: 'a.gallery__image',
			pswpModule: () => PhotoSwipe,
		});
		lightbox.init();
		lightboxActive = true;
	}

	const galleries = document.querySelectorAll('.lg-block__gallery--native');
	galleries.forEach((gallery) => {
		initGallery(gallery);
	});
}

export function initGallery(gallery) {
	new Gallery(gallery);
}

window.addEventListener('DOMContentLoaded', function () {
	initGalleries();
});
