<?php if (isset($component)) { $__componentOriginal5863877a5171c196453bfa0bd807e410 = $component; } ?>
<?php if (isset($attributes)) { $__attributesOriginal5863877a5171c196453bfa0bd807e410 = $attributes; } ?>
<?php $component = Illuminate\View\AnonymousComponent::resolve(['view' => 'components.layouts.app','data' => ['title' => 'POS']] + (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag ? $attributes->all() : [])); ?>
<?php $component->withName('layouts.app'); ?>
<?php if ($component->shouldRender()): ?>
<?php $__env->startComponent($component->resolveView(), $component->data()); ?>
<?php if (isset($attributes) && $attributes instanceof Illuminate\View\ComponentAttributeBag): ?>
<?php $attributes = $attributes->except(\Illuminate\View\AnonymousComponent::ignoredParameterNames()); ?>
<?php endif; ?>
<?php $component->withAttributes(['title' => 'POS']); ?>
    <div
        x-data="posApp({
            categories: <?php echo \Illuminate\Support\Js::from($categories)->toHtml() ?>,
            products: <?php echo \Illuminate\Support\Js::from($products)->toHtml() ?>,
            registers: <?php echo \Illuminate\Support\Js::from($registers)->toHtml() ?>,
            defaultRegisterId: <?php echo \Illuminate\Support\Js::from($defaultRegisterId)->toHtml() ?>,
            syncUrl: '<?php echo e(url('/api/sync/orders')); ?>',
            orderStoreUrl: '<?php echo e(route('pos.orders.store')); ?>',
            csrf: '<?php echo e(csrf_token()); ?>'
        })"
        x-init="init()"
        class="grid gap-4 xl:grid-cols-[1fr_390px]"
    >
        <section class="surface p-4">
            <div class="mb-4 flex flex-wrap items-center gap-2">
                <input x-ref="searchBox" x-model="search" placeholder="Cari menu (tekan /)"
                       class="min-w-56 flex-1 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-sm outline-none focus:border-sky-300 focus:bg-white">
                <template x-for="cat in categories" :key="cat.id">
                    <button @click="activeCategory = cat.id"
                            class="rounded-xl px-3 py-2 text-sm font-medium transition"
                            :class="activeCategory === cat.id ? 'bg-slate-900 text-white' : 'bg-slate-100 text-slate-600 hover:bg-slate-200'">
                        <span x-text="cat.name"></span>
                    </button>
                </template>
            </div>

            <div class="grid grid-cols-2 gap-3 md:grid-cols-3 2xl:grid-cols-4">
                <template x-for="product in filteredProducts" :key="product.id">
                    <button @click="openModifierModal(product)"
                            class="group overflow-hidden rounded-2xl border border-slate-200 bg-white text-left transition hover:-translate-y-0.5 hover:border-slate-300 hover:shadow-md">
                        <div class="aspect-[4/3] bg-slate-100">
                            <img :src="product.image_url || '/icons/icon-512.svg'" alt=""
                                 class="h-full w-full object-cover">
                        </div>
                        <div class="p-3">
                            <p class="truncate text-sm font-semibold text-slate-800" x-text="product.name"></p>
                            <p class="mt-1 text-xs text-slate-500" x-text="'SKU: ' + product.sku"></p>
                            <p class="mt-2 text-sm font-bold text-slate-900" x-text="'Rp ' + formatMoney(product.base_price)"></p>
                        </div>
                    </button>
                </template>
            </div>
        </section>

        <aside class="surface h-fit p-4 xl:sticky xl:top-20">
            <h2 class="mb-3 text-base font-bold">Cart</h2>
            <div class="max-h-[50vh] space-y-2 overflow-auto pr-1">
                <template x-for="(item, idx) in cart" :key="idx">
                    <div class="rounded-xl border border-slate-200 p-2">
                        <div class="flex items-start justify-between gap-2">
                            <div class="min-w-0">
                                <p class="truncate text-sm font-semibold" x-text="item.name"></p>
                                <p class="text-xs text-slate-500" x-text="'Rp ' + formatMoney(item.unit_price)"></p>
                                <p class="truncate text-[11px] text-slate-400" x-show="item.variant_label" x-text="item.variant_label"></p>
                                <p class="truncate text-[11px] text-slate-400" x-show="item.addons_label" x-text="item.addons_label"></p>
                                <p class="truncate text-[11px] text-slate-400" x-show="item.note" x-text="'Note: ' + item.note"></p>
                            </div>
                            <div class="flex flex-col items-end gap-1">
                                <button @click="editCartItem(idx)" class="text-xs text-sky-600">edit</button>
                                <button @click="removeItem(idx)" class="text-xs text-rose-600">hapus</button>
                            </div>
                        </div>
                        <div class="mt-2 flex items-center gap-2">
                            <button @click="decQty(idx)" class="rounded border px-2">-</button>
                            <span class="text-sm" x-text="item.qty"></span>
                            <button @click="incQty(idx)" class="rounded border px-2">+</button>
                        </div>
                    </div>
                </template>
                <p x-show="!cart.length" class="text-sm text-slate-400">Belum ada item.</p>
            </div>

            <div class="mt-4 space-y-1 border-t pt-3 text-sm">
                <div class="flex justify-between"><span>Subtotal</span><span x-text="'Rp ' + formatMoney(subtotal)"></span></div>
                <div class="flex justify-between"><span>Tax</span><span x-text="'Rp ' + formatMoney(tax)"></span></div>
                <div class="flex justify-between"><span>Service</span><span x-text="'Rp ' + formatMoney(service)"></span></div>
                <div class="flex justify-between text-base font-bold"><span>Total</span><span x-text="'Rp ' + formatMoney(total)"></span></div>
            </div>

            <div class="mt-3 grid grid-cols-2 gap-2 text-sm">
                <select x-model="orderType" class="rounded-xl border px-2 py-2">
                    <option value="dine-in">Dine In</option>
                    <option value="takeaway">Takeaway</option>
                    <option value="delivery">Delivery</option>
                </select>
                <input x-model="tableNumber" placeholder="No meja" class="rounded-xl border px-2 py-2">
                <div class="col-span-2 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-500">
                    Register otomatis: <span class="font-semibold text-slate-700" x-text="registerLabel"></span>
                </div>
                <div class="col-span-2 space-y-2 rounded-xl border border-slate-200 bg-slate-50 p-2">
                    <div class="flex items-center justify-between">
                        <p class="text-xs font-semibold text-slate-600">Pembayaran (Split)</p>
                        <button @click="addPaymentRow" class="rounded bg-slate-900 px-2 py-1 text-xs text-white">+ Tambah</button>
                    </div>
                    <template x-for="(payment, pIdx) in paymentRows" :key="pIdx">
                        <div class="grid grid-cols-[1fr_1fr_auto] gap-2">
                            <select x-model="payment.method" class="rounded-lg border px-2 py-2 text-xs">
                                <option value="CASH">CASH</option>
                                <option value="QRIS">QRIS</option>
                                <option value="DEBIT">DEBIT</option>
                            </select>
                            <input x-model.number="payment.amount" type="number" min="0" class="rounded-lg border px-2 py-2 text-xs">
                            <button @click="removePaymentRow(pIdx)" class="rounded-lg border border-rose-300 px-2 text-xs text-rose-600">x</button>
                        </div>
                    </template>
                    <div class="flex items-center justify-between text-xs">
                        <span class="text-slate-500">Total bayar</span>
                        <span class="font-semibold" :class="paymentTotal < total ? 'text-rose-600' : 'text-emerald-600'" x-text="'Rp ' + formatMoney(paymentTotal)"></span>
                    </div>
                </div>
                <label class="col-span-2 inline-flex items-center gap-2 rounded-xl border border-slate-200 px-3 py-2 text-xs">
                    <input type="checkbox" x-model="autoPrint">
                    <span>Auto print thermal setelah sukses bayar</span>
                </label>
            </div>

            <div class="mt-3 grid grid-cols-3 gap-2 text-sm">
                <button @click="holdOrder" class="rounded-xl border border-amber-200 bg-amber-50 px-3 py-2">Hold</button>
                <button @click="clearCart" class="rounded-xl border border-slate-200 bg-white px-3 py-2">Clear</button>
                <button @click="pay" class="rounded-xl bg-slate-900 px-3 py-2 text-white">Pay</button>
            </div>

            <p class="mt-3 text-xs text-slate-500">
                Sync: <span x-text="isOnline ? 'Online' : 'Offline'" class="font-semibold"></span>
                | Pending <span x-text="pendingCount" class="font-semibold"></span>
            </p>
        </aside>
    </div>

    <div x-show="modifierModalOpen" x-transition class="fixed inset-0 z-50 flex items-center justify-center bg-slate-900/40 p-4">
        <div class="surface w-full max-w-lg p-4">
            <div class="mb-3 flex items-center justify-between">
                <h3 class="text-base font-semibold" x-text="editingCartIndex === null ? 'Tambah Item' : 'Edit Item'"></h3>
                <button @click="closeModifierModal()" class="rounded border px-2 py-1 text-xs">x</button>
            </div>
            <p class="mb-3 text-sm font-semibold" x-text="selectedProduct?.name"></p>

            <div class="space-y-3 text-sm">
                <template x-for="variant in (selectedProduct?.variants || [])" :key="variant.id">
                    <div>
                        <p class="mb-1 text-xs font-semibold text-slate-600" x-text="variant.name"></p>
                        <div class="flex flex-wrap gap-2">
                            <template x-for="option in (variant.options || [])" :key="option.id">
                                <button
                                    @click="selectedVariantOptionId = option.id"
                                    class="rounded-lg border px-2 py-1 text-xs"
                                    :class="selectedVariantOptionId === option.id ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-200 bg-white'">
                                    <span x-text="option.name"></span>
                                    <span x-show="option.price_delta !== 0" x-text="' (+' + formatMoney(option.price_delta) + ')'"></span>
                                </button>
                            </template>
                        </div>
                    </div>
                </template>

                <div x-show="(selectedProduct?.addons || []).length">
                    <p class="mb-1 text-xs font-semibold text-slate-600">Add-ons</p>
                    <div class="flex flex-wrap gap-2">
                        <template x-for="addon in (selectedProduct?.addons || [])" :key="addon.id">
                            <button
                                @click="toggleAddon(addon.id)"
                                class="rounded-lg border px-2 py-1 text-xs"
                                :class="selectedAddonIds.includes(addon.id) ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-200 bg-white'">
                                <span x-text="addon.name"></span>
                                <span x-text="' (+' + formatMoney(addon.price) + ')'"></span>
                            </button>
                        </template>
                    </div>
                </div>

                <textarea x-model="itemNote" rows="2" placeholder="Catatan item (opsional)" class="w-full rounded-lg border px-2 py-2 text-xs"></textarea>
                <div class="text-sm font-semibold">
                    Harga item: <span x-text="'Rp ' + formatMoney(modifierUnitPrice)"></span>
                </div>
            </div>

            <div class="mt-4 flex justify-end gap-2">
                <button @click="closeModifierModal()" class="rounded-lg border px-3 py-2 text-sm">Batal</button>
                <button @click="confirmModifier()" class="rounded-lg bg-slate-900 px-3 py-2 text-sm text-white">
                    <span x-text="editingCartIndex === null ? 'Tambah ke Cart' : 'Simpan Perubahan'"></span>
                </button>
            </div>
        </div>
    </div>

    <script>
        function posApp(config) {
            return {
                categories: config.categories,
                products: config.products,
                registers: config.registers,
                activeCategory: null,
                search: '',
                cart: [],
                orderType: 'dine-in',
                tableNumber: '',
                registerId: config.registers[0]?.id ?? null,
                autoPrint: localStorage.getItem('pos_auto_print') !== '0',
                modifierModalOpen: false,
                selectedProduct: null,
                selectedVariantOptionId: null,
                selectedAddonIds: [],
                itemNote: '',
                editingCartIndex: null,
                get registerLabel() {
                    const reg = this.registers.find((r) => Number(r.id) === Number(this.registerId));
                    return reg ? reg.name : '-';
                },
                paymentRows: [{ method: 'CASH', amount: 0 }],
                pendingCount: 0,
                isOnline: navigator.onLine,
                get filteredProducts() {
                    return this.products.filter((p) => {
                        const matchCategory = !this.activeCategory || p.category_id === this.activeCategory;
                        const matchSearch = !this.search || p.name.toLowerCase().includes(this.search.toLowerCase());
                        return matchCategory && matchSearch;
                    });
                },
                get subtotal() { return this.cart.reduce((acc, it) => acc + (it.unit_price * it.qty), 0); },
                get tax() { return Math.floor(this.subtotal * 0.11); },
                get service() { return Math.floor(this.subtotal * 0.05); },
                get total() { return this.subtotal + this.tax + this.service; },
                get paymentTotal() { return this.paymentRows.reduce((acc, p) => acc + Number(p.amount || 0), 0); },
                get modifierUnitPrice() {
                    if (!this.selectedProduct) return 0;
                    const base = Number(this.selectedProduct.base_price || 0);
                    const variantDelta = this.getVariantDelta(this.selectedProduct, this.selectedVariantOptionId);
                    const addonsTotal = this.getAddonsTotal(this.selectedProduct, this.selectedAddonIds);
                    return base + variantDelta + addonsTotal;
                },
                formatMoney(v) { return Number(v || 0).toLocaleString('id-ID'); },
                addPaymentRow() { this.paymentRows.push({ method: 'QRIS', amount: 0 }); },
                removePaymentRow(idx) {
                    if (this.paymentRows.length <= 1) return;
                    this.paymentRows.splice(idx, 1);
                    this.syncDefaultPayment();
                },
                syncDefaultPayment() {
                    if (this.paymentRows.length === 1) this.paymentRows[0].amount = this.total;
                },
                getVariantDelta(product, optionId) {
                    if (!optionId) return 0;
                    for (const variant of (product.variants || [])) {
                        const found = (variant.options || []).find((o) => Number(o.id) === Number(optionId));
                        if (found) return Number(found.price_delta || 0);
                    }
                    return 0;
                },
                getAddonsTotal(product, addonIds) {
                    const ids = addonIds || [];
                    return (product.addons || [])
                        .filter((a) => ids.includes(a.id))
                        .reduce((acc, a) => acc + Number(a.price || 0), 0);
                },
                resolveVariantLabel(product, optionId) {
                    if (!optionId) return '';
                    for (const variant of (product.variants || [])) {
                        const found = (variant.options || []).find((o) => Number(o.id) === Number(optionId));
                        if (found) return `${variant.name}: ${found.name}`;
                    }
                    return '';
                },
                resolveAddonsLabel(product, addonIds) {
                    if (!addonIds?.length) return '';
                    const names = (product.addons || [])
                        .filter((a) => addonIds.includes(a.id))
                        .map((a) => a.name);
                    return names.join(', ');
                },
                openModifierModal(product) {
                    this.selectedProduct = product;
                    this.selectedVariantOptionId = product.variants?.[0]?.options?.[0]?.id ?? null;
                    this.selectedAddonIds = [];
                    this.itemNote = '';
                    this.editingCartIndex = null;
                    this.modifierModalOpen = true;
                },
                closeModifierModal() {
                    this.modifierModalOpen = false;
                    this.selectedProduct = null;
                    this.selectedVariantOptionId = null;
                    this.selectedAddonIds = [];
                    this.itemNote = '';
                    this.editingCartIndex = null;
                },
                toggleAddon(addonId) {
                    if (this.selectedAddonIds.includes(addonId)) {
                        this.selectedAddonIds = this.selectedAddonIds.filter((id) => id !== addonId);
                    } else {
                        this.selectedAddonIds.push(addonId);
                    }
                },
                confirmModifier() {
                    if (!this.selectedProduct) return;
                    const unitPrice = this.modifierUnitPrice;
                    const variantLabel = this.resolveVariantLabel(this.selectedProduct, this.selectedVariantOptionId);
                    const addonsLabel = this.resolveAddonsLabel(this.selectedProduct, this.selectedAddonIds);
                    const payload = {
                        product_id: this.selectedProduct.id,
                        name: this.selectedProduct.name,
                        qty: 1,
                        unit_price: unitPrice,
                        variant_option_id: this.selectedVariantOptionId,
                        addon_ids: [...this.selectedAddonIds],
                        note: this.itemNote,
                        variant_label: variantLabel,
                        addons_label: addonsLabel,
                    };

                    if (this.editingCartIndex !== null) {
                        const existingQty = this.cart[this.editingCartIndex].qty || 1;
                        this.cart[this.editingCartIndex] = { ...payload, qty: existingQty };
                    } else {
                        this.cart.push(payload);
                    }
                    this.syncDefaultPayment();
                    this.closeModifierModal();
                },
                editCartItem(idx) {
                    const item = this.cart[idx];
                    const product = this.products.find((p) => Number(p.id) === Number(item.product_id));
                    if (!product) return;
                    this.selectedProduct = product;
                    this.selectedVariantOptionId = item.variant_option_id;
                    this.selectedAddonIds = [...(item.addon_ids || [])];
                    this.itemNote = item.note || '';
                    this.editingCartIndex = idx;
                    this.modifierModalOpen = true;
                },
                removeItem(idx) { this.cart.splice(idx, 1); this.syncDefaultPayment(); },
                incQty(idx) { this.cart[idx].qty += 1; this.syncDefaultPayment(); },
                decQty(idx) { if (this.cart[idx].qty > 1) this.cart[idx].qty -= 1; this.syncDefaultPayment(); },
                clearCart() { this.cart = []; this.syncDefaultPayment(); },
                holdOrder() {
                    localStorage.setItem('pos_hold_order', JSON.stringify(this.cart));
                    alert('Order di-hold.');
                },
                buildPayload() {
                    return {
                        client_order_id: crypto.randomUUID(),
                        register_id: Number(this.registerId),
                        order_type: this.orderType,
                        table_number: this.orderType === 'dine-in' ? this.tableNumber : null,
                        discount: 0,
                        items: this.cart.map((it) => ({
                            product_id: it.product_id,
                            qty: it.qty,
                            note: it.note,
                            variant_option_id: it.variant_option_id,
                            addon_ids: it.addon_ids,
                        })),
                        payments: this.paymentRows
                            .map((p) => ({ method: p.method, amount: Number(p.amount || 0), reference: null }))
                            .filter((p) => p.amount > 0),
                    };
                },
                async pay() {
                    if (!this.cart.length || !this.registerId) return;
                    if (this.paymentTotal < this.total) {
                        alert('Total pembayaran kurang dari grand total.');
                        return;
                    }
                    const payload = this.buildPayload();
                    if (!payload.payments.length) {
                        alert('Isi minimal 1 pembayaran.');
                        return;
                    }
                    if (!this.isOnline) {
                        await window.offlineQueue.enqueue(payload);
                        this.pendingCount = await window.offlineQueue.count();
                        this.clearCart();
                        alert('Offline: order masuk antrian sync.');
                        return;
                    }
                    const response = await fetch(config.orderStoreUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'Accept': 'application/json',
                            'X-CSRF-TOKEN': config.csrf,
                        },
                        body: JSON.stringify(payload),
                    });
                    if (response.ok) {
                        const result = await response.json();
                        if (this.autoPrint && result?.order_id) {
                            window.open(`/orders/${result.order_id}/print`, '_blank');
                        }
                        this.clearCart();
                        if (result?.order_id) {
                            window.location.href = `/orders/${result.order_id}`;
                        } else {
                            window.location.href = '/orders';
                        }
                        return;
                    }
                    await window.offlineQueue.enqueue(payload);
                    this.pendingCount = await window.offlineQueue.count();
                },
                async syncPending() {
                    if (!this.isOnline) return;
                    const pending = await window.offlineQueue.all();
                    if (!pending.length) return;
                    const token = localStorage.getItem('device_token');
                    if (!token) return;
                    const response = await fetch(config.syncUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'Authorization': `Bearer ${token}`,
                            'Accept': 'application/json',
                        },
                        body: JSON.stringify({ orders: pending.map((p) => p.payload) }),
                    });
                    if (response.ok) {
                        await window.offlineQueue.clear();
                        this.pendingCount = 0;
                    }
                },
                async init() {
                    this.pendingCount = await window.offlineQueue.count();
                    this.activeCategory = this.categories[0]?.id ?? null;
                    this.registerId = config.defaultRegisterId ?? this.registerId;
                    this.paymentRows = [{ method: 'CASH', amount: this.total }];
                    window.addEventListener('online', async () => { this.isOnline = true; await this.syncPending(); });
                    window.addEventListener('offline', () => this.isOnline = false);
                    document.addEventListener('keydown', (e) => {
                        if (e.key === '/') { e.preventDefault(); this.$refs.searchBox?.focus(); }
                        if (e.key === 'Escape') { this.closeModifierModal(); this.clearCart(); }
                    });
                    this.$watch('autoPrint', (v) => localStorage.setItem('pos_auto_print', v ? '1' : '0'));
                },
            };
        }
    </script>
 <?php echo $__env->renderComponent(); ?>
<?php endif; ?>
<?php if (isset($__attributesOriginal5863877a5171c196453bfa0bd807e410)): ?>
<?php $attributes = $__attributesOriginal5863877a5171c196453bfa0bd807e410; ?>
<?php unset($__attributesOriginal5863877a5171c196453bfa0bd807e410); ?>
<?php endif; ?>
<?php if (isset($__componentOriginal5863877a5171c196453bfa0bd807e410)): ?>
<?php $component = $__componentOriginal5863877a5171c196453bfa0bd807e410; ?>
<?php unset($__componentOriginal5863877a5171c196453bfa0bd807e410); ?>
<?php endif; ?>
<?php /**PATH C:\Users\IPI ACD\Documents\WORKSPACE\kasir\resources\views/pos/index.blade.php ENDPATH**/ ?>