import isNumber from 'is-number';
import $ from 'jquery';

const {
	Image,
	VPData,
	VPPopupAPI,
	PhotoSwipe,
	PhotoSwipeUI_Default: PhotoSwipeUIDefault,
} = window;
const { __, settingsPopupGallery } = VPData;

function resizeVideo(data, curItem) {
	if (typeof curItem === 'undefined') {
		if (data && data.itemHolders.length) {
			data.itemHolders.forEach((val) => {
				if (val.item && val.item.html) {
					resizeVideo(data, val.item);
				}
			});
		}
		return;
	}

	// calculate real viewport in pixels
	const vpW = data.viewportSize.x;
	let vpH = data.viewportSize.y;
	const ratio = curItem.vw / curItem.vh;
	let resultW;
	const $container = $(curItem.container);

	const bars = data.options.barsSize;
	let barTop = 0;
	let barBot = 0;
	if (bars) {
		barTop = bars.top && bars.top !== 'auto' ? bars.top : 0;
		barBot = bars.bottom && bars.bottom !== 'auto' ? bars.bottom : 0;
	}
	vpH -= barTop + barBot;

	if (ratio > vpW / vpH) {
		resultW = vpW;
	} else {
		resultW = vpH * ratio;
	}

	const $videoCont = $container.find('.vp-pswp-video');

	$videoCont.css('max-width', resultW);
	$videoCont.children().css({
		paddingBottom: `${100 * (curItem.vh / curItem.vw)}%`,
	});

	$container.css({
		top: barTop,
		bottom: barBot,
	});
}

