<!doctype html>
<html lang="id">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1">
	<title>RAW Print SPK</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}
	</style>
</head>

<body>
	<div class="card">
		<h3 style="margin:0 0 6px">Print SPK (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>

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

	<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('operator/spk_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 elProfile = document.getElementById('profile');

			function setStatus(html){ elStatus.innerHTML = html; }
			function setProfileText(t){ elProfile.innerHTML = t || ''; }

			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 SPK");
				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") {
					setStatus('<span class="bad">JSPrintManager.js tidak ter-load.</span> Cek path assets/js/JSPrintManager.js.');
					return false;
				}

				try {
					JSPM.JSPrintManager.auto_reconnect = true;
					await JSPM.JSPrintManager.start(true, "localhost", 28443);

					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();
					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);
					});

					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) {
					setStatus('<span class="bad">Gagal connect ke JSPrintManager.</span> Pastikan JSPM running, port 28443 aktif, dan domain di-ALLOW. Detail: ' + (e.message || e));
					return false;
				}
			}

			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;
			}

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

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

					const payload = await loadRawB64();
					elPreview.textContent =
						"[SOURCE] " + RAW_URL + "\n" +
						"bytes: " + payload.bytes + "\n\n" +
						payload.b64.slice(0, 900) + (payload.b64.length > 900 ? "\n... (trimmed)" : "");

					const bytes = b64ToUint8Array(payload.b64);
					const cpj = new JSPM.ClientPrintJob();
					const installed = new JSPM.InstalledPrinter(printerName);

					if ("autoDetectRawModeDataType" in installed) {
						installed.autoDetectRawModeDataType = true;
					}
					cpj.clientPrinter = installed;

					if ("binaryPrinterCommands" in cpj) {
						cpj.binaryPrinterCommands = bytes;
					} else {
						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);
					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);

			await loadServerProfile();
			const ok = await initJSPM();
			if (ok) {
				setTimeout(() => { doPrint(); }, 350);
			} else {
				elPreview.textContent = "JSPM belum connect, auto-print dibatalkan.";
			}
		})();
	</script>
</body>
</html>
