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,

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

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

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

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

		get unvalidatedSorted() {
			return 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;
			});
		},

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

		get unvalidatedFiltered() {
			if (!this.filterTable) return this.unvalidatedList;
			const searchTerm = this.filterTable.toLowerCase();
			return this.unvalidatedList.filter(item =>
				Object.values(item).some(value =>
					String(value).toLowerCase().includes(searchTerm)
				)
			);
		},

		get unvalidatedCount() {
			return this.unvalidatedList.length;
		},

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

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

			this.$watch('filterTable', () => {
				this.currentPage = 1;
			});

			// Auto-fetch on page load
			this.fetchUnvalidated();

			// Keyboard shortcuts for dialog
			document.addEventListener('keydown', (e) => {
				if (this.isDialogValOpen) {
					// N key - skip to next
					if (e.key === 'n' || e.key === 'N') {
						if (!e.target.closest('input, textarea, button')) {
							e.preventDefault();
							this.skipToNext();
						}
					}
				}
			});
		},

		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 ?? [];
			}).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,
		toast: { show: false, message: '', type: 'success' },

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

		openValDialogByIndex(index) {
			const filtered = this.unvalidatedFiltered;
			if (index < 0 || index >= filtered.length) {
				this.showToast('No more requests', 'error');
				this.closeValDialog();
				return;
			}
			const item = filtered[index];
			this.currentIndex = index;
			this.valAccessnumber = item.SP_ACCESSNUMBER;
			this.valItem = item;
			this.isDialogValOpen = true;
			// Focus validate button after dialog renders - use setTimeout for reliability
			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;
		},

		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 (!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 => {
				if (data.val === 2) {
					this.showToast(`Validated (val2): ${accessnumber} - PDF queued`);
				} 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}`;
		},
	}));
});
