<!doctype html>
<html lang="id">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1">
	<title>RAW Print</title>

	<script src="<?= base_url('assets/js/JSPrintManager.js'); ?>"></script>

	<style>
		body{font-family:system-ui,Segoe UI,Arial,sans-serif; padding:14px; background:#f6f7fb;}
		.card{background:#fff; border:1px solid rgba(0,0,0,.08); border-radius:12px; padding:14px; max-width:560px; margin:0 auto;}
		.row{display:flex; gap:10px; flex-wrap:wrap; align-items:center}
		.muted{color:#6b7280; font-size:13px; margin-top:6px}
		.btn{border:0; padding:10px 12px; border-radius:10px; cursor:pointer; font-weight:700}
		.btn-primary{background:#4f46e5; color:#fff}
		.btn-ghost{background:#eef2ff; color:#1f2937}
		select{padding:10px 12px; border-radius:10px; border:1px solid rgba(0,0,0,.12); min-width:220px}
		pre{white-space:pre-wrap; background:#0b1220; color:#e5e7eb; padding:10px; border-radius:10px; max-height:220px; overflow:auto; font-size:12px}
		.ok{color:#16a34a; font-weight:800}
		.bad{color:#dc2626; font-weight:800}
		.install-panel{display:none;margin-top:14px;padding:16px;border:1px solid #fecaca;border-radius:12px;background:#fff7f7}.install-panel.show{display:block}.install-head{display:flex;align-items:flex-start;gap:11px}.install-icon{display:flex;align-items:center;justify-content:center;width:38px;height:38px;flex:0 0 38px;border-radius:11px;background:#fee2e2;color:#dc2626;font-size:20px;font-weight:900}.install-head h4{margin:0 0 4px;color:#991b1b;font-size:15px}.install-head p{margin:0;color:#7f1d1d;font-size:12px;line-height:1.45}.install-steps{margin:13px 0;padding-left:20px;color:#4b5563;font-size:12px;line-height:1.65}.downloads{display:flex;gap:8px;flex-wrap:wrap}.downloads a{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:9px 11px;border:1px solid #dbe3ee;border-radius:9px;background:#fff;color:#26354d;font-size:12px;font-weight:700;text-decoration:none}.downloads a.recommended{border-color:#4f46e5;background:#4f46e5;color:#fff}.install-actions{display:flex;align-items:center;gap:9px;margin-top:12px;padding-top:12px;border-top:1px solid #fee2e2}.install-error{flex:1;color:#9f1239;font-size:11px;word-break:break-word}@media(max-width:600px){body{padding:8px}.card{padding:12px}.downloads a{width:100%}.install-actions{align-items:stretch;flex-direction:column}.install-actions .btn{width:100%}}
	</style>
</head>

<body>
	<div class="card">
		<?php if (!empty($choose_printer)) { ?>
		<h3 style="margin:0 0 6px">Pilih printer aktif</h3>
		<div class="muted">Pilih printer sebelum proses cetak berjalan.</div>
		<div style="margin-top:12px">
			<?php foreach ($active_printers as $printer) {
				$slug = strtolower(trim((string)($printer['slug'] ?? '')));
				$isInvoice = in_array($slug, ['in', 'dotmatrix'], true);
				$query = '?printer_id='.(int)$printer['id'];
				$url = $isInvoice
					? base_url('produk/print_invoice_html/'.$token).$query
					: base_url('produk/print_thermal_raw/'.$token).$query;
				$detail = trim(($printer['shared_name'] ?? '').' - '.($printer['ukuran_kertas'] ?? '').' '.($printer['posisi'] ?? ''));
			?>
				<button class="btn btn-ghost" style="display:block;width:100%;text-align:left;margin-bottom:8px" onclick="window.location.href='<?= htmlspecialchars($url, ENT_QUOTES); ?>'">
					<b><?= htmlspecialchars($printer['name'] ?? 'Printer', ENT_QUOTES); ?></b><br>
					<span class="muted"><?= $isInvoice ? 'Cetak invoice' : 'Cetak struk invoice'; ?> - <?= htmlspecialchars($detail, ENT_QUOTES); ?></span>
				</button>
			<?php } ?>
		</div>
		<?php } else { ?>
		<h3 style="margin:0 0 6px">Print Struk (RAW ESC/POS)</h3>
		<div id="status" class="muted">Menyiapkan koneksi JSPrintManager…</div>

		<div class="row" style="margin-top:10px">
			<select id="printer"></select>
			<button class="btn btn-ghost" id="btnSave">Simpan Default</button>
			<button class="btn btn-primary" id="btnPrint">PRINT ULANG</button>
		</div>
		<div id="profile" class="muted" style="margin-top:6px"></div>

		<div class="muted">
			Pastikan JSPrintManager running & domain di-ALLOW. Port: <b>28443 (SSL)</b>.
		</div>

		<section class="install-panel" id="installPanel" aria-live="polite">
			<div class="install-head"><span class="install-icon">!</span><div><h4>JSPrintManager belum terpasang atau belum berjalan</h4><p>Install aplikasi pendamping pada komputer yang terhubung ke printer thermal, kemudian jalankan aplikasinya.</p></div></div>
			<ol class="install-steps"><li>Unduh installer yang sesuai dengan perangkat pengguna.</li><li>Jalankan installer sampai selesai, lalu buka JSPrintManager.</li><li>Izinkan domain aplikasi jika diminta, kemudian klik <b>Coba Hubungkan Lagi</b>.</li></ol>
			<div class="downloads">
				<a id="downloadWindows" href="<?=base_url('assets/downloads/jsprintmanager/JSPrintManager-8.0.26-Windows.exe');?>" download><span>↓</span> Windows (.exe)</a>
				<a id="downloadMac" href="<?=base_url('assets/downloads/jsprintmanager/JSPrintManager-8.0.26-macOS.pkg');?>" download><span>↓</span> macOS (.pkg)</a>
				<a id="downloadAndroid" href="<?=base_url('assets/downloads/jsprintmanager/JSPrintManager-8.0.26-Android.apk');?>" download><span>↓</span> Android (.apk)</a>
			</div>
			<div class="install-actions"><span class="install-error" id="installError"></span><button type="button" class="btn btn-primary" id="btnRetryJspm">Coba Hubungkan Lagi</button></div>
		</section>

		<div style="margin-top:12px">
			<div class="muted">Debug payload RAW (base64 snippet):</div>
			<pre id="preview">Loading…</pre>
		</div>
		<?php } ?>
	</div>

	<?php if (empty($choose_printer)) { ?>
	<script>
		(async function(){
			const TOKEN = "<?= htmlspecialchars($token, ENT_QUOTES); ?>";
			const PRINTER_ID = <?= isset($printer_id) ? (int) $printer_id : 0; ?>;
			const PRINTER_QUERY = PRINTER_ID > 0 ? "?printer_id=" + encodeURIComponent(PRINTER_ID) : "";
			const PROFILE_URL = "<?= base_url('produk/printer_profile'); ?>" + PRINTER_QUERY;
			const RAW_URL = "<?= base_url('produk/raw_cmd/'); ?>" + TOKEN + PRINTER_QUERY;

			const elStatus = document.getElementById('status');
			const elPrinter = document.getElementById('printer');
			const elPreview = document.getElementById('preview');
			const btnPrint = document.getElementById('btnPrint');
			const btnSave  = document.getElementById('btnSave');
			const installPanel = document.getElementById('installPanel');
			const installError = document.getElementById('installError');
			const btnRetryJspm = document.getElementById('btnRetryJspm');

			const elProfile = document.getElementById('profile');
			let jspmConnected = false;
			let installerWatchdog = null;
			function setStatus(html){ elStatus.innerHTML = html; }
			function setProfileText(t){ elProfile.innerHTML = t || ''; }
			function clearInstallerWatchdog(){
				if (installerWatchdog !== null) {
					clearTimeout(installerWatchdog);
					installerWatchdog = null;
				}
			}
			function armInstallerWatchdog(){
				clearInstallerWatchdog();
				installerWatchdog = setTimeout(() => {
					if (jspmConnected) return;
					setStatus('<span class="bad">JSPrintManager tidak terdeteksi.</span> Unduh dan install aplikasi pendamping di bawah ini.');
					elPreview.textContent = 'JSPrintManager belum terhubung. Install dan jalankan JSPrintManager, lalu klik Coba Hubungkan Lagi.';
					showInstaller('Layanan lokal JSPrintManager tidak memberi respons pada port 28443.');
				}, 5000);
			}
			function showInstaller(error){
				const ua = navigator.userAgent || '';
				const platform = (navigator.userAgentData && navigator.userAgentData.platform) || navigator.platform || '';
				let recommended = 'downloadWindows';
				if (/android/i.test(ua)) recommended = 'downloadAndroid';
				else if (/mac/i.test(platform)) recommended = 'downloadMac';
				document.querySelectorAll('.downloads a').forEach(a => a.classList.toggle('recommended', a.id === recommended));
				installError.textContent = error ? 'Detail koneksi: ' + error : '';
				installPanel.classList.add('show');
				btnPrint.disabled = true;
				btnSave.disabled = true;
				installPanel.scrollIntoView({behavior:'smooth', block:'nearest'});
			}
			function hideInstaller(){
				installPanel.classList.remove('show');
				btnPrint.disabled = false;
				btnSave.disabled = false;
			}
			btnRetryJspm.addEventListener('click', () => window.location.reload());

  // base64 -> binary string (aman utk bytes ESC/POS)
			function b64ToBinaryString(b64){
				return atob(b64);
			}

			async function loadRawB64(){
				const res = await fetch(RAW_URL, { credentials: 'same-origin' });
				if (!res.ok) throw new Error("HTTP " + res.status);
				const js = await res.json();
				if (!js.ok) throw new Error(js.message || "Gagal build RAW");
				return js;
			}

			let serverProfile = null;
			async function loadServerProfile(){
				try{
					const res = await fetch(PROFILE_URL, { credentials:'same-origin' });
					if(!res.ok) return null;
					const js = await res.json();
					if(js && js.ok){
						serverProfile = js;
						const label = (js.name ? '<b>' + js.name + '</b>' : '');
						const shared = (js.shared_name ? ' — <span class="text-muted">' + js.shared_name + '</span>' : '');
						const extra = (js.slug ? ' <span class="badge badge-light">' + js.slug + '</span>' : '');
						setProfileText('Profil default (server): ' + label + shared + extra);
					}
					return serverProfile;
				}catch(e){ return null; }
			}

			async function initJSPM(){
				if (typeof JSPM === "undefined") {
					clearInstallerWatchdog();
					setStatus('<span class="bad">JSPrintManager.js tidak ter-load.</span> Cek path assets/js/JSPrintManager.js (case-sensitive).');
					showInstaller('Library JSPrintManager tidak dapat dimuat.');
					return false;
				}

				try {
					JSPM.JSPrintManager.auto_reconnect = true;
					await Promise.race([
						Promise.resolve(JSPM.JSPrintManager.start(true, "localhost", 28443)),
						new Promise((resolve, reject) => setTimeout(() => reject(new Error("JSPrintManager tidak merespons dalam 5 detik")), 5000))
					]);

					const waitReady = () => new Promise((resolve, reject) => {
						const t0 = Date.now();
						const timer = setInterval(() => {
							if (JSPM.JSPrintManager.websocket_status === JSPM.WSStatus.Open) {
								clearInterval(timer); resolve(true);
							}
							if (Date.now() - t0 > 8000) { clearInterval(timer); reject(new Error("Timeout connect WS")); }
						}, 200);
					});

					await waitReady();
					jspmConnected = true;
					clearInstallerWatchdog();
					hideInstaller();
					setStatus('<span class="ok">Tersambung ke JSPrintManager ✅</span> (auto-print berjalan)');

					const printers = await JSPM.JSPrintManager.getPrinters();
					elPrinter.innerHTML = "";
					printers.forEach(p => {
						const opt = document.createElement("option");
						opt.value = p; opt.textContent = p;
						elPrinter.appendChild(opt);
					});

					// prioritas: printer aktif dari server, fallback ke pilihan user di browser
					const saved = localStorage.getItem("POS_PRINTER_DEFAULT") || "";
					if (serverProfile && serverProfile.shared_name && printers.includes(serverProfile.shared_name)) {
						elPrinter.value = serverProfile.shared_name;
					} else if (saved && printers.includes(saved)) {
						elPrinter.value = saved;
					}

					return true;
				} catch (e) {
					jspmConnected = false;
					clearInstallerWatchdog();
					setStatus('<span class="bad">Gagal connect ke JSPrintManager.</span> Pastikan JSPM running, port 28443 aktif, dan domain di-ALLOW. Detail: ' + (e.message || e));
					showInstaller(e && e.message ? e.message : String(e));
					return false;
				}
			}

			async function doPrint(){
				try {
					btnPrint.disabled = true;
					setStatus('Menyiapkan RAW & mengirim ke printer…');

					const printerName = elPrinter.value;
					if (!printerName) throw new Error("Pilih printer dulu.");

					const payload = await loadRawB64();

      // tampilkan snippet base64 untuk debug (bukan full biar ringan)
					elPreview.textContent =
					"[SOURCE] " + RAW_URL + "\n" +
					"bytes: " + payload.bytes + "\n\n" +
					payload.b64.slice(0, 900) + (payload.b64.length > 900 ? "\n... (trimmed)" : "");

      // base64 -> Uint8Array (BINARY ASLI, aman utk logo/QRIS)
					function b64ToUint8Array(b64) {
						const bin = atob(b64);
						const len = bin.length;
						const bytes = new Uint8Array(len);
						for (let i = 0; i < len; i++) bytes[i] = bin.charCodeAt(i);
							return bytes;
					}

					const bytes = b64ToUint8Array(payload.b64);

					const cpj = new JSPM.ClientPrintJob();
					const installed = new JSPM.InstalledPrinter(printerName);
					// Paksa auto-detect RAW di sisi driver agar bytes bitmap ESC/POS tidak diperlakukan sebagai teks.
					if ("autoDetectRawModeDataType" in installed) {
						installed.autoDetectRawModeDataType = true;
					}
					cpj.clientPrinter = installed;

// ✅ kirim sebagai binary (INI YANG MEMPERBAIKI LOGO & QRIS)
					if ("binaryPrinterCommands" in cpj) {
						cpj.binaryPrinterCommands = bytes;
					} else {
  // fallback kalau versi JSPM lama (tetap jalan, tapi bisa kembali rusak utk gambar)
						let s = "";
						for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
							cpj.printerCommands = s;
					}

					await cpj.sendToClient();


					setStatus('<span class="ok">SUKSES ✅</span> Terkirim ke printer: ' + printerName);

      // auto close tab setelah sukses
					setTimeout(() => { window.close(); }, 900);

				} catch (e) {
					setStatus('<span class="bad">PRINT GAGAL:</span> ' + (e.message || e));
				} finally {
					btnPrint.disabled = false;
				}
			}

			btnSave.addEventListener("click", () => {
				const p = elPrinter.value || "";
				if (!p) return alert("Pilih printer dulu.");
				localStorage.setItem("POS_PRINTER_DEFAULT", p);
				alert("✅ Default printer disimpan: " + p);
			});

			btnPrint.addEventListener("click", doPrint);

  // ===== AUTO PRINT SAAT DIBUKA =====
			armInstallerWatchdog();
			await loadServerProfile();
			const ok = await initJSPM();
			if (ok) {
    // kasih delay kecil biar list printer kebaca stabil
				setTimeout(() => { doPrint(); }, 350);
			} else {
				elPreview.textContent = "JSPM belum connect, auto-print dibatalkan.";
			}
		})();
	</script>
	<?php } ?>
</body>
</html>
