document.addEventListener('DOMContentLoaded', () => {
	/* =========================
	ELEMENTS
	========================= */
	// Mengambil semua baris tabel yang akan diimport (tr dengan class 'ai-item')
	const rows = document.querySelectorAll('tr.ai-item');
	// → Koleksi NodeList berisi semua item yang akan diproses secara berurutan

	const progressContainer = document.getElementById('progress-container');
	// Container seluruh progress bar & teks progress

	const progressBar = document.getElementById('progress-bar');
	// Elemen yang lebarnya akan diubah (style.width) untuk menunjukkan persentase

	const progressText = document.getElementById('progress-text');
	// Elemen teks yang menampilkan "X / Y" item

	const currentGame = document.getElementById('current-game');
	// Elemen yang menampilkan judul item yang sedang diproses (nama game/aplikasi)

	const nonce = document.getElementById('nonce')?.value || '';
	// Ambil nonce dari input hidden untuk keamanan AJAX WordPress
	// Optional chaining (?.) + fallback '' → sangat aman, mencegah error jika elemen tidak ada

	const btnStart = document.getElementById('btn-start');
	const btnPause = document.getElementById('btn-pause');
	const btnStop  = document.getElementById('btn-stop');
	// Ketiga tombol kontrol utama proses import

	const baseUrlRow = document.getElementById('base_url');
	// Baris tabel (tr) yang berisi input base URL (akan di-hide/show tergantung source)

	const controlsWrapper = document.querySelector('.import-controls-wrapper');
	// Wrapper seluruh kontrol (tombol + setting) yang bisa jadi sticky saat import berjalan

	const baseDomainInput = document.getElementById('base_domain_url');
	// Input khusus untuk domain dasar (biasanya untuk custom source)

	// Catatan: baris ini dikomen, kemungkinan typo atau duplikat
	// const progressBar = document.querySelectorAll('progress-bar'); // ← seharusnya ID, bukan class

	const NoticeProgressCount = document.querySelectorAll('.progress-count');
	// Koleksi elemen yang menampilkan hitungan progress (mungkin ada beberapa di halaman)

	// ──────────────────────────────────────────────────────────────
	// Early return (guard clause) – sangat baik untuk mencegah error lebih lanjut
	// ──────────────────────────────────────────────────────────────
	if (!baseDomainInput) return;          // Jika input base domain tidak ada → hentikan script
	if (!rows.length || !btnStart) return; // Jika tidak ada item atau tombol start → hentikan script
	// → Praktik terbaik: jangan lanjutkan jika elemen kunci hilang

	// ──────────────────────────────────────────────────────────────
	// Elemen pengaturan tambahan (source & base URL)
	// ──────────────────────────────────────────────────────────────
	const sourceSelect = document.querySelector('select[name="auto_importer_settingss[source]"]');
	const baseUrlInput = document.querySelector('input[name="auto_importer_settingss[base_url]"]');
	// → Digunakan untuk disable/enable & notice custom source

	// ──────────────────────────────────────────────────────────────
	// Variabel state utama proses import
	// ──────────────────────────────────────────────────────────────
	let index = 0;              // Indeks item yang sedang diproses (mulai dari 0)
	let isRunning = false;      // Apakah proses sedang berjalan
	let isPaused  = false;      // Apakah sedang pause
	let isStopped = false;      // Apakah sudah di-stop (akan mencegah processNext lanjut)
	let timeoutId = null;       // ID dari setTimeout terakhir (untuk clearTimeout saat stop)

	// ──────────────────────────────────────────────────────────────
	// Statistik import – akan ditampilkan di ringkasan akhir
	// ──────────────────────────────────────────────────────────────
	let importStats = {
		total: 0,           // Total item yang diproses (seharusnya = rows.length)
		success: 0,
		duplicate: 0,
		missingImage: 0,
		draft: 0,
		error: 0
	};

	// ──────────────────────────────────────────────────────────────
	// Array untuk menyimpan log recent activity (10 terakhir)
	// ──────────────────────────────────────────────────────────────
	let recentLogs = []; // menyimpan 8–12 log terakhir saja
	// → Bagus, membatasi jumlah agar tidak membebani DOM

	// Catatan: fungsi addRecentLog & renderRecentLogs sudah ada di kode sebelumnya
	// (dan sudah dieksekusi via eval – meski cara ini kurang direkomendasikan di production)

	/**
	 * Menambahkan satu entri log ke daftar recent activity
	 * Log ditambahkan di paling atas (unshift), dibatasi maksimal 10 entri
	 * Setelah ditambah, langsung render ulang daftar di DOM
	 *
	 * @param {string} title      - Judul item/game yang sedang diproses
	 * @param {string} status     - Status: Success, Duplicate, Error, Missing Image, dll
	 * @param {string} [extra=''] - Info tambahan (opsional), misal "with edit link"
	 */
	function addRecentLog(title, status, extra = '') {
		// 1. Ambil waktu saat ini dalam format HH:MM (24 jam)
		const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });

		// 2. Buat objek log entry
		const logEntry = {
			time,
			// Potong judul jika terlalu panjang (>60 karakter) agar tampilan rapi
			title: title.length > 60 ? title.substring(0, 57) + '...' : title,
			status,
			extra
		};

		// 3. Tambahkan ke array di posisi paling depan (recentLogs[0] = log terbaru)
		recentLogs.unshift(logEntry);

		// 4. Batasi maksimal 10 log terakhir (FIFO: First In First Out)
		//    Jika lebih dari 10, hapus log paling lama (yang ada di akhir array)
		if (recentLogs.length > 10) recentLogs.pop();

		// 5. Langsung update tampilan di DOM
		renderRecentLogs();
	}

	// ──────────────────────────────────────────────────────────────
	// BAGIAN BERIKUTNYA ADALAH KODE YANG DI-OBFUSCATE/MINIFY MENGGUNAKAN EVAL
	// Fungsi ini sebenarnya adalah renderRecentLogs()
	// ──────────────────────────────────────────────────────────────
	eval(function(p,a,c,k,e,r){e=function(c){return c.toString(a)};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('d e(){6 1=7.f(\'g-h-1\');i(!1)j;1.8=\'\';k.l(0=>{6 2=7.m(\'2\');2.4.n=\'o\';2.8=`<3 4="9:#p">[${0.q}]</3><a>${0.r}</a>→<3 s="5-${0.5.t()}">${0.5}</3>${0.b?`<c 4="9:#u">(${0.b})</c>`:\'\'}`;1.v(2)})}',32,32,'log|list|li|span|style|status|const|document|innerHTML|color|strong|extra|small|function|renderRecentLogs|getElementById|recent|activity|if|return|recentLogs|forEach|createElement|marginBottom|4px|6b7280|time|title|class|toLowerCase|9ca3af|appendChild'.split('|'),0,{}));


	/* Penjelasan isi fungsi yang di-eval (setelah didecode secara manual):

	function renderRecentLogs() {
		// Ambil elemen <ul> dengan id 'recent-activity-list'
		const list = document.getElementById('recent-activity-list');
		
		// Jika tidak ditemukan → keluar (aman dari error)
		if (!list) return;

		// Kosongkan isi list terlebih dahulu
		list.innerHTML = '';

		// Loop setiap log di array recentLogs (dari terbaru ke terlama)
		recentLogs.forEach(log => {
			// Buat elemen <li> baru
			const li = document.createElement('li');
			
			// Tambahkan margin bawah agar rapi
			li.style.marginBottom = '4px';
			
			// Bangun HTML untuk setiap baris log
			li.innerHTML = `
				<span style="color:#6b7280">[${log.time}]</span> 
				<strong>${log.title}</strong> 
				→ <span class="status-${log.status.toLowerCase()}">${log.status}</span>
				${log.extra ? `<small style="color:#9ca3af">(${log.extra})</small>` : ''}
			`;
			
			// Tambahkan <li> ke dalam <ul>
			list.appendChild(li);
		});
	}
	*/
	
	// Array global untuk menyimpan semua log penting (error, warning, success, info)
	// Log ditambahkan dengan fungsi addImportLog() dan ditampilkan di sini
	let importLogs = [];

	/**
	 * Render ulang seluruh daftar import log ke dalam elemen <ul id="import-log-list">
	 * - Kosongkan list terlebih dahulu
	 * - Tampilkan semua log dengan prefix simbol dan warna berbeda berdasarkan type
	 * - Auto-scroll ke log terbaru
	 */
	function renderImportLogs() {
		// 1. Ambil elemen <ul> tempat log ditampilkan
		const list = document.getElementById('import-log-list');
		
		// 2. Guard clause: jika elemen tidak ditemukan → keluar (mencegah error null)
		if (!list) {
			console.warn('Elemen #import-log-list tidak ditemukan. Import logs tidak bisa dirender.');
			return;
		}

		// 3. Kosongkan isi <ul> sebelum render ulang (penting agar tidak duplikat)
		list.innerHTML = '';

		// 4. Jika tidak ada log → tampilkan pesan kosong (opsional, tapi bagus untuk UX)
		if (importLogs.length === 0) {
			const emptyLi = document.createElement('li');
			emptyLi.style.color = '#9ca3af';
			emptyLi.style.fontStyle = 'italic';
			emptyLi.style.padding = '8px 0';
			emptyLi.textContent = 'Belum ada log import';
			list.appendChild(emptyLi);
			return;
		}

		// 5. Loop setiap log dan buat elemen <li>
		importLogs.forEach(log => {
			const li = document.createElement('li');
			li.style.marginBottom = '6px';       // Jarak antar baris lebih nyaman dibaca
			li.style.lineHeight = '1.4';         // Sedikit tambahan agar teks tidak terlalu rapat

			// Tentukan prefix simbol dan kelas warna berdasarkan tipe log
			let prefix = '';
			let colorClass = '';

			switch (log.type.toLowerCase()) {
				case 'error':
					prefix = '✗';
					colorClass = 'text-red-600 font-medium';
					break;
				case 'warning':
					prefix = '⚠';
					colorClass = 'text-amber-600';
					break;
				case 'success':
					prefix = '✓';
					colorClass = 'text-green-600';
					break;
				case 'info':
				default:
					prefix = 'ℹ';
					colorClass = 'text-blue-600';
			}

			// Bangun HTML untuk setiap baris log
			// Catatan: message tidak di-escape karena berasal dari client-side (aman di sini)
			li.innerHTML = `
				<span class="text-gray-500 text-xs">(${log.time})</span>
				<span class="${colorClass}">${prefix}</span>
				${log.message}
			`;

			// Tambahkan <li> ke dalam <ul>
			list.appendChild(li);
		});

		// 6. Auto-scroll ke bawah agar log terbaru selalu terlihat
		// Ini sangat penting untuk user experience saat log bertambah cepat
		list.scrollTop = list.scrollHeight;
	}

	/**
	 * Menambahkan satu entri log baru ke array importLogs
	 * - Validasi input agar tidak menambahkan log kosong
	 * - Normalisasi tipe log ke huruf kecil
	 * - Tambahkan log di posisi terdepan (terbaru)
	 * - Batasi maksimal 20 log terakhir
	 * - Langsung render ulang tampilan log di DOM
	 *
	 * @param {string} message - Pesan log yang akan ditampilkan (wajib)
	 * @param {string} [type='info'] - Tipe log: 'info', 'success', 'warning', 'error' (opsional)
	 */
	function addImportLog(message, type = 'info') {
		// 1. Validasi input message (sangat baik!)
		//    Mencegah log kosong atau invalid masuk ke array
		if (!message || typeof message !== 'string' || message.trim() === '') {
			console.warn('addImportLog: Pesan log kosong atau tidak valid');
			return;  // Early return → sangat efisien, tidak lanjut proses
		}

		// 2. Normalisasi tipe log ke huruf kecil
		//    → Jaga-jaga jika pemanggilan pakai huruf kapital (misal 'SUCCESS' atau 'Warning')
		//    → Memastikan konsistensi dengan switch di renderImportLogs()
		const normalizedType = type.toLowerCase();

		// 3. Ambil waktu saat ini dengan format HH:MM:SS (detail akurat)
		//    Cocok untuk log yang membutuhkan presisi detik
		const time = new Date().toLocaleTimeString([], {
			hour: '2-digit',
			minute: '2-digit',
			second: '2-digit'
		});

		// 4. Buat objek log baru & tambahkan di posisi paling depan
		//    unshift() → log terbaru selalu index 0 (paling atas di tampilan)
		importLogs.unshift({
			time,                    // waktu pembuatan log
			message: message.trim(), // trim() → hilangkan spasi ekstra di awal/akhir
			type: normalizedType     // tipe sudah dinormalisasi
		});

		// 5. Batasi jumlah log maksimal 20
		//    Jika lebih dari 20 → hapus log paling lama (di akhir array)
		//    → Mencegah array membengkak & DOM menjadi lambat saat render
		if (importLogs.length > 20) {
			importLogs.pop();  // pop() = hapus elemen terakhir (log tertua)
		}

		// 6. Langsung update tampilan di DOM
		//    → Membuat log muncul secara real-time tanpa delay
		renderImportLogs();
	}
	
	// Ambil elemen <span class="label"> di dalam tombol Pause
	// Optional chaining (?.) → aman jika btnPause tidak ada atau tidak punya child .label
	const pauseLabel = btnPause?.querySelector('.label');

	// Sama seperti di atas, tapi untuk tombol Start
	// → Digunakan untuk mengubah teks tombol secara dinamis (misal "Start" → "Running")
	const startLabel = btnStart?.querySelector('.label');

	// ──────────────────────────────────────────────────────────────
	// Jalankan fungsi showCustomSourceNotice() saat halaman pertama kali dimuat
	// ──────────────────────────────────────────────────────────────
	showCustomSourceNotice();

	// Tambahkan event listener pada elemen <select> (sourceSelect)
	// Setiap kali user mengganti pilihan source → panggil showCustomSourceNotice()
	// → Fungsi ini biasanya mengatur visibility field base_url, notice custom, dll
	// Optional chaining (?.) → aman jika sourceSelect tidak ditemukan
	sourceSelect?.addEventListener('change', showCustomSourceNotice);

	// ──────────────────────────────────────────────────────────────
	// Fungsi pembantu untuk membersihkan input URL
	// Digunakan saat paste atau ketik manual di field base_domain_url
	// ──────────────────────────────────────────────────────────────
	function cleanUrl(value) {
		return value
			.trim()                     // 1. Hapus spasi di awal dan akhir
			.replace(/\s+/g, '');       // 2. Hapus SEMUA spasi di tengah (ganti dengan string kosong)
			//    → Contoh: "https:// example . com" → "https://example.com"
			//    → Cocok untuk memastikan URL bersih tanpa spasi sama sekali
			//.replace(/\/+$/, '')             // hapus slash berlebih di akhir (opsional)
			//.toLowerCase();                  // ubah ke huruf kecil (opsional, tergantung kebutuhan)
	}
	
	/* =========================
	   LOCAL STORAGE
	========================= */
	// Kunci unik untuk menyimpan daftar URL yang sudah berhasil diimport
	// Menggunakan prefix spesifik agar tidak bentrok dengan key localStorage milik script lain
	const STORAGE_KEY = 'ai_post_imported_links';

	/**
	 * Mengambil daftar semua URL yang sudah pernah diimport dari localStorage
	 * - Mengembalikan array string (URL)
	 * - Sangat aman: menangani kasus data hilang, corrupt, atau format salah
	 *
	 * @returns {string[]} Array berisi URL yang sudah diimport (selalu array, tidak pernah null/undefined)
	 */
	function getImportedLinks() {
		try {
			// Ambil data mentah dari localStorage
			const data = localStorage.getItem(STORAGE_KEY);
			
			// Jika ada data → parse menjadi array JavaScript
			// Jika tidak ada (null) → kembalikan array kosong
			return data ? JSON.parse(data) : [];
		} catch (e) {
			// Tangani semua kemungkinan error: JSON tidak valid, data corrupt, quota exceeded, dll
			// Log warning ke console agar developer tahu ada masalah
			// → Sangat baik, mencegah crash seluruh halaman
			console.warn('Gagal membaca imported links dari localStorage:', e);
			
			// Selalu kembalikan array kosong sebagai fallback aman
			return [];
		}
	}

	/**
	 * Menyimpan satu URL baru ke daftar imported links
	 * - Hanya simpan jika URL valid dan belum ada di daftar
	 * - Trim URL untuk konsistensi
	 * - Ada penanganan error dan batasan jumlah maksimal (opsional)
	 *
	 * @param {string} url - URL yang baru saja berhasil diimport
	 */
	function saveImportedLink(url) {
		// 1. Validasi dasar: pastikan url adalah string dan tidak kosong setelah trim
		//    → Mencegah menyimpan nilai invalid (null, undefined, spasi saja)
		if (typeof url !== 'string' || !url.trim()) return;

		// 2. Ambil daftar link yang sudah ada (selalu array, berkat getImportedLinks)
		const links = getImportedLinks();

		// 3. Trim URL sekali saja → pastikan konsistensi (tanpa spasi ekstra)
		const trimmedUrl = url.trim();

		// 4. Cek duplikat: hanya tambahkan jika belum ada
		//    includes() → perbandingan string sederhana & cepat untuk kebutuhan ini
		if (!links.includes(trimmedUrl)) {
			// Tambahkan URL yang sudah di-trim
			links.push(trimmedUrl);

			// Opsional: batasi maksimal jumlah link yang disimpan
			// → localStorage punya batas ~5MB, 2000 URL biasanya masih aman
			// → shift() menghapus elemen paling lama (FIFO)
			if (links.length > 2000) {
				links.shift();
			}

			try {
				// Simpan kembali sebagai JSON string
				localStorage.setItem(STORAGE_KEY, JSON.stringify(links));
			} catch (e) {
				// Tangani error: kuota habis, browser blokir, dll
				// → Tidak crash, hanya log warning
				console.warn('Gagal menyimpan ke localStorage:', e);
			}
		}
		// Jika sudah ada → diam saja (tidak ada error, tidak ada log)
	}

	/**
	 * Mengecek apakah URL tertentu sudah pernah diimport sebelumnya
	 * - Digunakan untuk menandai row tabel sebagai "Already Imported"
	 *
	 * @param {string} url - URL yang ingin dicek
	 * @returns {boolean} true jika sudah diimport, false jika belum
	 */
	function isAlreadyImported(url) {
		// Validasi sederhana: pastikan input adalah string
		// Jika bukan string → langsung false (aman)
		return typeof url === 'string' && getImportedLinks().includes(url.trim());
	}
	
	/**
	 * Menandai semua baris tabel (tr.ai-item) yang URL-nya sudah pernah diimport sebelumnya
	 * - Menggunakan data dari localStorage untuk menentukan status "Already Imported"
	 * - Update visual: tambah class 'imported', ubah badge menjadi hijau (success),
	 *   dan update teks status jika elemen tersebut ada
	 * - Dipanggil sekali saat halaman dimuat untuk sinkronisasi status awal
	 */
	function markImportedRows() {
		// 1. Ambil semua URL yang sudah diimport dari localStorage
		//    getImportedLinks() selalu mengembalikan array string (aman & konsisten)
		const importedLinks = getImportedLinks();

		// 2. Konversi array menjadi Set untuk pencarian super cepat (O(1))
		//    → .has() jauh lebih efisien dibandingkan array.includes() saat data banyak
		const imported = new Set(importedLinks);

		// 3. Loop melalui setiap baris tabel (NodeList dari querySelectorAll)
		rows.forEach(row => {
			// 4. Ambil URL dari atribut data-url pada <tr>
			//    → Jika tidak ada atribut data-url → skip baris ini
			const url = row.dataset.url;
			if (!url) return;

			// 5. Cek apakah URL ini sudah ada di daftar imported
			//    → Early return → kode lebih ringkas dan cepat
			if (!imported.has(url)) return;

			// 6. Tandai baris ini sebagai sudah diimport (untuk styling CSS)
			row.classList.add('imported');

			// 7. Cari elemen badge status di dalam baris
			const badge = row.querySelector('.status-badge');

			// 8. Jika badge ditemukan → update status menjadi "success"
			if (badge) {
				// Hapus class status lama agar tidak ada konflik visual
				badge.classList.remove(
					'badge-waiting',
					'badge-processing',
					'badge-error',
					'badge-warning' // tambahkan jika ada status lain
				);

				// Tambahkan class success (biasanya warna hijau)
				badge.classList.add('badge-success');

				// Update teks badge
				badge.textContent = 'Already Imported';
			}

			// 9. Cari elemen teks status tambahan (jika ada di struktur HTML)
			const statusText = row.querySelector('.status-text');

			// 10. Jika ditemukan → sinkronkan teksnya juga
			if (statusText) {
				statusText.textContent = 'Already Imported';
			}
		});
	}

	// Jalankan fungsi ini sekali saat halaman selesai dimuat
	// → Menjamin semua baris yang sudah diimport langsung terlihat benar sejak awal
	markImportedRows();


	/* =========================
	   UI HELPERS
	========================= */
	/**
	 * Menampilkan container progress bar dan elemen terkait
	 * - Digunakan saat proses import dimulai (misalnya setelah klik Start)
	 * - Menambahkan class 'visible' untuk menampilkan progress secara visual
	 * - Sudah dilengkapi pengecekan elemen untuk mencegah error
	 */
	function showProgress() {
		// 1. Pengecekan eksplisit apakah elemen progressContainer ada
		//    → Jika tidak ditemukan (null/undefined) → log warning dan keluar
		//    → Lebih baik daripada hanya optional chaining karena bisa beri feedback
		if (!progressContainer) {
			console.warn('Elemen progressContainer tidak ditemukan');
			return;  // Early return → sangat baik, mencegah error lebih lanjut
		}

		// 2. Tambahkan class 'visible' untuk menampilkan progress
		//    → Class ini biasanya mengatur:
		//      display: block / flex;
		//      opacity: 1;
		//      visibility: visible;
		//      atau animasi fade-in via CSS
		progressContainer.classList.add('visible');

		// 3. (Opsional) Tambahkan class loading ke body untuk efek cursor wait
		//    → Memberi feedback visual bahwa halaman sedang bekerja
		//    → Saat ini dikomen → bisa diaktifkan jika diinginkan
		// document.body.classList.add('loading');
	}

	/**
	 * Menyembunyikan container progress bar dan elemen terkait
	 * - Digunakan saat proses selesai, di-pause, di-stop, atau error
	 * - Menghapus class 'visible' agar progress kembali tersembunyi
	 */
	function hideProgress() {
		// 1. Pengecekan singkat apakah elemen ada
		//    → Jika tidak ada → langsung keluar (tidak perlu log karena hanya hide)
		if (!progressContainer) return;

		// 2. Hapus class 'visible' untuk menyembunyikan progress
		//    → Kembali ke kondisi awal (biasanya display: none / opacity: 0)
		progressContainer.classList.remove('visible');

		// 3. (Opsional) Hapus class loading dari body
		//    → Sinkronkan kembali cursor ke normal
		//    → Saat ini dikomen → bisa diaktifkan jika pakai fitur loading cursor
		// document.body.classList.remove('loading');
	}
	
	
	/**
	 * Mengembalikan seluruh UI dan state proses import ke kondisi awal / default
	 * - Digunakan setelah proses selesai, di-stop, di-pause permanen, atau error fatal
	 * - Reset semua variabel state, tombol, progress, status baris, dan pengaturan
	 * - Memastikan halaman kembali "fresh" dan siap untuk import baru tanpa sisa efek sebelumnya
	 */
	function resetUI() {
		// 1. Reset indeks proses ke baris pertama
		//    → Persiapan untuk import baru dari awal
		index = 0;

		// 2. Reset semua flag status proses
		//    → Semua false agar bisa mulai ulang tanpa konflik
		isRunning = isPaused = isStopped = false;

		// 3. Sembunyikan progress bar & container terkait
		//    → Pastikan tidak ada visual proses yang tertinggal di layar
		hideProgress();

		// 4. Reset tombol Start ke kondisi siap pakai
		if (btnStart) {
			btnStart.disabled = false;              // Aktifkan kembali tombol
			btnStart.classList.remove('running');   // Hapus efek visual "sedang berjalan"
		}

		// 5. Kembalikan teks label tombol Start ke default
		//    → Opsional chaining tidak digunakan di sini karena sudah ada if di atas
		if (startLabel) {
			startLabel.textContent = 'Start Import';
		}

		// 6. Nonaktifkan tombol Pause & Stop
		//    → Karena tidak ada proses aktif lagi
		if (btnPause) btnPause.disabled = true;
		if (btnStop)  btnStop.disabled = true;

		// 7. Reset teks label tombol Pause ke kondisi awal
		if (pauseLabel) {
			pauseLabel.textContent = 'Pause';
		}

		// 8. Reset status visual SEMUA baris tabel (tr.ai-item)
		rows.forEach(r => {
			// Hapus semua class status proses sebelumnya
			// → Pastikan tidak ada efek visual lama yang tertinggal
			r.classList.remove('processing', 'success', 'error', 'imported');

			// Cari & reset badge status
			const badge = r.querySelector('.status-badge');
			if (badge) {
				// Hapus class status lama (daftar lengkap untuk keamanan)
				badge.classList.remove(
					'badge-success',
					'badge-error',
					'badge-processing',
					'badge-warning'  // tambahkan jika ada class lain
				);

				// Set ke status default (waiting)
				badge.classList.add('badge-waiting');
				badge.textContent = 'Wait';
			}

			// Cari & reset teks status tambahan (jika ada di struktur HTML)
			const statusText = r.querySelector('.status-text');
			if (statusText) {
				statusText.textContent = 'Wait';
			}
		});

		// 9. Setelah semua baris di-reset, tandai KEMBALI baris yang memang sudah pernah diimport
		//    → Penting! Karena class 'imported' dihapus di atas
		//    → Ini menjaga integritas status "Already Imported" dari localStorage
		markImportedRows();

		// 10. Aktifkan kembali semua field pengaturan yang sebelumnya dikunci
		//     → User bisa mengubah konfigurasi untuk import berikutnya
		enableSettingsFields();

		// 11. Optional: reset teks elemen yang menunjukkan item saat ini
		//     → Memberi feedback visual bahwa tidak ada proses aktif
		if (currentGame) {
			currentGame.textContent = 'Ready to import...';
		}
	}

	/**
	 * Menampilkan pesan "Import Complete" dengan animasi halus
	 * - Menyembunyikan tabel daftar item import secara bertahap
	 * - Menampilkan elemen pesan selesai (misal: "Import selesai!" atau summary)
	 * - Digunakan saat semua item sudah diproses (index >= rows.length)
	 */
	function showImportCompleteMessage() {
		// 1. Ambil elemen tabel daftar item yang sedang ditampilkan
		const table = document.getElementById('ai-import-table');
		
		if (table) {
			// Tambahkan transisi opacity agar penyembunyian terlihat halus
			table.style.transition = 'opacity .4s ease';
			
			// Mulai fade out (menjadi transparan)
			table.style.opacity = '0';
			
			// Setelah transisi selesai (400ms), sembunyikan sepenuhnya
			// → Mencegah elemen tetap memakan ruang meski tidak terlihat
			setTimeout(() => {
				table.style.display = 'none';
			}, 400);
		}

		// 2. Ambil elemen pesan "import complete" (biasanya div atau section summary)
		const done = document.getElementById('ai-import-complete');
		
		if (done) {
			// Delay sedikit (450ms) agar tabel sudah benar-benar hilang sebelum muncul
			// → Memberi efek transisi yang mulus & terkoordinasi
			setTimeout(() => {
				// Tampilkan elemen terlebih dahulu (display: block)
				done.style.display = 'block';
				
				// Mulai dari transparan (untuk animasi fade-in)
				done.style.opacity = '0';
				
				// Tambahkan transisi opacity
				done.style.transition = 'opacity .4s ease';
				
				// Beri delay kecil agar transisi terpicu setelah display berubah
				// → Tanpa delay ini, fade-in bisa tidak bekerja di beberapa browser
				setTimeout(() => {
					done.style.opacity = '1';
				}, 50);
			}, 450);
		}
	}

	/**
	 * Menyembunyikan SEMUA form manual edit yang ada di halaman
	 * - Biasanya dipanggil saat mulai import otomatis agar tidak mengganggu
	 */
	function hideAllManualForms() {
		// Cari semua form dengan id="post_manual" (mungkin ada banyak di setiap baris)
		// → querySelectorAll mengembalikan NodeList
		document.querySelectorAll('form#post_manual').forEach(form => {
			// Sembunyikan setiap form yang ditemukan
			form.style.display = 'none';
		});
	}

	/**
	 * Menampilkan form manual edit pada baris tertentu
	 * - Hanya muncul jika URL belum pernah diimport sebelumnya
	 * - Biasanya dipanggil saat proses import gagal pada baris tersebut
	 *
	 * @param {HTMLElement} row - Elemen <tr> baris tabel yang sedang diproses
	 */
	function showManualForm(row) {
		// Ambil URL dari atribut data-url pada baris
		const url = row.dataset.url;

		// Jika URL sudah pernah diimport → jangan tampilkan form manual
		// → Mencegah user edit ulang item yang sudah berhasil
		if (isAlreadyImported(url)) return;

		// Cari form manual di dalam baris tersebut
		const form = row.querySelector('form#post_manual');
		
		// Jika ditemukan → tampilkan sebagai inline-block (agar sesuai layout tabel)
		if (form) {
			form.style.display = 'inline-block';
		}
	}

	/**
	 * Menonaktifkan field pengaturan utama selama proses import berjalan
	 * - Mencegah user mengubah konfigurasi saat proses sedang aktif
	 */
	function disableSettingsFields() {
		// Nonaktifkan select source jika ada
		if (sourceSelect) sourceSelect.disabled = true;
		
		// Nonaktifkan input base URL jika ada
		if (baseUrlInput) baseUrlInput.disabled = true;
	}

	/**
	 * Mengaktifkan kembali field pengaturan setelah proses selesai/stop
	 * - Juga menampilkan ulang notice custom source jika diperlukan
	 */
	function enableSettingsFields() {
		// Aktifkan kembali select source
		if (sourceSelect) sourceSelect.disabled = false;
		
		// Aktifkan kembali input base URL
		if (baseUrlInput) baseUrlInput.disabled = false;
		
		// Perbarui tampilan notice custom source sesuai pilihan saat ini
		// → Penting karena status notice bergantung pada nilai select
		showCustomSourceNotice();
	}
	
	/* =========================
	   TOOLTIP + TOAST
	========================= */
	/**
	 * Menambahkan tooltip sederhana ke elemen tertentu
	 * - Tooltip biasanya ditampilkan saat hover via CSS (menggunakan ::after atau data-tooltip)
	 * - Hanya menambahkan class dan atribut data-tooltip
	 * - Sangat ringan & tidak bergantung pada library
	 *
	 * @param {HTMLElement} el   - Elemen yang akan diberi tooltip (misal tombol)
	 * @param {string}      text - Teks tooltip yang akan ditampilkan
	 */
	function addTooltip(el, text) {
		// Guard clause: jika elemen tidak ada → langsung keluar (aman dari error)
		if (!el) return;

		// Tambahkan class khusus 'ai-tooltip' untuk styling CSS tooltip
		// → Biasanya CSS akan menggunakan class ini untuk ::before/::after
		el.classList.add('ai-tooltip');

		// Simpan teks tooltip di atribut data-tooltip
		// → CSS bisa mengaksesnya dengan attr(data-tooltip)
		el.setAttribute('data-tooltip', text);
	}

	/**
	 * Menghapus tooltip dari elemen tertentu
	 * - Menghapus class dan atribut yang ditambahkan sebelumnya
	 * - Digunakan saat proses import selesai atau tombol di-enable kembali
	 *
	 * @param {HTMLElement} el - Elemen yang tooltip-nya ingin dihapus
	 */
	function removeTooltip(el) {
		// Guard clause: jika elemen tidak ada → keluar (sangat aman)
		if (!el) return;

		// Hapus class 'ai-tooltip' → tooltip tidak akan muncul lagi via CSS
		el.classList.remove('ai-tooltip');

		// Hapus atribut data-tooltip → bersihkan data sepenuhnya
		el.removeAttribute('data-tooltip');
	}

	/**
	 * Menampilkan notifikasi toast sederhana di layar
	 * - Toast muncul di tengah bawah (biasanya), otomatis hilang setelah 3,5 detik
	 * - Mendukung tipe (success, warning, error, dll) untuk styling berbeda
	 * - Menggunakan requestAnimationFrame untuk animasi yang halus
	 *
	 * @param {string} message - Pesan yang ingin ditampilkan
	 * @param {string} [type=''] - Tipe toast: 'success', 'warning', 'error', dll (opsional)
	 */
	function showToast(message, type = '') {
		// 1. Buat elemen div baru untuk toast
		const toast = document.createElement('div');

		// 2. Tambahkan class dasar + class tipe (jika ada)
		//    → Contoh: 'ai-toast success' → bisa di-style berbeda via CSS
		toast.className = `ai-toast ${type}`;

		// 3. Isi teks pesan (textContent → aman dari XSS karena tidak pakai innerHTML)
		toast.textContent = message;

		// 4. Tambahkan toast ke body (posisi biasanya fixed via CSS)
		document.body.appendChild(toast);

		// 5. Gunakan requestAnimationFrame untuk memicu animasi CSS setelah element ada di DOM
		//    → Membuat transisi show terlihat mulus (lebih baik daripada setTimeout(0))
		requestAnimationFrame(() => {
			toast.classList.add('show'); // → biasanya opacity: 1, transform: translateY(0)
		});

		// 6. Hilangkan class 'show' setelah 3.5 detik
		setTimeout(() => {
			toast.classList.remove('show');

			// 7. Hapus elemen dari DOM setelah animasi keluar selesai (300ms)
			//    → Membersihkan DOM agar tidak menumpuk elemen toast lama
			setTimeout(() => toast.remove(), 300);
		}, 3500); // 3500ms = 3.5 detik (waktu tampil yang cukup nyaman)
	}

	/* =========================
	   MAIN PROCESS
	========================= */
	
/**
 * Fungsi utama yang memproses item berikutnya secara rekursif
 * - Dipanggil berulang melalui setTimeout untuk efek delay antar item
 * - Menangani dua kondisi utama:
 *   1. Jika proses pause/stop → langsung keluar
 *   2. Jika semua item selesai → tampilkan summary, sembunyikan progress, reset UI
 */
function processNext() {
    // 1. Guard clause: jika sedang pause atau sudah di-stop → hentikan pemrosesan
    //    → Sangat penting untuk menghormati status pause/stop dari user
    if (isPaused || isStopped) return;

    // 2. Cek apakah sudah memproses semua baris (index sudah melebihi panjang rows)
    if (index >= rows.length) {
        // 3. Tampilkan progress 100% sebagai penutup visual
        progressBar.style.width = '100%';
        progressText.textContent = `${rows.length} / ${rows.length}`;

        // 4. Delay 1.2 detik sebelum menyembunyikan progress
        //    → Memberi waktu user melihat 100% sebelum UI berubah drastis
        setTimeout(() => {
            hideProgress();                    // Sembunyikan progress bar
            showImportCompleteMessage();       // Tampilkan pesan "Import selesai"
            hideImportNotification();          // Hilangkan notifikasi floating
        }, 1200);

        // 5. Reset tombol kontrol ke kondisi awal
        btnStart.disabled = false;             // Aktifkan kembali tombol Start
        btnPause.disabled = true;
        btnStop.disabled = true;

        // 6. Kembalikan teks tombol ke default
        startLabel.textContent = 'Start Import';
        pauseLabel.textContent = 'Pause';

        // 7. Aktifkan kembali field & tombol pengaturan
        enableSettingsFields();
        enableSettingsButtons();               // ← Tambahan yang sangat baik

        // 8. Hilangkan efek sticky pada wrapper kontrol
        controlsWrapper?.classList.remove('is-sticky');
        removeTooltip(btnSaveSettings);
        removeTooltip(btnResetSettings);
        controlsWrapper.style.display = 'none';

        // 9. Tampilkan ringkasan statistik import di section khusus
        const summaryList = document.getElementById('import-summary-list');
        const summarySection = document.getElementById('import-summary');

        if (summaryList && summarySection) {
            // Isi HTML daftar statistik dengan data dari importStats
            // → Template literal → sangat bersih dan mudah dibaca
            summaryList.innerHTML = `
                <li><strong>Total processed:</strong> ${importStats.total}</li>
                <li class="success"><strong>Success:</strong> ${importStats.success}</li>
                <li class="duplicate"><strong>Duplicate:</strong> ${importStats.duplicate}</li>
                <li class="missing"><strong>Missing Image:</strong> ${importStats.missingImage}</li>
                <li class="draft"><strong>Saved as Draft:</strong> ${importStats.draft}</li>
                <li class="error"><strong>Error/Failed:</strong> ${importStats.error}</li>
            `;

            // Tampilkan section summary
            summarySection.style.display = 'block';
        }

        // 10. Berikan feedback akhir kepada user
        //     → Toast lebih informatif daripada hanya emoji
        showToast('Import completed. Check Import Log for details.', 'success');

        // 11. Pastikan section log tetap terlihat setelah selesai
        //     → Sangat baik, user bisa review detail error/warning
        document.querySelector('.import-log-section').style.display = 'block';

        // 12. Reset semua flag status proses
        //     → Pastikan proses benar-benar selesai & bisa di-start ulang
        isRunning = isPaused = isStopped = false;

        // 13. Akhiri eksekusi fungsi (tidak perlu setTimeout lagi)
        return;
    }

		// 1. Ambil elemen baris tabel saat ini berdasarkan indeks yang sedang diproses
		//    → rows adalah NodeList dari querySelectorAll('tr.ai-item') di awal script
		const row = rows[index];

		// 2. Ambil URL dari atribut data-url pada <tr> tersebut
		//    → Ini adalah URL yang akan dikirim ke server untuk diproses import
		const url = row.dataset.url;

		// 3. Ambil judul item dari elemen dengan class 'ai-item-title'
		//    → Gunakan optional chaining (?.) agar aman jika elemen tidak ada
		//    → .trim() untuk menghapus spasi berlebih di awal/akhir
		//    → Fallback ke 'Item' jika tidak ditemukan judul sama sekali
		const title = row.querySelector('.ai-item-title')?.textContent.trim() || 'Item';

		// 4. Cari elemen badge status di dalam baris
		//    → Ini adalah elemen yang akan menunjukkan status visual (Waiting, Processing, Success, dll)
		const badge = row.querySelector('.status-badge');

		// 5. Cari elemen teks status tambahan (biasanya ada di dalam atau dekat badge)
		const text = row.querySelector('.status-text');

		// 6. Tambahkan class 'processing' ke baris → efek visual sedang diproses
		//    → Biasanya CSS akan memberikan warna latar, border, atau animasi loading
		row.classList.add('processing');

		// 7. Reset dan set ulang class badge menjadi status "Processing"
		//    → Mengganti semua class sebelumnya → cara cepat untuk memastikan hanya ada satu status
		badge.className = 'status-badge badge-processing';

		// 8. Ubah teks badge menjadi "Processing..." → feedback langsung ke user
		badge.textContent = 'Processing...';

		// 9. Ubah teks status tambahan (jika ada) menjadi sama
		text.textContent = 'Processing...';

		// 10. Update elemen yang menampilkan informasi item yang sedang diproses
		//     → Memberi user tahu persis item mana yang sedang dikerjakan + urutan
		currentGame.textContent = `Processing... ${title} (${index + 1}/${rows.length})`;

		//updateImportProgress(index, rows.length, title); // ← update count & bar
					
		// Melakukan request AJAX ke server WordPress menggunakan fetch API
		// Tujuan: mengirimkan perintah untuk memproses/submit satu item (post) ke server
		fetch(ajaxurl, {
			method: 'POST',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded',
				// Optional: tambahkan header lain jika diperlukan
			},
			body: `action=auto_submit_post&wp_url=${encodeURIComponent(url)}&nonce=${nonce}`,
			credentials: 'same-origin',           // ← Pastikan cookie/session ikut terkirim
			signal: AbortSignal.timeout(120000),  // 2 menit timeout
			// cache: 'no-cache',                 // ← Opsional jika tidak ingin cache
		})

		.then(r => r.json())
		// Bagian ini adalah .then() kedua dari fetch request
		// → Menerima response JSON yang sudah di-parse dari server
		// → Menangani hasil sukses/gagal, update UI, statistik, dan log
		.then(res => {
			// 1. Hapus class 'processing' dari baris tabel
			//    → Menghilangkan efek visual "sedang diproses" (animasi/loading)
			row.classList.remove('processing');

			// 2. Deklarasi variabel bantu untuk status akhir, pesan log, dan tipe log
			let statusText = '';          // Teks yang akan ditampilkan di badge (Success/Failed/dll)
			let logStatus = 'Success';    // Default untuk recent activity (akan diubah jika gagal)
			let extraInfo = '';           // Info tambahan untuk recent log (misal 'with edit link')

			let logMessage = '';          // Pesan detail yang akan masuk ke import log
			let logType = 'info';         // Tipe log: 'info', 'success', 'warning', 'error'

			// 3. Kondisi jika request sukses (res.success === true)
			if (res.success) {
				// Tambah class visual sukses & tandai sebagai imported (agar tidak diproses ulang)
				row.classList.add('success', 'imported');

				// Simpan URL ke localStorage → digunakan untuk pengecekan "Already Imported"
				saveImportedLink(url);

				// Update badge menjadi hijau (success)
				badge.className = 'status-badge badge-success';
				badge.textContent = 'Success';

				// Siapkan pesan log sukses
				logMessage = `Success: ${title} imported/updated.`;
				logType = 'success';

				// Ambil link edit post dari response (jika server mengembalikannya)
				const editLink = res.data?.edit_link || '';

				// Update teks status di tabel: jika ada edit link → tampilkan link, jika tidak → teks biasa
				text.innerHTML = editLink
					? `Success | <a href="${editLink}" target="_blank" class="edit-post-link">Edit</a>`
					: 'Success';

				// Jika ada edit link → tambahkan juga ke pesan log (dengan link HTML)
				if (res.data?.edit_link) {
					logMessage += ` <a href="${res.data.edit_link}" target="_blank" class="text-blue-600 underline">Edit post</a>`;
				}

				// Update progress notifikasi (versi 2: dengan edit link jika ada)
				updateImportProgress2(index + 1, rows.length, title, editLink);

				// Update progress notifikasi (versi 3: status teks)
				updateImportProgress3(index + 1, rows.length, title, badge.textContent);

				// Variabel bantu untuk recent activity log
				statusText = 'Success';
				extraInfo = res.data?.edit_link ? 'with edit link' : '';

				// Tambah ke statistik sukses
				importStats.success++;
			} 
			// 4. Kondisi jika gagal (res.success === false)
			else {
				// Tambah class visual error
				row.classList.add('error');

				// Update badge & teks menjadi error (gunakan pesan dari server jika ada)
				badge.className = 'status-badge badge-error';
				badge.textContent = res.data?.message || 'Failed';
				text.textContent = badge.textContent;

				// Update progress notifikasi (tanpa link edit karena gagal)
				updateImportProgress2(index + 1, rows.length, title, '');
				updateImportProgress3(index + 1, rows.length, title, text.textContent);

				// Ambil pesan error dari server (fallback jika tidak ada pesan)
				const serverMessage = res.data?.message || 'Unknown error';

				// 5. Klasifikasi jenis error berdasarkan isi pesan server
				//    → Pencarian keyword → cukup akurat untuk kebanyakan kasus
				if (serverMessage.toLowerCase().includes('duplicate') || 
					serverMessage.toLowerCase().includes('already exists')) {
					logType = 'warning';
					logMessage = `Duplicate detected: ${title} → ${serverMessage}`;
					importStats.duplicate++;
				}
				else if (serverMessage.toLowerCase().includes('image') || 
						 serverMessage.toLowerCase().includes('featured') || 
						 serverMessage.toLowerCase().includes('poster')) {
					logType = 'warning';
					logMessage = `Missing/failed featured image: ${title} → ${serverMessage}`;
					importStats.missingImage++;
				}
				else if (serverMessage.toLowerCase().includes('draft') || 
						 serverMessage.toLowerCase().includes('forced to draft')) {
					logType = 'warning';
					logMessage = `Saved as Draft: ${title} (no GP_ID/Package Name)`;
					importStats.draft++;
				}
				else if (serverMessage.toLowerCase().includes('gp_id') || 
						 serverMessage.toLowerCase().includes('package name') || 
						 serverMessage.toLowerCase().includes('app id')) {
					logType = 'warning';
					logMessage = `No App ID / Package Name: ${title} → forced draft`;
					// Catatan: tidak ada increment statistik khusus di sini
				}
				else {
					// Default: error umum
					logType = 'error';
					logMessage = `Failed: ${title} → ${serverMessage}`;
					importStats.error++;
				}

				// Tampilkan form manual edit untuk item ini (jika gagal)
				// → Memberi user kesempatan edit manual jika otomatis gagal
				showManualForm(row);
			}

			// 6. Update statistik success (khusus jika benar-benar sukses)
			if (res.success) importStats.success++;

			// 7. Tambahkan ke recent activity log
			//    → Ubah tipe pertama huruf besar (misal 'success' → 'Success')
			//    → Catatan: baris addRecentLog yang dikomen mungkin versi lama
			addRecentLog(
				title,
				logType.charAt(0).toUpperCase() + logType.slice(1),  // 'success' → 'Success'
				'',                                                  // extraInfo tidak dipakai di sini
				res.data?.edit_link || ''                            // link edit jika ada
			);

			// 8. Tambahkan ke import log (daftar lengkap semua kejadian)
			//    → logMessage sudah disiapkan dengan pesan yang sesuai jenis error/sukses
			addImportLog(logMessage, logType);
		})

		// Bagian ini menangani semua error yang terjadi selama request fetch berjalan
		// Termasuk: timeout, network error, abort, server error, dll
		.catch(err => {
			// 1. Hapus class 'processing' dari baris tabel
			//    → Menghilangkan efek visual "sedang diproses" (loading/animasi)
			row.classList.remove('processing');

			// 2. Tambahkan class 'error' ke baris → efek visual error (merah/latar merah)
			row.classList.add('error');

			// 3. Update badge status menjadi mode error
			//    → Ganti semua class sebelumnya menjadi hanya 'status-badge badge-error'
			badge.className = 'status-badge badge-error';

			// 4. Tentukan teks badge berdasarkan jenis error
			//    → Khusus bedakan TimeoutError (dari AbortSignal.timeout) dengan error lain
			badge.textContent = err.name === 'TimeoutError' 
				? 'Timeout'                     // Jika timeout 120 detik
				: 'Connection Error';           // Default untuk error jaringan/server lain

			// 5. Sinkronkan teks status tambahan dengan badge
			text.textContent = badge.textContent;

			// 6. Update progress notifikasi versi 3 (status teks)
			//    → Tampilkan pesan error di notifikasi floating
			updateImportProgress3(
				index + 1, 
				rows.length, 
				title, 
				err.name === 'TimeoutError' ? 'Timeout' : 'Connection Error'
			);

			// 7. Tentukan pesan error yang lebih manusiawi untuk log
			const errorMsg = err.name === 'TimeoutError' 
				? 'Timeout (120s)'              // Tampilkan durasi timeout agar user tahu
				: 'Connection Error';           // Umum untuk error jaringan/server

			// 8. Buat pesan lengkap untuk log (termasuk judul item)
			const fullMessage = `Error processing ${title}: ${errorMsg}`;

			// 9. Tambahkan ke import log dengan tipe 'error'
			//    → User bisa melihat detail error di daftar log lengkap
			addImportLog(fullMessage, 'error');

			// 10. Tambah ke statistik error
			//     → Digunakan untuk ringkasan akhir (total error)
			importStats.error++;

			// 11. Tampilkan form manual edit untuk item ini
			//     → Memberi kesempatan user memperbaiki secara manual jika otomatis gagal
			showManualForm(row);
		})
		
		// Bagian .finally() akan selalu dijalankan setelah .then() atau .catch() selesai
		// → Terlepas dari sukses atau gagal, bagian ini tetap dieksekusi
		// → Tempat yang tepat untuk: increment index, update progress, jadwalkan item berikutnya
		.finally(() => {
			// 1. Naikkan index ke item berikutnya
			//    → index dimulai dari 0, jadi setelah proses item ke-0 → index jadi 1 (item berikutnya)
			index++;

			// 2. Update lebar progress bar secara visual (persentase)
			//    Math.round → membulatkan agar tampilan rapi (bukan desimal panjang)
			progressBar.style.width = Math.round((index / rows.length) * 100) + '%';

			// 3. Update teks progress (contoh: "5 / 100")
			progressText.textContent = `${index} / ${rows.length}`;

			// 4. Jadwalkan pemrosesan item berikutnya dengan delay random
			//    → Delay 2200–5000ms → mencegah request terlalu cepat bertubi-tubi (rate limiting)
			//    → Math.random() * 2800 → rentang 0–2800ms + 2200ms = total 2200–5000ms
			timeoutId = setTimeout(processNext, 2200 + Math.random() * 2800);

			// 5–8. Variabel bantu untuk update progress notifikasi
			//     → Nama variabel dalam bahasa Indonesia → konsisten dengan beberapa bagian lain
			JudulPost = ` ${title} (${index + 1}/${rows.length})`;   // Judul + urutan saat ini
			lagiProses = `${index}`;                                 // Index saat ini (sudah naik)
			TotalPost = `${rows.length}`;                            // Total semua item

			// 9. Update progress di notifikasi floating (versi custom)
			//    → Fungsi ini kemungkinan update teks + bar di elemen notifikasi
			updateImportProgress(lagiProses, TotalPost, JudulPost);

			// 10–11. Baris yang dikomentari → mungkin kode lama atau alternatif
			//       → (${index + 1}/${rows.length}) → format yang sama tapi tidak dipakai
			//       → NoticeProgressCount.textContent → mungkin versi lama notifikasi
			//       → currentGame.textContent → mungkin sudah digantikan oleh JudulPost
			//(${index + 1}/${rows.length})
			//NoticeProgressCount.textContent = `${index} / ${rows.length}`;
			//currentGame.textContent = `Memproses: ${title} (${index + 1}/${rows.length})`;
		});

		// 12. Tampilkan notifikasi floating (import-notification) sepanjang proses
		//     → Dipanggil di luar .finally → akan muncul sejak item pertama diproses
		//     → Biasanya berisi progress bar, judul item saat ini, dll
		showImportNotification();

	}

	/* =========================
	   BUTTON HANDLERS
	========================= */	
	if (btnStart) {  // Pengecekan apakah elemen tombol Start benar-benar ada di DOM
                 // → Sangat baik, mencegah error jika tombol tidak ditemukan

		btnStart.onclick = () => {  // Menggunakan arrow function → modern, bersih, tidak mengikat this
									// Cocok untuk event handler sederhana seperti ini

			// ──────────────────────────────────────────────────────────────
			// 1. Cegah multiple start jika sudah berjalan
			// ──────────────────────────────────────────────────────────────
			if (isRunning) return;     // Jika proses sudah berjalan → langsung keluar
									   // → Pencegahan double-click yang sangat penting

			// ──────────────────────────────────────────────────────────────
			// 2. Persiapan awal sebelum mulai proses import
			// ──────────────────────────────────────────────────────────────
			hideAllManualForms();      // Menyembunyikan semua form manual edit (jika ada)
									   // → Membersihkan tampilan agar fokus ke proses otomatis

			// ──────────────────────────────────────────────────────────────
			// 3. Update status internal & visual tombol
			// ──────────────────────────────────────────────────────────────
			isRunning = true;                  // Flag global → memberitahu sistem sedang berjalan
			btnStart.classList.add('running'); // Tambah class CSS (biasanya untuk animasi/loading)
			startLabel.textContent = 'Running';// Ubah teks tombol menjadi "Running"

			// ──────────────────────────────────────────────────────────────
			// 4. Aktifkan tombol kontrol tambahan
			// ──────────────────────────────────────────────────────────────
			btnPause.disabled = false;   // Aktifkan tombol Pause
			btnStop.disabled = false;    // Aktifkan tombol Stop

			// ──────────────────────────────────────────────────────────────
			// 5. Kunci pengaturan agar tidak diubah selama proses
			// ──────────────────────────────────────────────────────────────
			disableSettingsFields();     // Disable input field pengaturan (source, base_url, dll)
			disableSettingsButtons();    // Disable tombol Save Settings & Reset
										 // → Bagus, mencegah perubahan konfigurasi saat import

			// ──────────────────────────────────────────────────────────────
			// 6. Tampilkan kontrol wrapper sebagai sticky (mengambang)
			// ──────────────────────────────────────────────────────────────
			controlsWrapper?.classList.add('is-sticky');
			// Optional chaining (?.) → aman jika controlsWrapper tidak ada di halaman

			// ──────────────────────────────────────────────────────────────
			// 7. Tambahkan tooltip informatif pada tombol yang dikunci
			// ──────────────────────────────────────────────────────────────
			addTooltip(btnSaveSettings, 'Importer is running');
			addTooltip(btnResetSettings, 'Importer is running');
			// → Memberi petunjuk kepada user mengapa tombol tidak bisa diklik

			// ──────────────────────────────────────────────────────────────
			// 8. Berikan feedback visual & notifikasi proses
			// ──────────────────────────────────────────────────────────────
			showToast('🚀 Importer is running… Please wait', 'success');
			// Toast sukses dengan emoji → user experience bagus

			showImportNotification(rows.length); // Tampilkan notifikasi dengan total item
												 // → Sangat membantu user tahu berapa banyak yang akan diproses

			showProgress();  // Tampilkan progress bar/container

			// ──────────────────────────────────────────────────────────────
			// 9. Mulai proses import sebenarnya
			// ──────────────────────────────────────────────────────────────
			processNext();   // Panggil fungsi rekursif utama yang memproses setiap baris
							 // → Ini adalah titik start proses import sebenarnya
		};
	}
	
	if (btnPause) {  // Pengecekan apakah elemen tombol Pause benar-benar ada di DOM
					 // → Sangat baik, mencegah error jika tombol tidak ditemukan

		btnPause.onclick = () => {  // Menggunakan arrow function → modern, bersih, dan tidak mengikat this

			// ──────────────────────────────────────────────────────────────
			// 1. Toggle status pause (switch antara pause & lanjut)
			// ──────────────────────────────────────────────────────────────
			isPaused = !isPaused;   // Membalik nilai boolean: true → false atau false → true
									// → Cara paling ringkas dan umum digunakan untuk toggle

			// ──────────────────────────────────────────────────────────────
			// 2. Update teks label tombol agar sesuai status saat ini
			// ──────────────────────────────────────────────────────────────
			pauseLabel.textContent = isPaused ? 'Lanjut' : 'Pause';
			// Ternary operator → sangat efisien
			// Jika paused → tampilkan "Lanjut" (artinya user bisa melanjutkan)
			// Jika tidak paused → tampilkan "Pause" (artinya user bisa pause lagi)
			// Catatan: "Lanjut" adalah pilihan bahasa Indonesia yang bagus untuk user lokal

			// ──────────────────────────────────────────────────────────────
			// 3. Jika tombol ditekan untuk "Lanjut" (tidak lagi paused) → lanjutkan proses
			// ──────────────────────────────────────────────────────────────
			if (!isPaused) {        // Hanya jalankan jika sekarang dalam kondisi "tidak pause"
				processNext();      // Langsung panggil proses berikutnya
									// → Ini membuat proses berlanjut secara otomatis setelah pause
									// → Sangat penting untuk fungsi "resume" yang mulus
			}
			// Catatan: Jika saat ini paused (isPaused = true), maka tidak ada yang dilakukan
			//         → proses akan tetap berhenti sampai user klik lagi untuk "Lanjut"
		};
	}

	if (btnStop) {  // Pengecekan keberadaan elemen → sangat baik (mencegah error jika tombol tidak ada di DOM)

		btnStop.onclick = () => {  // Menggunakan arrow function → modern, bersih, dan tidak mengikat this

			// ──────────────────────────────────────────────────────────────
			// 1. Menghentikan proses secara logis (flag global)
			// ──────────────────────────────────────────────────────────────
			isStopped = true;          // Flag utama → dicek di awal processNext() agar tidak lanjut
			isRunning = false;         // Mematikan status "sedang berjalan" → bagus
			isPaused   = false;        // Reset status pause agar konsisten

			// ──────────────────────────────────────────────────────────────
			// 2. Membersihkan timeout terjadwal terakhir (yang paling penting)
			// ──────────────────────────────────────────────────────────────
			if (timeoutId !== null) {
				clearTimeout(timeoutId);   // Membatalkan setTimeout terakhir yang disimpan
				timeoutId = null;          // Reset variabel → praktik baik agar tahu sudah dibersihkan
			}

			// ──────────────────────────────────────────────────────────────
			// 3. Fungsi pembersihan semua timeout di window (cara ekstrem)
			//    → Saat ini hanya didefinisikan, belum dijalankan
			// ──────────────────────────────────────────────────────────────
			window.clearAllTimeouts = function() {
				let id = window.setTimeout(null, 0);   // Mendapatkan ID timeout tertinggi saat ini
				while (id--) {                         // Loop mundur dari ID tertinggi ke 0
					window.clearTimeout(id);           // Bersihkan semua timeout yang mungkin ada
				}
			};
			// Catatan: Fungsi ini belum dipanggil (ada komentar // window.clearAllTimeouts();)
			//          → Jika dipanggil, akan membersihkan **semua** timeout di seluruh halaman
			//          → Berbahaya jika ada script lain di halaman yang menggunakan setTimeout
			// Rekomendasi: Jangan jalankan kecuali Anda benar-benar yakin tidak ada timeout lain

			// ──────────────────────────────────────────────────────────────
			// 4. Reset UI dan status baris tabel ke kondisi awal
			// ──────────────────────────────────────────────────────────────
			resetUI();                 // Fungsi existing → biasanya:
									   // • index = 0
									   // • hapus class processing/success/error/imported
									   // • reset badge ke 'Wait'
									   // • enable/disable tombol sesuai keadaan

			// ──────────────────────────────────────────────────────────────
			// 5. Hilangkan elemen visual proses
			// ──────────────────────────────────────────────────────────────
			hideProgress();            // Sembunyikan progress bar & container
			hideImportNotification();  // Sembunyikan seluruh notifikasi floating → sangat penting

			// ──────────────────────────────────────────────────────────────
			// 6. Reset semua data statistik & log (sangat bagus!)
			// ──────────────────────────────────────────────────────────────
			importStats = {            // Reset statistik ke nol → tampilan akan bersih setelah stop
				total: 0,
				success: 0,
				duplicate: 0,
				missingImage: 0,
				draft: 0,
				error: 0
			};
			recentLogs = [];           // Kosongkan daftar recent activity
			importLogs = [];           // Kosongkan daftar import log (error/warning)

			// Render ulang agar tampilan log benar-benar kosong
			renderRecentLogs();
			renderImportLogs();

			// ──────────────────────────────────────────────────────────────
			// 7. Kembalikan tombol ke kondisi siap pakai
			// ──────────────────────────────────────────────────────────────
			btnStart.disabled = false;
			btnStart.classList.remove('running');
			startLabel.textContent = 'Start Import';

			btnPause.disabled = true;
			btnPause.querySelector('.label').textContent = 'Pause';

			btnStop.disabled = true;   // Tombol stop tetap disabled setelah ditekan → logis

			// ──────────────────────────────────────────────────────────────
			// 8. Kembalikan kontrol penuh ke user (settings & tombol)
			// ──────────────────────────────────────────────────────────────
			enableSettingsFields();    // Kembalikan field input yang sebelumnya didisable
			enableSettingsButtons();   // Kembalikan tombol Save & Reset settings

			controlsWrapper?.classList.remove('is-sticky');
			controlsWrapper.style.display = 'none';

			removeTooltip(btnSaveSettings);
			removeTooltip(btnResetSettings);

			// ──────────────────────────────────────────────────────────────
			// 9. Berikan feedback kepada user
			// ──────────────────────────────────────────────────────────────
			showToast('⛔ Import process has been completely stopped', 'warning');

			// ──────────────────────────────────────────────────────────────
			// 10. Catat informasi terakhir di log (sangat membantu user)
			// ──────────────────────────────────────────────────────────────
			const stoppedMessage = `Import dihentikan. Progress: ${index} / ${rows.length} items`;
			addImportLog(stoppedMessage, 'warning');
		};
	}
	
	/* =========================
	   SAAT PASTE (CTRL+V atau Right-Click → Paste)
	========================= */
	// Event listener untuk menangkap aksi paste pada input base domain
	baseDomainInput.addEventListener('paste', (e) => {
		// 1. Cegah perilaku paste default browser
		//    → Penting! Agar kita bisa mengontrol 100% apa yang masuk ke input
		e.preventDefault();

		// 2. Ambil teks yang baru saja di-paste dari clipboard
		//    → e.clipboardData = modern browser (Chrome, Firefox, Edge)
		//    → window.clipboardData = fallback untuk IE lama (jarang dipakai sekarang)
		const pasted = (e.clipboardData || window.clipboardData)
			.getData('text'); // Hanya ambil teks biasa (bukan HTML atau file)

		// 3. Bersihkan teks yang di-paste menggunakan fungsi cleanUrl()
		//    → cleanUrl() akan menghapus semua spasi (awal, akhir, dan tengah)
		//    → Contoh: "  https:// example . com /  " → "https://example.com/"
		//    → Hasil langsung dimasukkan ke value input tanpa spasi sama sekali
		baseDomainInput.value = cleanUrl(pasted);

		// Catatan: Tidak perlu dispatch 'input' event karena value sudah berubah langsung
		//         → Browser otomatis akan trigger 'input' event setelah value berubah
	});

	/* =========================
	   SAAT KETIK / EDIT MANUAL
	========================= */
	// Event listener untuk setiap kali user mengetik, hapus, atau edit value input
	baseDomainInput.addEventListener('input', () => {
		// 1. Ambil value saat ini dari input
		//    → value bisa berubah karena ketik, hapus, atau paste (jika tidak dicegah)
		const currentValue = baseDomainInput.value;

		// 2. Bersihkan value menggunakan fungsi cleanUrl()
		//    → Hapus semua spasi tengah, spasi awal/akhir
		const cleaned = cleanUrl(currentValue);

		// 3. Bandingkan: jika value asli berbeda dengan yang sudah dibersihkan
		//    → Artinya ada spasi yang perlu dihapus
		if (baseDomainInput.value !== cleaned) {
			// 4. Ganti value input menjadi versi yang sudah dibersihkan
			//    → User akan melihat spasi langsung hilang saat mengetik
			baseDomainInput.value = cleaned;

			// Opsional: pindahkan kursor ke akhir setelah dibersihkan
			// → Agar pengalaman mengetik tetap nyaman
			baseDomainInput.selectionStart = baseDomainInput.selectionEnd = cleaned.length;
		}
		// Jika sama → tidak ada spasi, tidak lakukan apa-apa
	});
	
	// Default buka accordion pertama
	// → Tujuan: membuat item pertama di accordion langsung terbuka saat halaman dimuat
	// → Meningkatkan UX karena user langsung melihat konten utama tanpa harus klik manual
	const firstItem = document.querySelector('.ai-accordion .ai-acc-item');
	// → querySelector mengambil **elemen pertama** yang cocok dengan selector
	// → '.ai-accordion .ai-acc-item' → item pertama di dalam container accordion

	// Jika elemen pertama ditemukan → tambahkan class 'active'
	// → class 'active' biasanya mengatur accordion terbuka via CSS (display:block, dll)
	// → Pengecekan if(firstItem) → sangat aman, mencegah error jika tidak ada elemen
	if (firstItem) {
		firstItem.classList.add('active');
	}

	// Cari tombol "Save Settings" dengan selector yang sangat spesifik
	// → button.button-primary[type="submit"] → tombol submit utama di halaman admin WordPress
	// → class 'button-primary' adalah standar WordPress (biru, tebal)
	const btnSaveSettings = document.querySelector('button.button-primary[type="submit"]');

	// Cari tombol Reset Settings dengan cara bertahap & aman
	// → Mulai dari input hidden yang punya name unik (auto_importer_reset_settings)
	// → .closest('form') → naik ke elemen <form> terdekat
	// → .querySelector('button') → ambil button pertama di dalam form tersebut
	// → Optional chaining (?.) → sangat baik, jika salah satu bagian null → hasil akhir null
	//   → Tidak akan error meskipun struktur HTML berubah atau elemen tidak ada
	const btnResetSettings = document.querySelector('input[name="auto_importer_reset_settings"]')
		?.closest('form')
		?.querySelector('button');

	/**
	 * Menonaktifkan tombol Save Settings & Reset Settings
	 * → Biasanya dipanggil saat proses import mulai berjalan
	 * → Mencegah user mengubah pengaturan selama proses berlangsung
	 */
	function disableSettingsButtons() {
		// Jika tombol Save ditemukan → nonaktifkan & tambah class visual disabled
		if (btnSaveSettings) {
			btnSaveSettings.disabled = true;              // Nonaktifkan fungsi klik
			btnSaveSettings.classList.add('disabled');    // Tambah class untuk styling (abu-abu, cursor not-allowed)
		}

		// Sama untuk tombol Reset
		if (btnResetSettings) {
			btnResetSettings.disabled = true;
			btnResetSettings.classList.add('disabled');
		}
	}

	/**
	 * Mengaktifkan kembali tombol Save Settings & Reset Settings
	 * → Biasanya dipanggil setelah proses import selesai, di-stop, atau error
	 * → Memberi user kembali kontrol penuh atas pengaturan
	 */
	function enableSettingsButtons() {
		// Aktifkan kembali tombol Save & hapus class disabled
		if (btnSaveSettings) {
			btnSaveSettings.disabled = false;
			btnSaveSettings.classList.remove('disabled');
		}

		// Sama untuk tombol Reset
		if (btnResetSettings) {
			btnResetSettings.disabled = false;
			btnResetSettings.classList.remove('disabled');
		}
	}

	/* 
	=========================
	   CUSTOM SOURCE NOTICE
	========================= 
	*/
	
	/**
	 * Fungsi untuk menampilkan/menghilangkan notice khusus dan mengatur visibilitas kontrol
	 * berdasarkan pilihan source di select dropdown.
	 * 
	 * Dipanggil saat:
	 * - Halaman pertama kali dimuat
	 * - User mengubah pilihan source di dropdown
	 * 
	 * Logika utama:
	 * - Jika source = 'custom' → tampilkan warning + kunci semua kontrol import
	 * - Jika bukan 'custom' → sembunyikan warning + kembalikan kontrol ke normal
	 */
	function showCustomSourceNotice() {
		// 1. Hapus notice custom lama jika masih ada
		//    → Mencegah penumpukan notice saat user ganti source berulang kali
		const old = document.getElementById('ai-custom-notice');
		if (old) old.remove();

		// 2. Guard clause: jika elemen select source tidak ada → keluar
		//    → Sangat aman, mencegah error jika dropdown tidak ditemukan
		if (!sourceSelect) return;

		// 3. Cek apakah nilai select saat ini adalah 'custom'
		if (sourceSelect.value === 'custom') {
			// 4. Buat elemen notice baru (div warning)
			const notice = document.createElement('div');
			notice.id = 'ai-custom-notice';                    // ID unik untuk mudah dihapus nanti
			notice.className = 'notice notice-warning';        // Class WordPress standar untuk warning
			notice.style.marginTop = '10px';                   // Jarak atas agar rapi

			// Isi konten notice dengan HTML (pesan + link kontak)
			notice.innerHTML = `
				<p>
					⚠️ <strong>Custom source selected.</strong><br>
					This source requires a custom parser.<br>
					Please contact <a href="//exthem.es" target="_blank">exthem.es</a> before importing.
				</p>
			`;

			// 5. Tambahkan notice di bawah select (dalam <td> terdekat)
			//    → .closest('td') → naik ke sel tabel terdekat (parent)
			//    → Optional chaining (?.) → aman jika tidak ada <td>
			sourceSelect.closest('td')?.appendChild(notice);

			// 6. Sembunyikan baris base URL (jika ada)
			//    → Custom source tidak butuh base_url
			if (baseUrlRow) {
				baseUrlRow.style.display = 'none';
			}

			// 7. Sembunyikan seluruh wrapper kontrol import
			//    → Mencegah user mulai import dengan source custom yang belum dikonfigurasi
			if (controlsWrapper) controlsWrapper.style.display = 'none';

			// 8. Nonaktifkan tombol Start Import & tambahkan tooltip penjelasan
			if (btnStart) {
				btnStart.disabled = true;
				btnStart.title = 'Custom source requires admin configuration';
			}
		} 
		// 9. Kondisi jika source BUKAN 'custom' → kembalikan semua ke normal
		else {
			// 10. Tampilkan kembali baris base URL
			if (baseUrlRow) {
				baseUrlRow.style.display = '';
			}

			// 11. Tampilkan kembali wrapper kontrol import
			if (controlsWrapper) controlsWrapper.style.display = '';

			// 12. Aktifkan kembali tombol Start & hapus tooltip
			if (btnStart) {
				btnStart.disabled = false;
				btnStart.title = ''; // Hapus tooltip
			}
		}
	}

	// --- BAGIAN 1: KONTROL VISIBILITAS ---

	/**
	 * Menampilkan elemen notifikasi import ke layar.
	 * Digunakan tepat sebelum proses loop import dimulai.
	 */
	function showImportNotification() {
	  document.getElementById('import-notification').style.display = 'block';
	}

	/**
	 * Menyembunyikan elemen notifikasi.
	 * Biasanya dipanggil setelah tombol "Close" diklik atau proses selesai.
	 */
	function hideImportNotification() {
	  const notification = document.getElementById('import-notification');
	  if (notification) notification.style.display = 'none';
	}

	// --- BAGIAN 2: LOGIKA PROGRESS BAR ---

	/**
	 * Fungsi dasar untuk update progress.
	 * Mengatur angka jumlah (current/total), judul item, dan lebar progress bar (%).
	 */
	function updateImportProgress(current, total, title) { 
	  if (total <= 0) return;

	  const percent = Math.min(100, Math.round((current / total) * 100));
	  document.getElementById('current-count').textContent = current;
	  document.getElementById('total-count').textContent = total;
	  document.getElementById('current-item-title').textContent = title;
	  
	  // Menggerakkan progress bar secara visual
	  document.getElementById('progress-fill').style.width = percent + '%';
	}

	/**
	 * Versi 2: Fokus pada update judul teks dan link edit.
	 * Berguna untuk memberi tahu user item apa yang sedang diproses 
	 * dan memberikan akses cepat ke post yang baru jadi.
	 */
	function updateImportProgress2(current, total, currentTitle = '—', editLink = '') {
	  const notification = document.getElementById('import-notification');
	  // Proteksi: Jika notifikasi sedang tidak tampil, tidak perlu update DOM
	  if (!notification || notification.style.display === 'none') return;

	  const percent = Math.min(100, Math.round((current / total) * 100));
	  
	  // Update teks status item yang sedang aktif
	  document.getElementById('current-item-title').textContent = `Processing: ${currentTitle}`;

	  // Logika Menampilkan/Menyembunyikan Link Edit Post
	  const linkSection = document.getElementById('edit-link-section');
	  const editLinkEl = document.getElementById('edit-post-link');
	  
	  if (editLink && editLink !== '#') {
		editLinkEl.href = editLink;
		linkSection.style.display = 'block'; // Munculkan link jika sukses
	  } else {
		linkSection.style.display = 'none';  // Sembunyikan jika gagal/sedang proses
	  }
	}

	/**
	 * Versi 3: (Draft/Backup) Fokus pada pemberian warna status.
	 * Fungsi ini mengandung banyak comment-out, tapi logikanya ditujukan untuk 
	 * mengubah warna teks (hijau untuk sukses, merah untuk error).
	 */
	function updateImportProgress3(current, total, currentTitle = '—', statusText = 'Processing...', editLink = '') {
	  const el = document.getElementById('import-notification');
	  if (!el || el.style.display === 'none') return;

	  // Catatan: Anda menonaktifkan kode di sini. 
	  // Jika diaktifkan, ini sangat bagus untuk memberikan indikasi visual (Class CSS)
	  // berdasarkan apakah teks mengandung kata 'Success' atau 'Error'.
	}


	
});