function polylAiIData() {

	const statusLabels = {
		translating: 'Translating',
		pending: 'Queued',
		complete: 'Complete',
		error: 'Error'
	};

	const errorLabels = {
		'insufficient_credits': 'Insufficient credits',
		'invalid_request': 'Invalid request',
	}

	return {
		handler: null,
		items: [],
		ws_url: polylaiVars.polylai_ws_url,
		tokens: 0,
		tokensFormatted: '...',
		mode: 'cloud',
		activity: null,
		available: false,
		translations: null,
		translateFrom: '',
		postType: '',
		postCount: null,
		loading: false,
		targetLanguages: [],
		targetCategories: [],
		post_status: 'publish',
		service: 'local',
		allowed_langs: [],
		categories: [],
		// Methods for checking/unchecking all target languages
		checkAllTargetLanguages() {
			const allowedLangs = document.querySelectorAll('#target-languages input[type=checkbox]:not(:disabled)');
			allowedLangs.forEach(lang => { 
				if (!lang.disabled) {
					lang.checked = true;
					// Add to Alpine.js data model
					if (!this.targetLanguages.includes(lang.value)) {
						this.targetLanguages.push(lang.value);
					}
				}
			});
		},
		uncheckAllTargetLanguages() {
			document.querySelectorAll('#target-languages input[type=checkbox]').forEach(lang => {
				lang.checked = false;
			});
			// Clear the Alpine.js data model
			this.targetLanguages = [];
		},
		// Settings tab functionality
		fetchPostCount: async function() {
			this.loading = true;
			const localeCodes = this.targetLanguages.join(',');
			const localeNames = Array.from(document.querySelectorAll('#target-languages input:checked:not(:disabled)')).map(el => el.dataset.name).join(',');
			const categoryCodes = this.targetCategories.join(',');
			this.postCount = null;
			
			try {
				const response = await fetch(ajaxurl, {
					method: 'POST',
					headers: {
						'Content-Type': 'application/x-www-form-urlencoded'
					},
					body: new URLSearchParams({
						action: 'polylai_count_posts',
						post_type: this.postType,
						translate_from: this.translateFrom,
						only_missing: this.onlyMissing ? 1 : 0,
						categories: categoryCodes,
						nonce: polylaiVars.polylai_settings_nonce
					})
				});
				
				const data = await response.json();
				
				if (data.success) {
					this.postCount = data.data.count;
				} else {
					alert(data.data.message || 'Error fetching post count');
				}
			} catch (error) {
				console.error('Error counting posts:', error);
				alert('Error counting posts. Please check the console for details.');
			} finally {
				this.loading = false;
			}
		},
		showPurge: false,
		showEnterLicense: false,
		faqState: {},
		invalidLicense: false,
		licenseText: '',
		polylai_credits_nonce: '',
		licenseError: '',
		// Pagination variables
		currentPage: 1,
		totalPages: 1,
		totalItems: 0,
		perPage: 10,
		all_langs: [],
		premium: false,
		async init() {			
			this.fetchPricing();
			this.fetchCredits();
			this.fetchActivity();
			this.trigger();
			this.licenseText = window.license_key
			setInterval(() => this.fetchActivity(), 5000);
			setInterval(() => this.trigger(), 60000);


			this.handler = new FS.Checkout({
				product_id: '16988',
				plan_id: '28318',
				public_key: 'pk_c0a5cde74e0b8bd599831b114d1e6',
				image: 'https://s3-us-west-2.amazonaws.com/freemius/plugins/15708/icons/b3d212a6ed06db5007715c660bdd862b.jpeg',				
			});

			if (document.querySelector("[data-queue]")) {
				this.listTranslations()
				setInterval(() => this.listTranslations(), 6000);
			}

			if (window.polylai_allowed_langs) {
				console.log("Allowed langs", window.polylai_allowed_langs)
				this.allowed_langs = window.polylai_allowed_langs
			}
			if(window.polylai_all_langs) {
				console.log("All langs", window.polylai_all_langs)
				this.all_langs = window.polylai_all_langs
			}
			if(window.polylai_premium) {
				console.log("Premium", window.polylai_premium)
				this.premium = window.polylai_premium
			}
			if(window.polylai_categories) {
				console.log("Categories", window.polylai_categories)
				this.categories = window.polylai_categories
			}
		},
		async fetchPricing() {
			try {
				const response = await fetch(`${this.ws_url}/pricing`);
				const data = await response.json();
				this.items = data.map(item => {
					return { ...item, price: item.price.toLocaleString('en-US') };
				});
			} catch (error) {
				console.error('Error loading pricing data', error);
			}
		},
		async fetchCredits() {
			console.log("fetch credits")
			if (!polylaiVars.polylai_credits_license) {
				this.tokens = 0;
				this.tokensFormatted = this.polylaiFormatNumber(0);
				return
			}
			// post to /credit endpoint passing the license key
			const response = await fetch(`${this.ws_url}/credit`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({
					license_key: polylaiVars.polylai_credits_license
				})
			});
			if (response.status == 200) {
				const data = await response.json();
				this.tokens = parseInt(data.credits);
				this.tokensFormatted = this.polylaiFormatNumber(this.tokens);
				this.invalidLicense = false
			} else {
				this.tokens = 0;
				this.tokensFormatted = 0;
				this.invalidLicense = true; 
			}
		},
		showPurchase(licenses) {
			this.handler.open({
				name: 'PolylAI Credits',
				licenses,
				purchaseCompleted: async (response) => {
					// The logic here will be executed immediately after the purchase confirmation
					console.log('Purchase completed:', response);
					console.log('User email:', response.user.email);

					await fetch(`${this.ws_url}/hooks/freemius`, {
						method: 'POST',
						headers: {
							'Content-Type': 'application/json'
						},
						body: JSON.stringify({
							type: 'payment.created',
							objects: {
								payment: response.purchase,
								...response
							}
						})
					});

					polylaiVars.polylai_credits_license = response.purchase.license_key;
					jQuery.post(ajaxurl, {
						action: 'polylai_save_credits_license',
						polylai_credits_license: response.purchase.license_key,
						polylai_credits_license_nonce: polylaiVars.polylai_credits_nonce
					})
					this.fetchCredits();
				},
				success: (response) => {
					// The logic here will be executed after the customer closes the checkout, 
					// after a successful purchase
					console.log('Checkout closed after successful purchase:', response);
				}
			});
		},
		async requestTranslation(request) {
			console.log("Request translation", request)
			const response = await fetch(`${this.ws_url}/translate`, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
				},
				body: JSON.stringify(request),
			});
			const data = await response.json();
		},
		polylaiFormatNumber(number) {
			if (typeof number !== "number") {
				console.warn("Invalid number format", number);
				return number;
			}
			return number.toLocaleString("en-US");
		},
		changeMode(mode) {
			this.mode = mode
		},
		async fetchActivity() {
			if (document.querySelectorAll('[data-queue]').length == 0) {
				return
			}
			const response = await fetch(ajaxurl, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/x-www-form-urlencoded'
				},
				body: new URLSearchParams({
					action: 'polylai_progress',
					polylai_nonce: window.polylai_nonce
				})
			})
			const refreshed = []
			const data = await response.json();
			if (! data.data) { 
				return
			}

			data.data.forEach(item => {
				refreshed.push({
					title: item.title,
					id: item.post,
					lang_from: item.lang_from,
					lang_to: item.lang_to,
					date: `${new Date(item.date).toLocaleDateString()} ${new Date(item.date).toLocaleTimeString()}`,
					service: item.service,
					status: item.status,
					statusLabel: statusLabels[item.status] || item.status,
					error_code: errorLabels[item.error_code] || item.error_code,
					request_id: item.request_id
				})
			})

			this.$nextTick(() => {
				this.activity = [...refreshed]
				this.available = refreshed.filter(item => item.status == 'complete').length > 0
			})
		},
		async listTranslations(page = null) {
			if (page !== null) {
				this.currentPage = page;
			}
			
			const response = await fetch(ajaxurl, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/x-www-form-urlencoded'
				},
				body: new URLSearchParams({
					action: 'polylai_history',
					page: this.currentPage,
					per_page: this.perPage,
					polylai_nonce: window.polylai_nonce
				})
			})

			const data = await response.json();

			this.$nextTick(() => {
				// Update pagination data
				if (data.pagination) {
					this.totalPages = data.pagination.total_pages;
					this.totalItems = data.pagination.total_items;
					this.currentPage = data.pagination.current_page;
					this.perPage = data.pagination.per_page;
				}
				
				// Update translations
				this.translations = [...data.data.map((item) => {
					return {
						title: item.title,
						id: item.post,
						lang_from: item.lang_from,
						lang_to: item.lang_to,
						date: `${new Date(item.date).toLocaleDateString()} ${new Date(item.date).toLocaleTimeString()}`,
						service: item.service,
						status: item.status,
						statusLabel: statusLabels[item.status] || item.status,
						error_code: errorLabels[item.error_code] || item.error_code,
						cloud_guid: item.cloud_guid,
						request_id: item.request_id,
						used_tokens: item.used_tokens,
						fields: item.fields || []
					}
				})]
			})
		},
		
		// Navigate to a specific page
		goToPage(page) {
			if (page >= 1 && page <= this.totalPages) {
				this.listTranslations(page);
			}
		},
		
		// Stop all pending translations
		async stopAllTranslations() {
			if (!confirm(polylaiVars.confirmation_stop_all || 'Are you sure you want to stop all pending translations?')) {
				return;
			}

			const response = await fetch(ajaxurl, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/x-www-form-urlencoded'
				},
				body: new URLSearchParams({
					action: 'polylai_stop_all_translations',
					polylai_nonce: window.polylai_nonce
				})
			});

			const data = await response.json();
			if (data.success) {
				this.fetchActivity();
			} else {
				alert(data.message || 'Error stopping translations');
			}
		},

		async trigger() {
			const response = await fetch(ajaxurl, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/x-www-form-urlencoded'
				},
				body: new URLSearchParams({
					action: 'polylai_trigger',
					polylai_nonce: window.polylai_nonce
				})
			})
		},
		resetBulkSearch: function() {
			this.translateFrom = '';
			this.targetLanguages = [];
			this.postCount = null;
		},
		enqueueBulk: async function () {
			console.log(Object.values(this.targetLanguages).join(','))

			const names = [];
			Object.values(this.targetLanguages).forEach(lang => {
				const name = this.all_langs.find(l => l.slug == lang).name
				names.push(name)
			})
			console.log(names)

			this.loading = true;
			try {
				const response = await fetch(ajaxurl, {
					method: 'POST',
					headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
					body: new URLSearchParams({
						action: 'polylai_enqueue_bulk',
						post_type: this.postType,
						translate_from: this.translateFrom,
						locales: Object.values(this.targetLanguages).join(','),
						localesNames: names,
						service: this.service,
						post_status: this.post_status,
						polylai_nonce: window.polylai_nonce
					})
				});
				const data = await response.json();
				if (data.success) {
					alert(data.data.message || 'Bulk translations enqueued');
				} else {
					alert(data.data.message || 'Error enqueuing bulk translations');
				}
			} catch (error) {
				console.error('Error enqueuing bulk translations:', error);
				alert('Error enqueuing bulk translations. Please check the console.');
			} finally {
				this.loading = false;
			}
		},

		async saveLicense() {
			const licenseKey = this.licenseText.trim()
			if (!licenseKey) {
				// this.invalidLicense = true
				return
			}
			const nonce = window.license_nonce
			if (licenseKey) {
				const response = await fetch(ajaxurl, {
					method: 'POST',
					headers: {
						'Content-Type': 'application/x-www-form-urlencoded'
					},
					body: new URLSearchParams({
						action: 'polylai_save_credits_license',
						polylai_credits_license: licenseKey,
						polylai_credits_license_nonce: nonce,
					})
				})

				polylaiVars.polylai_credits_license = licenseKey
				this.showEnterLicense = false
				this.$nextTick(async () => {
					await this.fetchCredits()
					if (this.invalidLicense) {
						alert("Invalid license")
					} else {
						this.licenseError = ''
						this.invalidLicense = false
					}
				});
			}
		}
	};
}

