<flux:main>
    <div class="flex justify-between items-center">
        <div>
            <flux:heading size="xl">{{ $pageTitle }}</flux:heading>
        </div>
        @can('create order')
            <div class="flex" x-data="{ isConnected: !!localStorage.getItem('printerDevice') }" @printer-status-change.window="isConnected = $event.detail.connected">
                <flux:button href="{{ route('studio.manage.order.create') }}" variant="primary" wire:navigate class="text-sm">
                    Tambah
                </flux:button>
                <template x-if="!isConnected">
                    <flux:button variant="primary" color="cyan" class="ms-2" wire:click="$dispatch('connectUSB')">
                        Connect USB
                    </flux:button>
                </template>
                <template x-if="isConnected">
                    <div class="ms-2 flex items-center gap-2 text-green-600 bg-green-50 px-3 py-1 rounded-lg border border-green-200">
                        <flux:icon.check-circle class="size-4" />
                        <span class="text-sm font-medium">Printer Connected</span>
                    </div>
                </template>
            </div>
        @endcan
    </div>

    <div class="mt-6">
        <livewire:datatable.manage.orders-table />
    </div>

    @include('components.modals.confirmation', [
        'modalName' => 'delete-confirmation',
        'modalTitle' => 'Apakah Anda yakin?',
        'modalMessage' => 'Data yang berelasi dengan data ini juga akan ikut terhapus.',
        'buttonVariant' => 'primary',
        'buttonColor' => 'danger',
        'buttonText' => 'Ya, Hapus',
    ])
    {{-- Print Modal --}}
    <flux:modal.trigger name="print-modal">
        <button id="btn-trigger-print-modal" class="hidden"></button>
    </flux:modal.trigger>

    <flux:modal name="print-modal" class="w-full max-w-sm">
        <div class="space-y-6" x-data="{ paperSize: '58' }">
            <div>
                <flux:heading size="lg">Cetak Struk</flux:heading>
                <flux:subheading>Pilih ukuran kertas printer thermal Anda.</flux:subheading>
            </div>

            <flux:radio.group label="Ukuran Kertas" x-model="paperSize">
                <flux:radio value="58" label="58mm" />
                <flux:radio value="80" label="80mm" />
            </flux:radio.group>

            <div class="flex justify-end gap-2">
                <flux:button variant="ghost" x-on:click="$dispatch('modal-close')">Batal</flux:button>
                <flux:button variant="primary"
                    x-on:click="$dispatch('trigger-print-process', { paperSize: paperSize })">
                    Cetak
                </flux:button>
            </div>
        </div>
    </flux:modal>
</flux:main>

