(function(){
	const config = window.VidVix || {};
	const roots = document.querySelectorAll('.vidvix-player[data-video-id]');
	if (!roots.length) return;

	const setStatus = (root, text) => {
		const el = root.querySelector('.vidvix-status');
		if (el) el.textContent = text;
	};

	const showVideo = (root, url) => {
		const wrap = root.querySelector('.vidvix-video-wrap');
		const video = root.querySelector('video');
		const rentButton = root.querySelector('.vidvix-rent-button');
		const buttons = root.querySelector('.vidvix-paypal-buttons');
		if (video) {
			video.addEventListener('loadedmetadata', () => {
				if (wrap) wrap.hidden = false;
				setStatus(root, 'Access granted for ' + config.rentHours + ' hours.');
			}, {once: true});
			video.addEventListener('error', () => {
				if (wrap) wrap.hidden = true;
				setStatus(root, 'Access granted, but this video could not be loaded. Please check the saved file or URL.');
			}, {once: true});
			video.src = url;
			video.load();
		}
		if (wrap) wrap.hidden = true;
		if (rentButton) rentButton.hidden = true;
		if (buttons) buttons.innerHTML = '';
		if (buttons) buttons.hidden = true;
		setStatus(root, 'Loading video...');
	};

	const showRentalButton = (root, videoId, priceLabel) => {
		const rentButton = root.querySelector('.vidvix-rent-button');
		const buttons = root.querySelector('.vidvix-paypal-buttons');
		if (buttons) buttons.hidden = true;
		if (!rentButton) {
			renderButtons(root, videoId, priceLabel);
			return;
		}

		rentButton.textContent = priceLabel || 'Rent this video';
		rentButton.hidden = false;
		setStatus(root, '');

		if (!rentButton.dataset.vidvixBound) {
			rentButton.addEventListener('click', () => {
				rentButton.hidden = true;
				renderButtons(root, videoId, rentButton.textContent);
			});
			rentButton.dataset.vidvixBound = 'true';
		}
	};

	const waitForPayPalButtons = () => new Promise((resolve) => {
		if (window.paypal && window.paypal.Buttons) {
			resolve(true);
			return;
		}

		let attempts = 0;
		const timer = window.setInterval(() => {
			attempts += 1;
			if (window.paypal && window.paypal.Buttons) {
				window.clearInterval(timer);
				resolve(true);
				return;
			}
			if (attempts >= 30) {
				window.clearInterval(timer);
				resolve(false);
			}
		}, 100);
	});

	const renderButtons = async (root, videoId, priceLabel) => {
		const mount = root.querySelector('.vidvix-paypal-buttons');
		const rentButton = root.querySelector('.vidvix-rent-button');
		if (!mount) {
			if (rentButton) rentButton.hidden = false;
			setStatus(root, 'PayPal is not ready. Please check plugin settings.');
			return;
		}

		if (!window.paypal || !window.paypal.Buttons) {
			if (!config.paypalClientId) {
				if (rentButton) rentButton.hidden = false;
				setStatus(root, 'PayPal Client ID is missing. Please save it in VidVix settings.');
				return;
			}

			setStatus(root, 'Loading PayPal...');
			const isReady = await waitForPayPalButtons();
			if (!isReady) {
				if (rentButton) rentButton.hidden = false;
				setStatus(root, 'PayPal is not ready. Please check plugin settings.');
				return;
			}
		}

		if (mount.dataset.rendered) {
			mount.hidden = false;
			setStatus(root, priceLabel || 'Choose a payment method');
			return;
		}

		mount.hidden = false;
		mount.innerHTML = '';
		setStatus(root, 'Choose a payment method');

		window.paypal.Buttons({
			createOrder: async () => {
				const response = await fetch(config.restBase + 'paypal/create-order', {
					method: 'POST',
					credentials: 'same-origin',
					headers: {'Content-Type': 'application/json'},
					body: JSON.stringify({video_id: videoId})
				});
				const data = await response.json();
				if (!response.ok || !data.orderID) {
					throw new Error(data.message || 'Could not create PayPal order.');
				}
				return data.orderID;
			},
			onApprove: async (data) => {
				setStatus(root, 'Finalizing payment...');
				const response = await fetch(config.restBase + 'paypal/capture-order', {
					method: 'POST',
					credentials: 'same-origin',
					headers: {'Content-Type': 'application/json'},
					body: JSON.stringify({orderID: data.orderID, video_id: videoId})
				});
				const payload = await response.json();
				if (!response.ok || !payload.ok) {
					setStatus(root, payload.message || 'Payment succeeded, but the video could not be unlocked.');
					return;
				}
				if (payload.stream_url) {
					showVideo(root, payload.stream_url);
					return;
				}
				setStatus(root, 'Access granted. Loading video...');
				await loadState(root, videoId);
			},
			onCancel: () => {
				if (rentButton) rentButton.hidden = false;
				mount.hidden = true;
				setStatus(root, '');
			},
			onError: () => {
				if (rentButton) rentButton.hidden = false;
				mount.hidden = true;
				setStatus(root, 'Payment could not be completed.');
			}
		}).render(mount).then(() => {
			mount.dataset.rendered = 'true';
		});
	};

	const loadState = async (root, videoId) => {
		setStatus(root, 'Checking access...');
		const response = await fetch(config.restBase + 'video/' + encodeURIComponent(videoId) + '/status', {
			credentials: 'same-origin'
		});
		const data = await response.json();
		if (!response.ok || !data) {
			setStatus(root, 'Could not load this video right now.');
			return;
		}
		if (data.status === 'unlocked' && data.stream_url) {
			showVideo(root, data.stream_url);
			return;
		}
		if (data.status === 'locked') {
			showRentalButton(root, videoId, data.price_label);
			return;
		}
		setStatus(root, data.message || 'This video is unavailable right now.');
	};

	roots.forEach((root) => {
		loadState(root, root.getAttribute('data-video-id'));
	});
})();