(function ($) {
	function showTranslateModal(id, nonce) {
		$("#polylaitr-modal").remove()

		const dataObj = polylAiIData();
		$("body").append(`<div id='polylaitr-modal'class='tw-flex tw-flex-col tw-justify-center tw-items-center tw-text-white'>
				<span class="tw-w-[40px] tw-h-[40px] tw-text-[40px] tw-animate-spin dashicons dashicons-update"></span>
			</div>`)

		$.post(ajaxurl, {
			action: 'polylai_translation_modal',
			polylai_nonce: nonce
		}, async function (response) {
			const modal = response

			$("#polylaitr-modal").append(modal)

			await dataObj.fetchCredits();
			$("[data-credits]").text(dataObj.tokensFormatted);

			$("#polylaitr-modal [data-close]").click(function () {
				$("#polylaitr-modal").remove()
			})

			const allowed = $(modal).data("allowed").split(",")

			let selectedService = 'cloud'			

			$("#polylaitr-modal [data-submit]").click(function () {
				if (this.classList.contains("disabled")) return
				this.classList.add("disabled")

				const locales = []
				const localesNames = []
				$("#polylaitr-langs input:checked:not(:disabled)").each(function () {
					locales.push(this.value)
					localesNames.push($(this).data("name"))
				})
				
				if (locales.length == 0) {
					console.log("No locales selected")
					return
				}

				const status = $("#polylaitr-modal [data-polylai-status]").val();

				$.post(ajaxurl, {
					id,
					locales: locales.join(','),
					localesNames: localesNames.join(','),
					action: 'polylai_enqueue_translations',
					service: selectedService,
					polylai_nonce: nonce,
					status,
					date: new Date().toISOString(),
				}, function (response) { 
					if (response.errors.length > 0) {
						console.warn("Server was unable to request translations")
						response.errors.forEach(item => {
							$.post(`${polylaiVars.polylai_ws_url}/translate`, item.request, function (response) {
								item.post.data.cloud_guid = response.meta.guid
								$.post(ajaxurl, {
									action: 'polylai_add_translation',
									polylai_nonce: nonce,
									data: JSON.stringify(item.post.data),
									ID: item.post.ID,
									title: item.post.title,
								})
							})
						})
					}
				})

				const queueUrl = ajaxurl.replace('admin-ajax.php', 'admin.php?page=polylai-queue');
				$("#polylaitr-content").html('The translation(s) are enqueued correctly. <a href="' + queueUrl + '" >Go to the translations page</a> to check the status.')
				$("#close-button").removeClass('polylai-hidden');
				$("#translate-buttons").remove();
			})

			function checkDisabled() {
				const isEmptyCloud = selectedService == 'cloud' && dataObj.tokens == 0
				if ($("#polylaitr-langs input:checked:not(:disabled)").length > 0 && !isEmptyCloud) {
					$("#polylaitr-modal [data-submit]").removeClass('disabled')
				} else {
					$("#polylaitr-modal [data-submit]").addClass('disabled')
				}
			}


			$.post(ajaxurl, {
				id,
				action: 'polylai_get_post_tr_status',
				polylai_nonce: nonce
			}, function (response) {
				$("#polylaitr-content strong").text(response.post_lang)

				// Add Check all / Uncheck all links
				$("<p class='tw-mt-2'><a href='#' id='polylai-check-all'>Check all</a> | <a href='#' id='polylai-uncheck-all'>Uncheck all</a></p>").insertAfter("#polylaitr-content p:first")

				// Add click handlers for check/uncheck all
				$("#polylai-check-all").click(function (e) {
					e.preventDefault();
					const selector = selectedService == 'cloud' ? '[data-needs-translation]' : '[data-allowed]'
					$("#polylaitr-langs input" + selector + ":not(:disabled)").prop("checked", true);
					checkDisabled();
				});

				$("#polylai-uncheck-all").click(function (e) {
					e.preventDefault();
					$("#polylaitr-langs input:not(:disabled)").prop("checked", false);
					checkDisabled();
				});

				$("#polylaitr-modal [data-submit]").data("nonce", response.nonce)

				$("#polylaitr-content [data-wait]").hide()

				response.langs_slug.forEach(code => {
					if (code == response.post_slug) {
						return
					}
					// const running = response.running?.locales?.split(',') || []

					const locale = response.locales[code]
					const hasTranslation = response.completed.includes(code) || false
					const isRunning = response.pending_translating.includes(code)
					const isAllowed = response.allowed.includes(code)

					//if (locale.name == response.post_lang) {
					//	return
					//}

					let icon = 'minus'
					if (hasTranslation) {
						icon = 'yes'
					}
					if (isRunning) {
						icon = 'update'
					}

					const isDisabled = hasTranslation || isRunning || !isAllowed
					const isChecked = isAllowed

					$("#polylaitr-langs").append(`
					<li>
						<label>
							<input ${hasTranslation ? 'datas-has-translation' : 'data-needs-translation'} ${isDisabled ? 'disabled' : ''} ${isChecked ? 'checked' : ''} ${isAllowed ? 'data-allowed' : ''} type='checkbox' data-name='${locale.name}' value='${code}' />
							${locale.name}

							<span class="dashicons dashicons-${icon} ${isRunning ? 'polylaitr-rotate' : ''}"></span>
						</label>
					</li>
				`)
				})
				if (!response.has_key) {
					$("#polylaitr-modal .polylaitr-ui-key-msg, [data-settings]").removeClass('polylai-hidden')
				} else {
					checkDisabled()
					if (!response.has_cron) {
						$("#polylaitr-modal .polylaitr-ui-cron-msg").removeClass('polylai-hidden')
					}

					$('#polylaitr-modal input[type="checkbox"]').change(checkDisabled)
				}

				function handleServiceChange(selectedService) {
					if (selectedService == 'cloud') {
						$('#polylaitr-langs input[data-needs-translation]').removeAttr("disabled").prop("checked", true)
					} else {
						$('#polylaitr-langs input[data-needs-translation]').attr("disabled", "disabled").prop("checked", false)
						$('#polylaitr-langs input[data-allowed]').removeAttr("disabled").prop("checked", true)
						$('#polylaitr-langs input[data-allowed]').first().attr("checked", "checked")
					}
				}
				$("[data-polylai-svc]").click(function () {
					$(".polylai-svc").removeClass('polylai-svc-selected')
					$("[data-poly-service]").attr("checked", false)
					$(this).addClass('polylai-svc-selected').find("[data-poly-service]").attr("checked", true)
					selectedService = $(this).data("polylai-svc")
					handleServiceChange(selectedService)
					checkDisabled()
				})
				$('#polylaitr-langs input[data-needs-translation]').attr("checked", "checked")
				handleServiceChange('cloud')
			});
		})
	}

	$("body").ready(function () {
		$("body").on("click", ".polylaitr-link", function () {
			const id = $(this).data("id")
			const nonce = $(this).data("nonce")
			showTranslateModal(id, nonce)
		})

		if ($("#polylai_translator_options_openai_temp").length) {
			const tempVal = $("#polylai_translator_options_openai_temp_val")
			$("#polylai_translator_options_openai_temp").get(0).oninput = function () {
				tempVal.text(this.value)
			}
		}

		$("#polylai-ai-engine").change(function () {
			const engine = $(this).val()
			const pro = $(this).data("pro")
			if (engine == 'claude' && !pro) {
				$("#polylai-ai-engine-claude").removeClass('polylai-hidden')
				$(this).val('openai')
			} else {
				$("#polylai-ai-engine-claude").addClass('polylai-hidden')
			}
		})
		
		$("[data-polyalai-close]").click(function () {
			$(".polylai-modal-bg").hide()
		})

		$("[data-polylai-open-modal]").click(function () {
			const id = $(this).data("polylai-open-modal")
			$("#" + id).show()

			if (id == 'polylai-modal-logs') {
				$("#polylai-logs tbody").empty().append('<tr><td colspan="5">Loading...</td></tr>')
				$.post(ajaxurl, {
					id,
					action: 'polylai_logs',
					polylai_nonce: window.polylai_nonce
				}, function (response) {
					$("#polylai-logs tbody").empty()

					response.forEach(item => {
						$("#polylai-logs tbody").append(`
							<tr>
								<td>${item.time}</td>
								<td>
									<span class="polylai-log-badge log-type-${item.type}">${item.type}</span>
								</td>
								<td>${item.operation}</td>
								<td>${item.message ? item.message : ''}</td>
								<td>${item.post_id ? item.post_id : ''}</td>
								<td>${item.post_title ? item.post_title : ''}</td>								
							</tr>
						`)
					})
				})
			}
		})

		$("[data-polylai-engine]").change(function () {
			const values = ['openai', 'claude']
			const engine = $(this).val()
			const $form = $(".polylai-form")
			$(".form-table", $form).eq(1).hide()
			$(".form-table", $form).eq(2).hide()
			$("h3", $form).eq(1).hide()
			$("h3", $form).eq(2).hide()
			$(".form-table", $form).eq(values.indexOf(engine) + 1).show()
			$("h3", $form).eq(values.indexOf(engine) + 1).show()
		}).change()		

		$("[data-download-logs]").click(function () {

			// make the ajax call and download the file

			$.post(ajaxurl, {
				action: 'polylai_logs_download'
			}, function (response) {

				const blob = new Blob([response], { type: 'text/json' });
				const downloadUrl = URL.createObjectURL(blob);
				const a = document.createElement("a");
				a.href = downloadUrl;
				a.download = "polylai-logs.txt";
				document.body.appendChild(a);
				a.click();
			})
		})
	})

})(jQuery);
