/**
 * Thermal Printer Helper untuk 58mm Bluetooth Printer
 * Menggunakan Web Bluetooth API untuk Chrome Android
 * 
 * Kompatibel dengan:
 * - ESC/POS Bluetooth Thermal Printer 58mm
 * - Chrome Android (harus HTTPS atau localhost)
 */

class ThermalPrinter {
    constructor() {
        this.device = null;
        this.characteristic = null;
        this.encoder = new TextEncoder('windows-1252');
        
        // ESC/POS Commands
        this.ESC = '\x1B';
        this.GS = '\x1D';
        this.Commands = {
            INIT: '\x1B\x40',           // Initialize printer
            ALIGN_LEFT: '\x1B\x61\x00',  // Align left
            ALIGN_CENTER: '\x1B\x61\x01', // Align center
            ALIGN_RIGHT: '\x1B\x61\x02', // Align right
            BOLD_ON: '\x1B\x45\x01',    // Bold on
            BOLD_OFF: '\x1B\x45\x00',   // Bold off
            SIZE_NORMAL: '\x1D\x21\x00', // Normal size
            SIZE_DOUBLE: '\x1D\x21\x11', // Double size
            SIZE_LARGE: '\x1D\x21\x22',  // Large size
            NEWLINE: '\n',
            CUT_PAPER: '\x1D\x56\x00',   // Cut paper
            FEED_3: '\x1B\x64\x03',      // Feed 3 lines
        };
    }

    /**
     * Check apakah Web Bluetooth didukung
     */
    isSupported() {
        if (!navigator.bluetooth) {
            console.warn('Web Bluetooth API tidak didukung di browser ini.');
            return false;
        }
        return true;
    }

    /**
     * Connect ke Bluetooth printer
     */
    async connect() {
        if (!this.isSupported()) {
            throw new Error('Web Bluetooth tidak didukung di browser ini. Gunakan Chrome Android atau Chrome Desktop.');
        }

        try {
            console.log('Mencari Bluetooth printer...');
            
            // Request Bluetooth device
            this.device = await navigator.bluetooth.requestDevice({
                filters: [
                    { services: ['000018f0-0000-1000-8000-00805f9b34fb'] }, // ESC/POS service
                ],
                optionalServices: [
                    '000018f0-0000-1000-8000-00805f9b34fb',
                    '49535343-fe7d-4ae5-8fa9-9fafd205e455' // Alternate service UUID
                ]
            });

            console.log('Printer ditemukan:', this.device.name);
            console.log('Menghubungkan ke GATT Server...');
            
            const server = await this.device.gatt.connect();
            console.log('Terhubung! Mencari service...');
            
            // Try to get the primary service
            let service;
            try {
                service = await server.getPrimaryService('000018f0-0000-1000-8000-00805f9b34fb');
            } catch (e) {
                console.log('Service pertama tidak ditemukan, mencoba alternatif...');
                service = await server.getPrimaryService('49535343-fe7d-4ae5-8fa9-9fafd205e455');
            }
            
            console.log('Service ditemukan! Mencari characteristic...');
            
            // Get the characteristic
            const characteristics = await service.getCharacteristics();
            console.log('Characteristics ditemukan:', characteristics.length);
            
            // Find writable characteristic
            for (const char of characteristics) {
                if (char.properties.write || char.properties.writeWithoutResponse) {
                    this.characteristic = char;
                    console.log('Characteristic writable ditemukan:', char.uuid);
                    break;
                }
            }
            
            if (!this.characteristic) {
                throw new Error('Tidak dapat menemukan writable characteristic');
            }
            
            console.log('✅ Terhubung ke printer!');
            return true;
            
        } catch (error) {
            console.error('Error connecting to printer:', error);
            throw new Error(`Gagal terhubung ke printer: ${error.message}`);
        }
    }

    /**
     * Disconnect dari printer
     */
    disconnect() {
        if (this.device && this.device.gatt.connected) {
            this.device.gatt.disconnect();
            console.log('Printer disconnected');
        }
    }