@script
    <script>
        document.addEventListener('livewire:navigated', () => {
            window.printerDevice = null;
            let currentOrder = null;

            // Check if device is already stored
            const savedDevice = localStorage.getItem('printerDevice');
            if (savedDevice) {
                // Dispatch event to update UI
                setTimeout(() => window.dispatchEvent(new CustomEvent('printer-status-change', {
                    detail: {
                        connected: true
                    }
                })), 100);
            }

            Livewire.on('connectUSB', async (event) => {
                try {
                    const device = await navigator.usb.requestDevice({
                        filters: [{}]
                    });

                    await device.open();

                    if (device.configuration === null) {
                        await device.selectConfiguration(1);
                    }

                    await device.claimInterface(0);

                    window.printerDevice = device;

                    const deviceInfo = {
                        vendorId: device.vendorId,
                        productId: device.productId,
                        productName: device.productName,
                        manufacturerName: device.manufacturerName,
                        serialNumber: device.serialNumber
                    };

                    localStorage.setItem('printerDevice', JSON.stringify(deviceInfo));

                    console.log('Connected to:', device.productName);
                    window.dispatchEvent(new CustomEvent('printer-status-change', {
                        detail: {
                            connected: true
                        }
                    }));

                } catch (err) {
                    console.error('Gagal connect:', err);
                }
            });

            async function autoReconnect() {
                const saved = localStorage.getItem('printerDevice');

                if (!saved) return;

                const {
                    vendorId,
                    productId
                } = JSON.parse(saved);

                const devices = await navigator.usb.getDevices();

                const target = devices.find(d => d.vendorId === vendorId && d.productId === productId);

                if (!target) return;

                try {
                    await target.open();
                    if (target.configuration === null) {
                        await target.selectConfiguration(1);
                    }

                    await target.claimInterface(0);
                    window.printerDevice = target;

                    console.log('Auto reconnected to:', target.productName);
                    window.dispatchEvent(new CustomEvent('printer-status-change', {
                        detail: {
                            connected: true
                        }
                    }));
                } catch (err) {
                    console.error('Gagal autoreconnect:', err);
                    // If fail, remove storage
                    localStorage.removeItem('printerDevice');
                    window.dispatchEvent(new CustomEvent('printer-status-change', {
                        detail: {
                            connected: false
                        }
                    }));
                }
            }

            autoReconnect();

            navigator.usb.addEventListener('disconnect', event => {
                const device = event.device;
                const saved = localStorage.getItem('printerDevice');

                if (!saved) return;

                const {
                    vendorId,
                    productId
                } = JSON.parse(saved);

                if (device.vendorId === vendorId && device.productId === productId) {
                    localStorage.removeItem('printerDevice');
                    window.printerDevice = null;
                    console.log('USB dicabut, localStorage dibersihkan.');
                    window.dispatchEvent(new CustomEvent('printer-status-change', {
                        detail: {
                            connected: false
                        }
                    }));
                }
            });

            function getMaxChar(widthMM) {
                // 58mm uses approx 32 chars (Font A)
                // 80mm uses approx 42-48 chars (Font A)
                if (parseInt(widthMM) === 58) return 32;
                return 48; // for 80mm
            }

            Livewire.on('open-print-modal', (data) => {
                currentOrder = data; // Store data
                // Trigger modal open
                const btn = document.getElementById('btn-trigger-print-modal');
                if (btn) btn.click();
            });

            window.addEventListener('trigger-print-process', async (e) => {
                if (!currentOrder) return;
                const paperSize = e.detail.paperSize;

                // Close modal
                // Assuming Flux handles close on click or we dispatch close
                // We will try to close it via dispatching 'close-modal' if configured, but Flux 
                // buttons inside modal might need `data-flux-close` or similar? 
                // The provided code used $dispatch('modal-close') which might be custom.
                // We will proceed to print.

                // Ideally we close the modal:
                // document.dispatchEvent(new CustomEvent('close-modal', { detail: 'print-modal' })); // Hypothetical

                await printReceipt(currentOrder, parseInt(paperSize));
            });

            async function printReceipt(order, paperSize = 58) {
                if (!window.printerDevice) {
                    // Try auto reconnect if not connected but saved
                    await autoReconnect();
                    if (!window.printerDevice) {
                        alert("Printer belum terkoneksi via USB.");
                        return;
                    }
                }

                const encoder = new TextEncoder();
                const device = window.printerDevice;

                // ESC/POS Commands
                const ESC = "\x1B";
                const GS = "\x1D";
                const reset = new Uint8Array([0x1B, 0x40]);
                const alignLeft = new Uint8Array([0x1B, 0x61, 0]);
                const alignCenter = new Uint8Array([0x1B, 0x61, 1]);
                const alignRight = new Uint8Array([0x1B, 0x61, 2]);
                const cut = new Uint8Array([0x1D, 0x56, 0x00]);

                const MAX = getMaxChar(paperSize);
                const line = "-".repeat(MAX) + "\n";

                // Function to format text rows
                const formatRow = (left, right, maxLen) => {
                    let out = "";
                    const leftLen = left.length;
                    const rightLen = right.length;
                    const space = maxLen - leftLen - rightLen;

                    if (space >= 0) {
                        out += left + " ".repeat(space) + right + "\n";
                    } else {
                        // Wrap
                        out += left + "\n";
                        out += " ".repeat(maxLen - rightLen) + right + "\n";
                    }
                    return out;
                };

                // BUILD TEXT
                let text = "";

                // HEADER
                text += ESC + "\x61\x01"; // Center
                // text += ESC + "\x21\x30"; // Double Height Width logic? 0x30 = 00110000 -> bit 4,5 set.
                // Standard thermal printer double size:
                text += ESC + "!" + "\x10"; // Double Height
                text += "Yadi Parfum\n";
                text += ESC + "!" + "\x00"; // Normal

                if (order.outlet_address) {
                    text += order.outlet_address + "\n";
                }
                text += "\n";

                text += ESC + "\x61\x00"; // Left Align
                text += `Kasir    : ${order.cashier || '-'}\n`;
                text += `Customer : ${order.customer || '-'}\n`;
                text += `Tanggal  : ${new Date().toLocaleString('id-ID')}\n`;
                text += line;

                // CONTENT
                order.items.forEach((i, idx) => {
                    const isLast = idx === order.items.length - 1;

                    // Item Name
                    text += i.name + "\n";

                    // Quality or Quantity logic
                    // If quality is present and not 'Custom', show Quality
                    // Else show numeric math
                    const qualityName = (i.quality && i.quality !== 'Custom') ? i.quality : null;

                    if (qualityName) {
                        // Display: QualityName ......... TotalPrice
                        text += formatRow(qualityName, Number(i.total).toLocaleString('id-ID'), MAX);
                    } else {
                        // Display: 2 x 10,000 ......... 20,000
                        // i.quantity might be formatted string in some contexts, but here it's likely number from PHP
                        const qtyStr =
                            `${i.quantity} x ${Number(i.unit_price).toLocaleString('id-ID')}`;
                        text += formatRow(qtyStr, Number(i.total).toLocaleString('id-ID'), MAX);
                    }

                    // Add extra newline if not packed tight
                    text += "\n"; 
                });

                text += line;

                // FOOTER
                text += formatRow("Subtotal", Number(order.subtotal).toLocaleString('id-ID'), MAX);
                if (order.discount > 0) {
                    text += formatRow("Diskon", "-" + Number(order.discount).toLocaleString('id-ID'), MAX);
                }

                text += "\n";
                text += ESC + "\x61\x01"; // Center
                text += ESC + "\x45\x01"; // Bold On
                text += `TOTAL: ${Number(order.total).toLocaleString('id-ID')}\n`;
                text += ESC + "\x45\x00"; // Bold Off
                text += line;

                text += "Terima kasih telah berbelanja\n";
                text += "dan memilih Yadi Parfum :)\n";

                // Add some feed
                text += "\n\n\n";

                const textBytes = encoder.encode(text);

                // SEND
                await device.transferOut(1, reset);
                await device.transferOut(1, textBytes);
                await device.transferOut(1, cut);
            }
        });
    </script>
@endscript