if (PhotoSwipe && VPPopupAPI) {
	let pswpInstance;

	// prepare photoswipe markup
	if (!$('.vp-pswp').length) {
		const markup = `
        <div class="pswp vp-pswp${
			settingsPopupGallery.click_to_zoom ? '' : ' vp-pswp-no-zoom'
		}" tabindex="-1" role="dialog" aria-hidden="true">
            <div class="pswp__bg"></div>
            <div class="pswp__scroll-wrap">
                <div class="pswp__container">
                    <div class="pswp__item"></div>
                    <div class="pswp__item"></div>
                    <div class="pswp__item"></div>
                </div>
                <div class="pswp__ui pswp__ui--hidden">
                    <div class="pswp__top-bar">
                        <div class="pswp__counter"></div>
                        <button class="pswp__button pswp__button--close" title="${
							__.pswp_close
						}"></button>
                        <a href="#" class="pswp__button pswp__button--download${
							settingsPopupGallery.show_download_button
								? ''
								: ' pswp__element--disabled'
						}" title="${__.pswp_download}" download>
							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z"></path></svg>
						</a>
                        <button class="pswp__button pswp__button--share" title="${
							__.pswp_share
						}"></button>
                        <button class="pswp__button pswp__button--fs" title="${
							__.pswp_fs
						}"></button>
                        <button class="pswp__button pswp__button--zoom" title="${
							__.pswp_zoom
						}"></button>
                    </div>
                    <div class="pswp__preloader">
                        <div class="pswp__preloader__icn">
                            <div class="pswp__preloader__cut">
                                <div class="pswp__preloader__donut"></div>
                            </div>
                        </div>
                    </div>
                    <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                        <div class="pswp__share-tooltip"></div>
                    </div>
                    <button class="pswp__button pswp__button--arrow--left" title="${
						__.pswp_prev
					}"></button>
                    <button class="pswp__button pswp__button--arrow--right" title="${
						__.pswp_next
					}"></button>
                    <div class="pswp__caption">
                        <div class="pswp__caption__center"></div>
                    </div>
                </div>
            </div>
        </div>
        `;
		$('body').append(markup);
	}

	// Extend Popup API.
	VPPopupAPI.vendor = 'photoswipe';
	VPPopupAPI.open = function (items, index, self) {
		const finalItems = [];

		// prepare items for fancybox api.
		items.forEach((item) => {
			if (item.type === 'embed') {
				finalItems.push({
					html: `<div class="vp-pswp-video"><div>${item.embed}</div></div>`,
					vw: item.width || 0,
					vh: item.height || 0,
					title: item.caption,
				});
			} else {
				finalItems.push({
					src: item.src,
					el: item.el,
					w: item.width || 0,
					h: item.height || 0,
					title: item.caption,
					o: {
						src: item.src,
						w: item.width || 0,
						h: item.height || 0,
					},
					...(item.srcMedium
						? {
								m: {
									src: item.srcMedium,
									w: item.srcMediumWidth || 0,
									h: item.srcMediumHeight || 0,
								},
								msrc: item.srcMedium,
							}
						: {}),
				});
			}
		});

		const $pswpElement = $('.vp-pswp');
		const pswpElement = $pswpElement[0];

		// define options (if needed)
		const options = {
			captionAndToolbarShowEmptyCaptions: false,
			closeEl: settingsPopupGallery.show_close_button,
			captionEl: true,
			fullscreenEl: settingsPopupGallery.show_fullscreen_button,
			zoomEl: settingsPopupGallery.show_zoom_button,
			shareEl: settingsPopupGallery.show_share_button,
			counterEl: settingsPopupGallery.show_counter,
			arrowEl: settingsPopupGallery.show_arrows,
			shareButtons: [
				{
					id: 'facebook',
					label: __.pswp_share_fb,
					url: 'https://www.facebook.com/sharer/sharer.php?u={{url}}',
				},
				{
					id: 'x',
					label: __.pswp_share_x,
					url: 'https://x.com/intent/tweet?text={{text}}&url={{url}}',
				},
				{
					id: 'pinterest',
					label: __.pswp_share_pin,
					url: 'https://www.pinterest.com/pin/create/button/?url={{url}}&media={{image_url}}&description={{text}}',
				},
			],
			getImageURLForShare() {
				const currentItem = items[pswpInstance.getCurrentIndex()];

				if (currentItem.type === 'image' && currentItem.src) {
					return currentItem.src;
				}

				return pswpInstance.currItem.src || '';
			},
			getPageURLForShare() {
				const currentItem = items[pswpInstance.getCurrentIndex()];

				if (currentItem.type === 'image' && currentItem.src) {
					return currentItem.src;
				}

				return window.location.href;
			},
			getTextForShare() {
				const currentItem = items[pswpInstance.getCurrentIndex()];

				if (currentItem.caption) {
					const $caption = $(currentItem.caption);

					if (
						$caption.filter('.vp-portfolio__item-popup-title')
							.length
					) {
						return $caption
							.filter('.vp-portfolio__item-popup-title')
							.text();
					}
					if (
						$caption.filter('.vp-portfolio__item-popup-description')
							.length
					) {
						return $caption
							.filter('.vp-portfolio__item-popup-description')
							.text();
					}
				}

				return '';
			},
			bgOpacity: 1,
			tapToClose: false,
			tapToToggleControls: true,
			showHideOpacity: true,
			history: false,
			getThumbBoundsFn(thumbIndex) {
				if (!finalItems[thumbIndex] || !finalItems[thumbIndex].el) {
					return false;
				}

				const $el = $(finalItems[thumbIndex].el).find('img')[0];

				if (!$el) {
					return false;
				}

				const rect = $el.getBoundingClientRect();
				const pageYScroll =
					window.pageYOffset || document.documentElement.scrollTop;
				const pswpTop = parseFloat($pswpElement.css('top')) || 0;

				return {
					x: rect.left,
					y: rect.top + pageYScroll - pswpTop,
					w: rect.width,
					h: rect.height,
				};
			},
			getDoubleTapZoom(isMouseClick, item) {
				// isMouseClick          - true if mouse, false if double-tap
				// item                  - slide object that is zoomed, usually current
				// item.initialZoomLevel - initial scale ratio of image
				//                         e.g. if viewport is 700px and image is 1400px,
				//                              initialZoomLevel will be 0.5
				if (isMouseClick) {
					// is mouse click on image or zoom icon

					// Click to zoom disabled.
					if (!settingsPopupGallery.click_to_zoom) {
						return item.initialZoomLevel;
					}

					// In case the image is vertically wide, zoom it to fit screen width only.
					// - check if original image size is wider than screen
					// - check if zoomed out image in less than 25% of the screen width
					if (
						item.w > window.innerWidth &&
						(item.w * item.initialZoomLevel) / window.innerWidth <
							0.25
					) {
						return window.innerWidth / item.w;
					}

					// zoom to original
					return 1;

					// e.g. for 1400px image:
					// 0.5 - zooms to 700px
					// 2   - zooms to 2800px
				}

				// zoom to original if initial zoom is less than 0.7x,
				// otherwise to 1.5x, to make sure that double-tap gesture always zooms image.
				return item.initialZoomLevel < 0.7 ? 1 : 1.5;
			},
		};

		options.index = parseInt(index, 10);

		// exit if index not found
		if (!isNumber(options.index)) {
			return;
		}

		// Pass data to PhotoSwipe and initialize it
		pswpInstance = new PhotoSwipe(
			pswpElement,
			PhotoSwipeUIDefault,
			finalItems,
			options
		);

		// see: http://photoswipe.com/documentation/responsive-images.html
		let realViewportWidth;
		let useLargeImages = false;
		let firstResize = true;
		let imageSrcWillChange;

		pswpInstance.listen('beforeResize', () => {
			// pswpInstance.viewportSize.x - width of PhotoSwipe viewport
			// pswpInstance.viewportSize.y - height of PhotoSwipe viewport
			// window.devicePixelRatio - ratio between physical pixels and device independent pixels (Number)
			//                          1 (regular display), 2 (@2x, retina) ...

			// calculate real pixels when size changes
			realViewportWidth =
				pswpInstance.viewportSize.x * window.devicePixelRatio;

			// Code below is needed if you want image to switch dynamically on window.resize

			// Find out if current images need to be changed
			if (useLargeImages && realViewportWidth < 1000) {
				useLargeImages = false;
				imageSrcWillChange = true;
			} else if (!useLargeImages && realViewportWidth >= 1000) {
				useLargeImages = true;
				imageSrcWillChange = true;
			}

			// Invalidate items only when source is changed and when it's not the first update
			if (imageSrcWillChange && !firstResize) {
				// invalidateCurrItems sets a flag on slides that are in DOM,
				// which will force update of content (image) on window.resize.
				pswpInstance.invalidateCurrItems();
			}

			if (firstResize) {
				firstResize = false;
			}

			imageSrcWillChange = false;
		});

		pswpInstance.listen('gettingData', (idx, item) => {
			// Prepare iframes.
			if (item.html) {
				// -- Iframe Autoplay - Part 1 --
				// Disable autoplay parameter in iframes on inactive slides.
				// Mostly for Youtube and Vimeo to prevent video playing in background.
				// Later we add autoplay only to active slides.
				item.html = item.html.replace(/autoplay=1/, 'autoplay=0');

				return;
			}

			// Prepare image sizes.
			if (useLargeImages && item.o) {
				if (item.o.src) {
					item.src = item.o.src;
				}
				if (item.o.w) {
					item.w = item.o.w;
				}
				if (item.o.h) {
					item.h = item.o.h;
				}
			} else if (item.m) {
				if (item.m.src) {
					item.src = item.m.src;
				}
				if (item.m.w) {
					item.w = item.m.w;
				}
				if (item.m.h) {
					item.h = item.m.h;
				}
			}
		});

		pswpInstance.listen('imageLoadComplete', (idx, item) => {
			if (item.h < 1 || item.w < 1) {
				const img = new Image();

				img.onload = () => {
					item.w = img.width;
					item.h = img.height;
					pswpInstance.invalidateCurrItems();
					pswpInstance.updateSize(true);
				};

				img.src = item.src;
			}
		});

		pswpInstance.listen('resize', function () {
			resizeVideo(this);
		});

		pswpInstance.listen('afterChange', function () {
			// Download button.
			const $downloadButton = settingsPopupGallery.show_download_button
				? this.template.querySelector('.pswp__button--download')
				: false;

			if ($downloadButton) {
				if (this.currItem.html) {
					$downloadButton.classList.add('pswp__element--disabled');
				} else {
					$downloadButton.classList.remove('pswp__element--disabled');
					$downloadButton.setAttribute(
						'href',
						this.currItem?.o?.src || this.currItem?.m?.src
					);
				}
			}

			resizeVideo(this);

			VPPopupAPI.emitEvent(
				'afterChangePhotoSwipe',
				[this, pswpInstance],
				self
			);
		});

		// disable video play if no active.
		pswpInstance.listen('beforeChange', function () {
			const data = this;

			// -- Iframe Autoplay - Part 2 --
			// Set autoplay to 1 on active slides and to 0 on inactive.
			if (data && data.itemHolders.length) {
				const currentIndex = data.getCurrentIndex();

				data.itemHolders.forEach((val) => {
					const $iframe = val.el
						? $(val.el).find('.vp-pswp-video iframe')
						: false;

					if ($iframe && $iframe.length) {
						if (val.index === currentIndex) {
							$iframe.attr(
								'src',
								$iframe
									.attr('src')
									.replace(/autoplay=0/, 'autoplay=1')
							);
						} else {
							$iframe.attr(
								'src',
								$iframe
									.attr('src')
									.replace(/autoplay=1/, 'autoplay=0')
							);
						}
					}
				});
			}

			VPPopupAPI.emitEvent(
				'beforeChangePhotoSwipe',
				[data, pswpInstance],
				self
			);
		});

		// destroy event.
		pswpInstance.listen('destroy', function () {
			const data = this;

			if (data) {
				// Remove video block.
				if (data.itemHolders.length) {
					data.itemHolders.forEach((val) => {
						if (val.el) {
							$(val.el).find('.vp-pswp-video').remove();
						}
					});
				}

				const currentItemData = items[data.getCurrentIndex()];

				if (currentItemData) {
					VPPopupAPI.maybeFocusGalleryItem(currentItemData);
				}

				VPPopupAPI.emitEvent(
					'beforeClosePhotoSwipe',
					[options, items, pswpInstance],
					self
				);
			}

			pswpInstance = false;
		});

		VPPopupAPI.emitEvent(
			'beforeInitPhotoSwipe',
			[options, finalItems, index, pswpInstance],
			self
		);

		pswpInstance.init();

		VPPopupAPI.emitEvent(
			'initPhotoSwipe',
			[options, finalItems, index, pswpInstance],
			self
		);
	};
	VPPopupAPI.close = function () {
		if (pswpInstance) {
			pswpInstance.close();
			pswpInstance = false;
		}
	};
}
