import { computed, ref } from 'vue'; import { encodeOrderReceipt } from '@/lib/thermal-printer/encode-order-receipt'; import { normalizeEncoderOptions } from '@/lib/thermal-printer/normalize-encoder-options'; import { connectBluetooth, connectionState, connectUsb, disconnect as disconnectTransport, getBluetoothEncoderSettings, isWebBluetoothSupported, isWebSerialSupported, restoreConnection, sendPrintData, tryReconnect as tryReconnectTransport, } from '@/lib/thermal-printer/stable-transport'; import type { PaperSize } from '@/lib/thermal-printer/types'; import type { OrderListItem } from '@/types/order'; const connecting = ref(false); async function withConnecting(callback: () => Promise): Promise { connecting.value = true; try { return await callback(); } finally { connecting.value = false; } } export type PrintOrderReceiptOptions = { order: OrderListItem; paperSize: PaperSize; storeName: string; storeAddress: string; }; async function printOrderReceipt(options: PrintOrderReceiptOptions): Promise { const { order, paperSize, storeName, storeAddress } = options; let connection = connectionState.value; if (!connection) { const restored = await restoreConnection(); connection = connectionState.value; if (!restored || !connection) { throw new Error('Printer belum terhubung. Hubungkan printer terlebih dahulu.'); } } const bluetoothSettings = connection === 'bluetooth' ? getBluetoothEncoderSettings() : null; const encoderOptions = normalizeEncoderOptions({ language: bluetoothSettings?.language, codepageMapping: bluetoothSettings?.codepageMapping, }); const encoded = encodeOrderReceipt(order, { storeName, storeAddress, paperSize, language: connection === 'bluetooth' ? encoderOptions.language : undefined, codepageMapping: connection === 'bluetooth' ? encoderOptions.codepageMapping : undefined, }); await sendPrintData(encoded); } export function useThermalPrinter() { const isConnected = computed(() => connectionState.value !== null); const connectionLabel = computed(() => { const connection = connectionState.value; if (connection === 'usb') { return 'USB'; } if (connection === 'bluetooth') { return 'Bluetooth'; } return null; }); return { activeConnection: connectionState, isConnected, connectionLabel, connecting, connectUsb: () => withConnecting(connectUsb), connectBluetooth: () => withConnecting(connectBluetooth), tryReconnect: () => withConnecting(tryReconnectTransport), disconnect: disconnectTransport, printOrderReceipt, supportsUsb: isWebSerialSupported(), supportsBluetooth: isWebBluetoothSupported(), }; } export function getPaperSizeLabel(paperSize: PaperSize): string { return paperSize; }