/**
 * print_manager.js
 * Modul untuk manajemen pencetakan dengan fitur failover (backup printer) dan logging.
 */

const PrintManager = {
    printers: [], // Akan diisi dengan data dari tabel 'kitchen'
    isInitialized: false,

    /**
     * Inisialisasi modul. Wajib dipanggil sekali saat aplikasi dimuat.
     * @returns {Promise<void>}
     */
    async init() {
        if (this.isInitialized) return;
        try {
            console.log('Menginisialisasi Print Manager...');
            const kitchenData = JSON.parse(await xambil('kitchen', 'id', '1', '999'));
            this.printers = kitchenData;
            this.isInitialized = true;
            console.log('Print Manager siap. Data printer berhasil dimuat:', this.printers);
        } catch (error) {
            console.error('Inisialisasi Print Manager Gagal:', error);
            // Tampilkan error ke pengguna jika perlu
            alert('KRITIS: Gagal memuat data printer. Fitur cetak tidak akan berfungsi.');
        }
    },

    /**
     * Fungsi utama untuk mencetak data.
     * @param {string} dataprint - Data teks ASCII yang akan dicetak.
     * @param {string} kode_printer - Kode printer utama (e.g., '01' untuk KITCHEN).
     * @param {string} tipe - Tipe cetakan untuk logging (e.g., 'BILL', 'ORDER').
     * @returns {Promise<boolean>} - True jika berhasil, false jika gagal.
     */
    async cetak(dataprint, kode_printer, tipe) {
        
        if (!this.isInitialized) {
            console.error('Print Manager belum diinisialisasi. Panggil PrintManager.init() terlebih dahulu.');
            return false;
        }

        const primaryPrinter = this.printers.find(p => p.kode === kode_printer);
        if (!primaryPrinter) {
            console.error(`Printer dengan kode '${kode_printer}' tidak ditemukan.`);
            return false;
        }

        try {
            // Coba cetak ke printer utama
            console.log(`Mencoba mencetak ke printer utama: ${primaryPrinter.nama} (${primaryPrinter.windows})`);
            await this._sendToPrintServer(dataprint, primaryPrinter);
            // -- TAMBAHKAN BARIS INI --
            await this._logCetak(dataprint, primaryPrinter, tipe, true); // Log sebagai sukses
            console.log(`Berhasil mengirim ke printer utama: ${primaryPrinter.nama}`);
            return true;

            return true;
        } catch (error) {
            // Jika Gagal, mulai alur failover
            await this._logCetak(dataprint, primaryPrinter, tipe, false); // Log sebagai gagal
            console.warn(`Gagal mencetak ke printer utama: ${primaryPrinter.nama}. Error: ${error}`);
            return await this._handleFailover(dataprint, primaryPrinter, tipe, error);
        }
    },

    /**
     * @private
     * Menangani alur saat printer utama gagal.
     */
async _logCetak(dataprint, printerInfo, tipe, isSuccess) {
    try {
        const now = new Date();
        const cetakData = {
            tanggal: now.toISOString().slice(0, 10),
            jam: now.toTimeString().slice(0, 8),
            tipe: tipe, // Tipe dari parameter fungsi cetak
            preview: dataprint, // Isi data teks yang dicetak
            printer_info: JSON.stringify({
                printerName: printerInfo.windows,
                port: `LPT${printerInfo.lpt}:`
            }),
            sukses: isSuccess ? 1 : 0, // 1 jika sukses, 0 jika gagal
            brand: window.xbrand || '',
            cab: window.xcab || ''
        };
        
        await tambahjson('cetak', cetakData);
        console.log(`Log cetak berhasil disimpan dengan status: ${isSuccess ? 'SUKSES' : 'GAGAL'}`);
    } catch (error) {
        console.error('Gagal menyimpan log ke tabel cetak:', error);
    }
},

    async _handleFailover(dataprint, primaryPrinter, tipe, initialError) {
        console.log('Memulai alur failover...');
        const backupCode = primaryPrinter.backup;

        if (!backupCode) {
            console.error(`Printer ${primaryPrinter.nama} tidak memiliki backup.`);
            await this._logReprint(dataprint, primaryPrinter.kode, tipe, 'failed', `Primary print failed, no backup available. Error: ${initialError}`);
            return false;
        }

        const backupPrinter = this.printers.find(p => p.kode === backupCode);
        if (!backupPrinter) {
            console.error(`Printer backup dengan kode '${backupCode}' tidak ditemukan.`);
            await this._logReprint(dataprint, primaryPrinter.kode, tipe, 'failed', `Primary print failed, backup printer '${backupCode}' not found.`);
            return false;
        }

        // Minta konfirmasi dari pengguna
        const userConfirmed = await window.showConfirmationDialog(
            `Printer ${primaryPrinter.nama} gagal merespon. Alihkan ke printer backup ${backupPrinter.nama}?`
        );

        if (userConfirmed) {
            try {
                // Coba cetak ke printer backup
                console.log(`Mencoba mencetak ke printer backup: ${backupPrinter.nama}`);
                await this._sendToPrintServer(dataprint, backupPrinter);
                console.log(`Berhasil mencetak via printer backup: ${backupPrinter.nama}`);
                await this._logReprint(dataprint, backupPrinter.kode, tipe, 'success', `Redirected from ${primaryPrinter.kode}.`);
                return true;
            } catch (backupError) {
                console.error(`Gagal mencetak ke printer backup ${backupPrinter.nama}. Error: ${backupError}`);
                await this._logReprint(dataprint, primaryPrinter.kode, tipe, 'failed', `Primary and backup printers failed. Backup Error: ${backupError}`);
                return false;
            }
        } else {
            // Pengguna menolak untuk beralih
            console.log('Pengguna menolak untuk mencetak ke printer backup.');
            await this._logReprint(dataprint, primaryPrinter.kode, tipe, 'failed', 'User rejected backup printer option.');
            return false;
        }
    },

    /**
     * @private
     * Mengirim data ke server WebSocket cetak.js.
     */
    _sendToPrintServer(textData, printerInfo) {
    return new Promise((resolve, reject) => {
        const ws = new WebSocket('ws://localhost:8080');

        const textToHex = (str) => {
            let hex = '';
            for (let i = 0; i < str.length; i++) {
                hex += str.charCodeAt(i).toString(16).padStart(2, '0');
            }
            return hex;
        };

        ws.onopen = () => {
            ws.send(JSON.stringify({
                action: 'cetak',
                nama_printer: printerInfo.windows,
                port: `LPT${printerInfo.lpt}:`,
                printData: textToHex(textData)
            }));
        };

        ws.onmessage = (event) => {
            const response = JSON.parse(event.data);

            // --- AWAL PERUBAIKAN LOGIKA ---
            if (response.type === 'success') {
                ws.close();
                resolve(response.message); // Promise selesai dan berhasil
            } else if (response.type === 'error') {
                ws.close();
                reject(response.message); // Promise selesai dan gagal
            }
            // Jika response.type adalah 'info' atau lainnya, kita abaikan dan biarkan koneksi terbuka
            // untuk menunggu pesan status final.
            console.log('Print status update:', response.message);
            // --- AKHIR PERUBAIKAN LOGIKA ---
        };

        ws.onerror = (error) => {
            reject('Tidak dapat terhubung ke Print Server.');
        };
    });
},
    
    /**
     * @private
     * Mencatat hasil cetak ke tabel 'reprint'.
     */
    async _logReprint(dataprint, printerCode, tipe, status, note) {
        try {
            const reprintData = {
                tanggal: new Date().toISOString().slice(0, 10),
                jam: new Date().toTimeString().slice(0, 8),
                printer: printerCode,
                tipe: tipe,
                status: status, // 'success' atau 'failed'
                data: dataprint,
                note: note,
                brand: window.xbrand || '', // Asumsi ada variabel global
                cab: window.xcab || ''      // Asumsi ada variabel global
            };
            await tambahjson('reprint', reprintData);
            console.log(`Berhasil mencatat ke tabel reprint dengan status: ${status}`);
        } catch (error) {
            console.error('Gagal mencatat ke tabel reprint:', error);
        }
    }
};