    /**
     * Kirim raw data ke printer
     */
    async sendRaw(data) {
        if (!this.characteristic) {
            throw new Error('Printer belum terhubung. Silakan hubungkan dulu.');
        }

        try {
            // Convert string to ArrayBuffer
            const buffer = this.encoder.encode(data);
            
            // Split into chunks (Bluetooth has max packet size)
            const chunkSize = 512; // Safe size for most Bluetooth printers
            for (let i = 0; i < buffer.length; i += chunkSize) {
                const chunk = buffer.slice(i, Math.min(i + chunkSize, buffer.length));
                await this.characteristic.writeValue(chunk);
                
                // Small delay between chunks
                if (i + chunkSize < buffer.length) {
                    await new Promise(resolve => setTimeout(resolve, 50));
                }
            }
        } catch (error) {
            console.error('Error sending data to printer:', error);
            throw new Error(`Gagal mengirim data ke printer: ${error.message}`);
        }
    }

    /**
     * Print text dengan formatting
     */
    async printText(text, options = {}) {
        const {
            align = 'left',
            bold = false,
            size = 'normal'
        } = options;

        let command = '';

        // Set alignment
        if (align === 'center') command += this.Commands.ALIGN_CENTER;
        else if (align === 'right') command += this.Commands.ALIGN_RIGHT;
        else command += this.Commands.ALIGN_LEFT;

        // Set bold
        if (bold) command += this.Commands.BOLD_ON;

        // Set size
        if (size === 'double') command += this.Commands.SIZE_DOUBLE;
        else if (size === 'large') command += this.Commands.SIZE_LARGE;
        else command += this.Commands.SIZE_NORMAL;

        // Add text
        command += text;

        // Reset formatting
        command += this.Commands.BOLD_OFF;
        command += this.Commands.SIZE_NORMAL;

        await this.sendRaw(command);
    }

    /**
     * Print line separator
     */
    async printLine(char = '-') {
        const line = char.repeat(32); // 32 characters untuk 58mm
        await this.sendRaw(line + this.Commands.NEWLINE);
    }

    /**
     * Print newline
     */
    async newLine(count = 1) {
        await this.sendRaw(this.Commands.NEWLINE.repeat(count));
    }

    /**
     * Cut paper
     */
    async cutPaper() {
        await this.sendRaw(this.Commands.FEED_3 + this.Commands.CUT_PAPER);
    }

    /**
     * Initialize printer (reset)
     */
    async initialize() {
        await this.sendRaw(this.Commands.INIT);
    }

    /**
     * Print struk lengkap (helper)
     */
    async printReceipt(data) {
        try {
            await this.initialize();

            // Header
            await this.printText('UMBUL TIRTOMARTO', { align: 'center', bold: true, size: 'double' });
            await this.newLine();
            await this.printText('Wahana Kreasi Nusantara', { align: 'center' });
            await this.printText('Jl. Raya Tirtomarto', { align: 'center' });
            await this.newLine();
            await this.printLine('=');

            // Info transaksi
            await this.printText(`No: ${data.id}`, { align: 'left' });
            await this.printText(`Tgl: ${data.tanggal}`, { align: 'left' });
            await this.printText(`Kasir: ${data.kasir}`, { align: 'left' });
            await this.printLine('-');

            // Items
            for (const item of data.items) {
                await this.printText(item.nama, { align: 'left' });
                const itemLine = `${item.quantity} x ${this.formatRupiah(item.harga)}`.padEnd(20) + 
                                this.formatRupiah(item.subtotal).padStart(12);
                await this.printText(itemLine, { align: 'left', size: 'normal' });
            }

            await this.printLine('-');

            // Total
            const totalLine = 'TOTAL:'.padEnd(20) + this.formatRupiah(data.total).padStart(12);
            await this.printText(totalLine, { bold: true, size: 'large' });
            
            await this.printLine('=');
            await this.newLine();
            await this.printText('Terima Kasih', { align: 'center', bold: true });
            await this.printText('Selamat Berkunjung Kembali', { align: 'center' });
            await this.newLine(3);

            // Cut paper
            await this.cutPaper();

            console.log('✅ Receipt printed successfully');
        } catch (error) {
            console.error('Error printing receipt:', error);
            throw error;
        }
    }

    /**
     * Format rupiah helper
     */
    formatRupiah(amount) {
        return 'Rp ' + Number(amount).toLocaleString('id-ID');
    }
}

// Export untuk digunakan di file lain
window.ThermalPrinter = ThermalPrinter;
