document.addEventListener('alpine:init', () => {
	Alpine.data("validatePage", () => ({
		// validate page specific
		unvalidatedList: [],
		isLoading: false,
		isValidating: false,

		// Date filter - missing in original code!
		filter: { date1: "", date2: "" },
		filterTable: "",

		// Sorting & Pagination (shared with dashboard)
		sortCol: 'REQDATE',
		sortAsc: false,
		currentPage: 1,
		pageSize: 30,

		// Cached computed properties to prevent memory leak
		unvalidatedFiltered: [],
		unvalidatedSorted: [],
		unvalidatedPaginated: [],
		unvalidatedTotalPages: 1,
		unvalidatedCount: 0,

		sort(col) {
			if (this.sortCol === col) {
				this.sortAsc = !this.sortAsc;
			} else {
				this.sortCol = col;
				this.sortAsc = true;
			}
			this.computeUnvalidatedSorted();
			this.computeUnvalidatedPaginated();
		},

		nextPage() {
			if (this.currentPage < this.unvalidatedTotalPages) {
				this.currentPage++;
				this.computeUnvalidatedPaginated();
			}
		},

		prevPage() {
			if (this.currentPage > 1) {
				this.currentPage--;
				this.computeUnvalidatedPaginated();
			}
		},

		setFilterTable(value) {
			this.filterTable = value;
			this.currentPage = 1;
			this.computeUnvalidatedFiltered();
			this.computeUnvalidatedSorted();
			this.computeUnvalidatedTotalPages();
			this.computeUnvalidatedPaginated();
		},

		// Compute methods - called only when dependencies change
		computeUnvalidatedFiltered() {
			if (!this.filterTable) {
				this.unvalidatedFiltered = this.unvalidatedList;
			} else {
				const searchTerm = this.filterTable.toLowerCase();
				this.unvalidatedFiltered = this.unvalidatedList.filter(item =>
					Object.values(item).some(value =>
						String(value).toLowerCase().includes(searchTerm)
					)
				);
			}
		},

		computeUnvalidatedSorted() {
			this.unvalidatedSorted = this.unvalidatedFiltered.slice().sort((a, b) => {
				let modifier = this.sortAsc ? 1 : -1;
				if (a[this.sortCol] < b[this.sortCol]) return -1 * modifier;
				if (a[this.sortCol] > b[this.sortCol]) return 1 * modifier;
				return 0;
			});
		},

		computeUnvalidatedPaginated() {
			const start = (this.currentPage - 1) * this.pageSize;
			const end = start + this.pageSize;
			this.unvalidatedPaginated = this.unvalidatedSorted.slice(start, end);
		},

		computeUnvalidatedTotalPages() {
			this.unvalidatedTotalPages = Math.ceil(this.unvalidatedFiltered.length / this.pageSize) || 1;
		},

		computeUnvalidatedCount() {
			this.unvalidatedCount = this.unvalidatedList.length;
		},

		init() {
			this.today = new Date().toISOString().slice(0, 10);

			this.filter.date1 = this.today;
			this.filter.date2 = this.today;

			// Initial load only - no auto-refresh
			this.fetchUnvalidated();

			// Keyboard shortcuts - added/removed when dialog opens/closes
			this._keyboardHandler = (e) => {
				if (this.isDialogValOpen) {
					if (e.key === 'n' || e.key === 'N') {
						if (!e.target.closest('input, textarea, button')) {
							e.preventDefault();
							this.skipToNext();
						}
					}
				}
			};
			document.addEventListener('keydown', this._keyboardHandler);
		},

		fetchUnvalidated() {
			this.isLoading = true;
			this.unvalidatedList = [];
			let param = new URLSearchParams(this.filter).toString();
			fetch(`${BASEURL}/api/validate/unvalidated?${param}`, {
				method: 'GET',
				headers: { 'Content-Type': 'application/json' },
			}).then(res => res.json()).then(data => {
				this.unvalidatedList = data.data ?? [];
				// Compute derived data after list is loaded
				this.computeUnvalidatedFiltered();
				this.computeUnvalidatedCount();
				this.computeUnvalidatedSorted();
				this.computeUnvalidatedTotalPages();
				this.computeUnvalidatedPaginated();
			}).finally(() => {
				this.isLoading = false;
			});
		},

		resetUnvalidated() {
			this.filter.date1 = this.today;
			this.filter.date2 = this.today;
			this.fetchUnvalidated();
		},

		/*
		 * validate dialog methods
		 */
		valAccessnumber: null,
		valItem: null,
		currentIndex: 0,
		isDialogValOpen: false,
		isIframeLoaded: false,
		validationDelayRemaining: 0,
		validationTimer: null,
		toast: { show: false, message: '', type: 'success' },

		showToast(message, type = 'success') {
			this.toast = { show: true, message, type };
			setTimeout(() => {
				this.toast.show = false;
			}, 2000);
		},

		onIframeLoad() {
			this.isIframeLoaded = true;
			this.validationDelayRemaining = 1;
			this.validationTimer = setInterval(() => {
				this.validationDelayRemaining--;
				if (this.validationDelayRemaining <= 0) {
					clearInterval(this.validationTimer);
					this.validationTimer = null;
				}
			}, 1000);
		},

		openValDialogByIndex(index) {
			const filtered = this.unvalidatedFiltered;
			if (index < 0 || index >= filtered.length) {
				this.showToast('No more requests', 'error');
				this.closeValDialog();
				return;
			}
			// Reset iframe loading state
			this.isIframeLoaded = false;
			this.validationDelayRemaining = 0;
			if (this.validationTimer) {
				clearInterval(this.validationTimer);
				this.validationTimer = null;
			}
			const item = filtered[index];
			this.currentIndex = index;
			this.valAccessnumber = item.SP_ACCESSNUMBER;
			this.valItem = item;
			this.isDialogValOpen = true;
			// Re-add keyboard handler when dialog opens
			if (this._keyboardHandler) {
				document.addEventListener('keydown', this._keyboardHandler);
			}
			setTimeout(() => {
				const btn = document.getElementById('validate-btn');
				if (btn) btn.focus();
			}, 50);
		},

		openValDialog(accessnumber) {
			// Find index by accessnumber
			const filtered = this.unvalidatedFiltered;
			const index = filtered.findIndex(item => item.SP_ACCESSNUMBER === accessnumber);
			if (index !== -1) {
				this.openValDialogByIndex(index);
			} else {
				this.openValDialogByIndex(0);
			}
		},

		closeValDialog() {
			this.isDialogValOpen = false;
			this.valAccessnumber = null;
			this.valItem = null;
			if (this.validationTimer) {
				clearInterval(this.validationTimer);
				this.validationTimer = null;
			}
			this.validationDelayRemaining = 0;
			this.isIframeLoaded = false;
			// Remove keyboard handler when dialog closes
			if (this._keyboardHandler) {
				document.removeEventListener('keydown', this._keyboardHandler);
				this._keyboardHandler = null;
			}
		},

		skipToNext() {
			const nextIndex = (this.currentIndex + 1) % this.unvalidatedFiltered.length;
			this.closeValDialog();
			// Use setTimeout for reliable focus after dialog re-renders
			setTimeout(() => this.openValDialogByIndex(nextIndex), 50);
		},

		validate(accessnumber, userid) {
			if (!this.isIframeLoaded || this.validationDelayRemaining > 0) {
				this.showToast('Please wait for the report to load', 'error');
				return;
			}
			if (!confirm(`Validate request ${accessnumber}?`)) return;
			this.isValidating = true;
			fetch(`${BASEURL}/api/requests/validate/${accessnumber}`, {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({ userid: `${userid}` })
			}).then(response => response.json()).then(data => {
				console.log(data);
				if (data.val === 2) {
					this.showToast(`Validated (val2): ${data.accessnumber} - PDF queued`);
					// Trigger PDF auto-generation after val2
					fetch(`${BASEURL}/report/${data.accessnumber}/pdf`).then(res => res.json()).then(pdfData => {
						if (pdfData.success) {
							console.log('PDF generation queued:', pdfData.jobId);
						} else {
							console.error('PDF generation failed:', pdfData.error);
						}
					}).catch(err => {
						console.error('PDF generation request failed:', err);
					});
				} else {
					this.showToast(`Validated: ${accessnumber}`);
				}

				this.unvalidatedList = this.unvalidatedList.filter(
					item => item.SP_ACCESSNUMBER !== accessnumber
				);

				const filteredLength = this.unvalidatedFiltered.length;
				if (filteredLength > 0) {
					const nextIndex = Math.min(this.currentIndex, filteredLength - 1);
					this.closeValDialog();
					setTimeout(() => this.openValDialogByIndex(nextIndex), 50);
				} else {
					this.closeValDialog();
					this.showToast('All requests validated!');
				}

				if (data.message && data.message.includes('already validate')) {
					alert(data.message);
				}
			}).catch(() => {
				this.showToast('Validation failed', 'error');
			}).finally(() => {
				this.isValidating = false;
			});
		},

		getPreviewUrl() {
			return `<?=base_url()?>report/${this.valAccessnumber}`;
		},
	}));
});
