@*
    EN: Café POS Desktop — Unified single-page with tabs: Sale, History, Dashboard.
        All data fetched from API — no hardcoded demo data.
    VI: POS Café Desktop — Trang đơn với tabs: Bán hàng, Lịch sử, Dashboard.
        Toàn bộ dữ liệu lấy từ API — không có dữ liệu demo cứng.
*@
@page "/pos/{ShopId:guid}/cafe"
@layout PosLayout
@inherits PosBase
@using WebClientTpos.Client.Services
@inject PosDataService DataService
@inject IJSRuntime JS
@inject ReceiptPrintService ReceiptPrint

@* ═══════════════ MAIN CONTENT AREA + VERTICAL NAV ═══════════════ *@
<div style="display:flex;flex:1;overflow:hidden;">
<div class="pos-content-area" style="flex:1;display:flex;overflow:hidden;">
    @switch (_activeTab)
    {
        case PosTab.Sale:
            @* ═══ PRODUCT PANEL (LEFT) ═══ *@
            <div class="pos-product-panel @(_paymentStep != PayStep.None ? "pos-product-panel--dimmed" : "")">
                @if (_isLoading)
                {
                    <div style="display:flex;align-items:center;justify-content:center;height:100%;color:var(--pos-text-tertiary);">
                        Đang tải...
                    </div>
                }
                else if (_loadError)
                {
                    <div style="display:flex;align-items:center;justify-content:center;height:100%;color:var(--pos-text-tertiary);">
                        Không thể tải dữ liệu
                    </div>
                }
                else
                {
                    <div class="pos-category-tabs">
                        @foreach (var cat in _categories)
                        {
                            <button class="pos-category-tab @(cat == _selectedCategory ? "pos-category-tab--active" : "")"
                                    @onclick="() => _selectedCategory = cat">
                                @cat
                            </button>
                        }
                    </div>

                    <div class="pos-product-grid">
                        @foreach (var product in FilteredProducts)
                        {
                            <div class="pos-product-card" @onclick="() => AddToCart(product)">
                                <div class="pos-product-card__image" style="display:flex;align-items:center;justify-content:center;">
                                    <i data-lucide="coffee" style="width:32px;height:32px;color:var(--pos-text-tertiary);"></i>
                                </div>
                                <span class="pos-product-card__name">@product.Name</span>
                                <span class="pos-product-card__price">@FormatPrice(product.Price)</span>
                            </div>
                        }
                    </div>
                }
            </div>

            @* ═══ CART / PAYMENT PANEL (RIGHT) ═══ *@
            <div class="pos-cart-panel">
                @if (_paymentStep == PayStep.None)
                {
                    @* ─── NORMAL CART MODE ─── *@
                    <div class="pos-cart-header">
                        <span class="pos-cart-header__title">Đơn hàng</span>
                        <span style="font-size:12px;color:var(--pos-text-tertiary);">@_cartItems.Count món</span>
                    </div>
                    <div class="pos-cart-items">
                        @foreach (var item in _cartItems)
                        {
                            <div class="pos-cart-item">
                                <div class="pos-cart-item__info">
                                    <span class="pos-cart-item__name">@item.Name</span>
                                    <span class="pos-cart-item__price">@FormatPrice(item.Price)</span>
                                </div>
                                <div class="pos-cart-item__qty">
                                    <button @onclick="() => ChangeQty(item, -1)">−</button>
                                    <span style="font-size:14px;font-weight:600;min-width:20px;text-align:center;">@item.Qty</span>
                                    <button @onclick="() => ChangeQty(item, 1)">+</button>
                                </div>
                            </div>
                        }
                    </div>
                    <div class="pos-cart-footer">
                        <!-- Voucher input -->
                        <div style="display:flex;gap:6px;margin-bottom:8px;">
                            <input type="text" @bind="_voucherCode" placeholder="Nhập mã voucher..." style="flex:1;padding:8px 10px;border:1px solid var(--pos-border);border-radius:8px;font-size:12px;background:var(--pos-bg-elevated);color:var(--pos-text-primary);" />
                            <button @onclick="ValidateVoucher" style="padding:6px 12px;border-radius:8px;border:none;background:rgba(139,92,246,0.1);color:#8B5CF6;font-size:11px;font-weight:600;cursor:pointer;">Áp dụng</button>
                            @if (_appliedVoucher != null)
                            {
                                <button @onclick="ClearVoucher" style="padding:6px 8px;border-radius:8px;border:none;background:rgba(239,68,68,0.1);color:#EF4444;font-size:11px;cursor:pointer;" title="Xóa voucher"><i data-lucide="x" style="width:12px;height:12px;"></i></button>
                            }
                        </div>
                        @if (_voucherMessage != null)
                        {
                            <div style="font-size:11px;margin-bottom:6px;color:@(_appliedVoucher != null ? "#16A34A" : "#EF4444");">@_voucherMessage</div>
                        }
                        @if (_appliedVoucher != null)
                        {
                            <div style="display:flex;justify-content:space-between;margin-bottom:6px;font-size:12px;">
                                <span style="color:var(--pos-text-tertiary);">Giảm giá (@_appliedVoucher.CampaignName)</span>
                                <span style="color:#16A34A;font-weight:600;">-@FormatPrice(_discountAmount)</span>
                            </div>
                        }
                        <div class="pos-cart-total">
                            <span class="pos-cart-total__label">Tổng cộng</span>
                            <span class="pos-cart-total__value">@FormatPrice(FinalTotal)</span>
                        </div>
                        @if (!string.IsNullOrEmpty(_orderError))
                        {
                            <div style="font-size:11px;margin-bottom:6px;color:#EF4444;">@_orderError</div>
                        }
                        <button class="pos-btn-checkout" @onclick="StartPayment" disabled="@(!_cartItems.Any() || _orderCreating)">
                            @if (_orderCreating)
                            {
                                <span>Đang tạo đơn...</span>
                            }
                            else
                            {
                                <i data-lucide="credit-card" style="width:18px;height:18px;"></i>
                                <span>Thanh toán</span>
                            }
                        </button>
                    </div>
                }
                else if (_paymentStep == PayStep.MethodSelect)
                {
                    @* ─── PAYMENT: METHOD SELECT ─── *@
                    <div class="pos-payment-panel">
                        <div class="pos-payment-header">
                            <button class="pos-payment-header__back" @onclick="CancelPayment">
                                <i data-lucide="arrow-left" style="width:16px;height:16px;"></i>
                            </button>
                            <span style="font-weight:600;">Thanh toán</span>
                            <span style="margin-left:auto;font-size:18px;font-weight:700;color:var(--pos-orange-primary);">@FormatPrice(FinalTotal)</span>
                        </div>
                        <div class="pos-payment-methods">
                            <button class="pos-payment-method-btn" @onclick='() => SelectPaymentMethod("cash")'>
                                <span class="pos-payment-method-btn__icon"><i data-lucide="wallet" style="width:28px;height:28px;"></i></span>
                                <span class="pos-payment-method-btn__label">Tiền mặt</span>
                            </button>
                            @if (_payCardEnabled)
                            {
                            <button class="pos-payment-method-btn" @onclick='() => SelectPaymentMethod("card")'>
                                <span class="pos-payment-method-btn__icon"><i data-lucide="credit-card" style="width:28px;height:28px;"></i></span>
                                <span class="pos-payment-method-btn__label">Thẻ</span>
                            </button>
                            }
                            @if (_payQrEnabled)
                            {
                            <button class="pos-payment-method-btn" @onclick='() => SelectPaymentMethod("qr")'>
                                <span class="pos-payment-method-btn__icon"><i data-lucide="smartphone" style="width:28px;height:28px;"></i></span>
                                <span class="pos-payment-method-btn__label">Mã QR</span>
                            </button>
                            }
                            @if (_payTransferEnabled)
                            {
                            <button class="pos-payment-method-btn" @onclick='() => SelectPaymentMethod("transfer")'>
                                <span class="pos-payment-method-btn__icon"><i data-lucide="building-2" style="width:28px;height:28px;"></i></span>
                                <span class="pos-payment-method-btn__label">Chuyển khoản</span>
                            </button>
                            }
                        </div>
                    </div>
                }
                else if (_paymentStep == PayStep.AmountInput)
                {
                    @* ─── PAYMENT: CASH AMOUNT INPUT ─── *@
                    <div class="pos-payment-panel">
                        <div class="pos-payment-header">
                            <button class="pos-payment-header__back" @onclick="() => _paymentStep = PayStep.MethodSelect">
                                <i data-lucide="arrow-left" style="width:16px;height:16px;"></i>
                            </button>
                            <span style="font-weight:600;display:flex;align-items:center;gap:6px;"><i data-lucide="wallet" style="width:16px;height:16px;"></i> Tiền mặt</span>
                            <span style="margin-left:auto;font-size:16px;font-weight:700;color:var(--pos-orange-primary);">@FormatPrice(FinalTotal)</span>
                        </div>
                        <div class="pos-payment-amount-section">
                            <div style="font-size:13px;font-weight:600;color:var(--pos-text-secondary);margin-bottom:10px;">Số tiền nhanh</div>
                            <div class="pos-payment-quick-amounts">
                                @foreach (var qa in GetQuickAmounts())
                                {
                                    <button class="pos-payment-quick-btn @(_receivedAmount == qa.Value ? "pos-payment-quick-btn--selected" : "")"
                                            @onclick="() => _receivedAmount = qa.Value">
                                        @qa.Label
                                    </button>
                                }
                            </div>
                            <div style="font-size:13px;font-weight:600;color:var(--pos-text-secondary);margin-bottom:8px;">Nhập số tiền</div>
                            <input type="number" class="pos-payment-input" placeholder="Nhập số tiền..."
                                   @bind="_customAmountInput" @bind:event="oninput" />
                            @if (!string.IsNullOrEmpty(_customAmountInput))
                            {
                                <button style="width:100%;padding:10px;border-radius:var(--pos-radius);border:none;background:var(--pos-bg-interactive);color:var(--pos-text-primary);cursor:pointer;font-size:13px;font-weight:600;margin-bottom:16px;"
                                        @onclick="ApplyCustomAmount">Áp dụng</button>
                            }
                            <div class="pos-payment-change">
                                <div class="pos-payment-change__row">
                                    <span style="color:var(--pos-text-tertiary);">Khách đưa</span>
                                    <span style="font-weight:600;">@FormatPrice(_receivedAmount)</span>
                                </div>
                                <div class="pos-payment-change__row" style="padding-top:8px;border-top:1px dashed var(--pos-border-subtle);">
                                    <span style="color:var(--pos-text-tertiary);">Tiền thối</span>
                                    <span style="font-size:18px;font-weight:700;color:@(ChangeAmount >= 0 ? "var(--pos-success)" : "var(--pos-danger)");">
                                        @FormatPrice(ChangeAmount)
                                    </span>
                                </div>
                            </div>
                        </div>
                        <div style="padding:16px;border-top:1px solid var(--pos-border-subtle);">
                            @if (!string.IsNullOrEmpty(_paymentError))
                            {
                                <div style="font-size:12px;color:var(--pos-danger);margin-bottom:8px;text-align:center;">@_paymentError</div>
                            }
                            <button class="pos-btn-checkout" @onclick="ConfirmPayment" disabled="@(_receivedAmount < FinalTotal || _paymentProcessing)">
                                @if (_paymentProcessing)
                                {
                                    <span>Đang xử lý...</span>
                                }
                                else
                                {
                                    <span>Xác nhận thanh toán</span>
                                }
                            </button>
                        </div>
                    </div>
                }
                else if (_paymentStep == PayStep.Processing)
                {
                    @* ─── PAYMENT: QR/CARD/TRANSFER — Confirm ─── *@
                    <div class="pos-payment-panel">
                        <div class="pos-payment-header">
                            <button class="pos-payment-header__back" @onclick="() => _paymentStep = PayStep.MethodSelect">
                                <i data-lucide="arrow-left" style="width:16px;height:16px;"></i>
                            </button>
                            <span style="font-weight:600;">@GetMethodLabel()</span>
                        </div>
                        <div style="flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px;padding:24px;">
                            <div style="font-size:32px;font-weight:700;color:var(--pos-orange-primary);">@FormatPrice(FinalTotal)</div>
                            @if (_selectedMethod == "qr")
                            {
                                <div style="width:180px;height:180px;background:white;border-radius:12px;display:flex;align-items:center;justify-content:center;">
                                    <div style="color:#333;font-size:14px;font-weight:600;text-align:center;">QR Code<br/>VietQR</div>
                                </div>
                                <div style="font-size:12px;color:var(--pos-text-tertiary);">Quét mã bằng app Ngân hàng / MoMo / ZaloPay</div>
                            }
                            else if (_selectedMethod == "card")
                            {
                                <div><i data-lucide="credit-card" style="width:48px;height:48px;color:var(--pos-text-secondary);"></i></div>
                                <div style="font-size:14px;color:var(--pos-text-secondary);">Chạm, quẹt hoặc cắm thẻ</div>
                            }
                            else
                            {
                                <div><i data-lucide="building-2" style="width:48px;height:48px;color:var(--pos-text-secondary);"></i></div>
                                <div style="font-size:14px;color:var(--pos-text-secondary);">Xác nhận đã nhận chuyển khoản</div>
                            }
                        </div>
                        <div style="padding:16px;border-top:1px solid var(--pos-border-subtle);">
                            @if (!string.IsNullOrEmpty(_paymentError))
                            {
                                <div style="font-size:12px;color:var(--pos-danger);margin-bottom:8px;text-align:center;">@_paymentError</div>
                            }
                            <button class="pos-btn-checkout" @onclick="ConfirmPayment" disabled="@_paymentProcessing">
                                @if (_paymentProcessing)
                                {
                                    <span>Đang xử lý...</span>
                                }
                                else
                                {
                                    <span>Xác nhận đã thanh toán</span>
                                }
                            </button>
                        </div>
                    </div>
                }
                else if (_paymentStep == PayStep.Success)
                {
                    @* ─── PAYMENT: SUCCESS ─── *@
                    <div class="pos-payment-success">
                        <div class="pos-payment-success__circle">
                            <div class="pos-payment-success__inner">
                                <i data-lucide="check" style="width:28px;height:28px;color:#fff;stroke-width:3;"></i>
                            </div>
                        </div>
                        <div style="font-size:18px;font-weight:700;color:var(--pos-success);">Thanh toán thành công!</div>
                        <div style="font-size:14px;color:var(--pos-text-tertiary);">@FormatPrice(_lastOrderTotal)</div>
                        <div style="font-size:12px;color:var(--pos-text-tertiary);">Mã: @_lastTransactionId</div>
                        <div style="display:flex;gap:10px;margin-top:8px;">
                            <button style="padding:10px 20px;border-radius:var(--pos-radius);border:1px solid var(--pos-border-default);background:transparent;color:var(--pos-text-primary);cursor:pointer;font-size:13px;font-weight:600;"
                                    @onclick="PrintReceipt">
                                <i data-lucide="printer" style="width:14px;height:14px;vertical-align:middle;margin-right:4px;"></i>In hóa đơn
                            </button>
                            <button style="padding:10px 20px;border-radius:var(--pos-radius);border:none;background:var(--pos-orange-primary);color:#fff;cursor:pointer;font-size:13px;font-weight:600;"
                                    @onclick="ResetAfterPayment">
                                <i data-lucide="plus" style="width:14px;height:14px;vertical-align:middle;margin-right:4px;"></i>Đơn mới
                            </button>
                        </div>
                    </div>
                }
            </div>
            break;

        case PosTab.History:
            @* ═══ ORDER HISTORY TAB ═══ *@
            <div class="pos-history" style="width:100%;">
                @if (_selectedOrderDetail != null)
                {
                    @* ─── ORDER DETAIL VIEW (API order) ─── *@
                    var od = _selectedOrderDetail.Order;
                    var items = _selectedOrderDetail.Items ?? new();
                    <div style="display:flex;flex-direction:column;height:100%;">
                        <div class="pos-payment-header">
                            <button class="pos-payment-header__back" @onclick="CloseOrderDetail">
                                <i data-lucide="arrow-left" style="width:16px;height:16px;"></i>
                            </button>
                            <span style="font-weight:600;">Chi tiết đơn hàng</span>
                        </div>
                        <div style="flex:1;overflow-y:auto;padding:16px;">
                            <div style="display:flex;flex-direction:column;gap:8px;margin-bottom:16px;">
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Mã đơn</span>
                                    <span style="font-weight:600;">@(od?.Id.ToString()[..8].ToUpper())</span>
                                </div>
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Ngày</span>
                                    <span>@(od?.CreatedAt.ToString("dd/MM/yyyy — HH:mm:ss"))</span>
                                </div>
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Trạng thái</span>
                                    <span style="color:var(--pos-success);font-weight:600;">@MapApiStatus(od?.Status)</span>
                                </div>
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Thanh toán</span>
                                    <span>@MapPaymentMethodLabel(od?.PaymentMethod)</span>
                                </div>
                            </div>
                            <div style="border-top:1px dashed var(--pos-border-subtle);margin-bottom:12px;"></div>
                            <table style="width:100%;border-collapse:collapse;font-size:13px;">
                                <thead>
                                    <tr style="color:var(--pos-text-tertiary);font-size:11px;text-transform:uppercase;">
                                        <th style="text-align:left;padding:6px 0;">Sản phẩm</th>
                                        <th style="text-align:center;padding:6px 4px;width:40px;">SL</th>
                                        <th style="text-align:right;padding:6px 0;width:80px;">Đ.Giá</th>
                                        <th style="text-align:right;padding:6px 0;width:90px;">T.Tiền</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    @foreach (var item in items)
                                    {
                                        <tr style="border-top:1px solid var(--pos-border-subtle);">
                                            <td style="padding:8px 0;">@(item.ProductName ?? "—")</td>
                                            <td style="text-align:center;padding:8px 4px;">@item.Quantity</td>
                                            <td style="text-align:right;padding:8px 0;">@FormatPrice(item.UnitPrice)</td>
                                            <td style="text-align:right;padding:8px 0;font-weight:600;">@FormatPrice(item.Subtotal)</td>
                                        </tr>
                                    }
                                </tbody>
                            </table>
                            <div style="border-top:1px dashed var(--pos-border-subtle);margin:12px 0;"></div>
                            <div style="display:flex;justify-content:space-between;font-size:16px;font-weight:700;">
                                <span>TỔNG CỘNG</span>
                                <span style="color:var(--pos-orange-primary);">@FormatPrice(od?.TotalAmount ?? 0)</span>
                            </div>
                        </div>
                        <div style="padding:16px;border-top:1px solid var(--pos-border-subtle);display:flex;gap:10px;">
                            <button style="flex:1;padding:12px;border-radius:var(--pos-radius);border:1px solid var(--pos-border-default);background:transparent;color:var(--pos-text-primary);cursor:pointer;font-size:13px;font-weight:600;"
                                    @onclick="PrintOrderDetail">
                                <i data-lucide="printer" style="width:14px;height:14px;vertical-align:middle;margin-right:4px;"></i>In hóa đơn
                            </button>
                        </div>
                    </div>
                }
                else if (_selectedOrder != null)
                {
                    @* ─── SESSION ORDER DETAIL VIEW ─── *@
                    var so = _selectedOrder;
                    <div style="display:flex;flex-direction:column;height:100%;">
                        <div class="pos-payment-header">
                            <button class="pos-payment-header__back" @onclick="CloseOrderDetail">
                                <i data-lucide="arrow-left" style="width:16px;height:16px;"></i>
                            </button>
                            <span style="font-weight:600;">Chi tiết đơn hàng</span>
                        </div>
                        <div style="flex:1;overflow-y:auto;padding:16px;">
                            <div style="display:flex;flex-direction:column;gap:8px;margin-bottom:16px;">
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Mã đơn</span>
                                    <span style="font-weight:600;">@so.Id</span>
                                </div>
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Thời gian</span>
                                    <span>@so.Time</span>
                                </div>
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Trạng thái</span>
                                    <span style="color:var(--pos-success);font-weight:600;">@so.Status</span>
                                </div>
                                <div style="display:flex;justify-content:space-between;font-size:13px;">
                                    <span style="color:var(--pos-text-tertiary);">Thanh toán</span>
                                    <span>@so.Method</span>
                                </div>
                            </div>
                            <div style="border-top:1px dashed var(--pos-border-subtle);margin-bottom:12px;"></div>
                            <div style="font-size:13px;color:var(--pos-text-secondary);margin-bottom:12px;">@so.Items</div>
                            <div style="border-top:1px dashed var(--pos-border-subtle);margin:12px 0;"></div>
                            <div style="display:flex;justify-content:space-between;font-size:16px;font-weight:700;">
                                <span>TỔNG CỘNG</span>
                                <span style="color:var(--pos-orange-primary);">@FormatPrice(so.Total)</span>
                            </div>
                        </div>
                        <div style="padding:16px;border-top:1px solid var(--pos-border-subtle);display:flex;gap:10px;">
                            <button style="flex:1;padding:12px;border-radius:var(--pos-radius);border:1px solid var(--pos-border-default);background:transparent;color:var(--pos-text-primary);cursor:pointer;font-size:13px;font-weight:600;"
                                    @onclick="PrintSessionOrderDetail">
                                <i data-lucide="printer" style="width:14px;height:14px;vertical-align:middle;margin-right:4px;"></i>In hóa đơn
                            </button>
                        </div>
                    </div>
                }
                else
                {
                @* ─── ORDER LIST ─── *@
                <div class="pos-history__toolbar">
                    <input class="pos-history__search" placeholder="Tìm mã đơn, tên khách..."
                           @bind="_historySearch" @bind:event="oninput" />
                    @foreach (var f in _historyFilters)
                    {
                        <button class="pos-history__filter-btn @(_historyFilter == f.Key ? "pos-history__filter-btn--active" : "")"
                                @onclick="() => ChangeHistoryFilter(f.Key)">
                            @f.Label
                        </button>
                    }
                </div>
                <div class="pos-history__list">
                    @if (_historyLoading || _orderDetailLoading)
                    {
                        <div style="display:flex;align-items:center;justify-content:center;padding:60px 0;color:var(--pos-text-tertiary);">
                            <div style="font-size:14px;">Đang tải...</div>
                        </div>
                    }
                    else
                    {
                        @* EN: Session orders (created during this POS session) shown first *@
                        @foreach (var order in FilteredSessionOrders)
                        {
                            <div class="pos-history__card" @onclick="() => _selectedOrder = order">
                                <div class="pos-history__card-header">
                                    <span class="pos-history__order-id">@order.Id</span>
                                    <span class="pos-history__status pos-history__status--completed">@order.Status</span>
                                </div>
                                <div class="pos-history__card-body">
                                    <span class="pos-history__items-preview">@order.Items</span>
                                    <div class="pos-history__card-meta">
                                        <div class="pos-history__total">@FormatPrice(order.Total)</div>
                                        <div class="pos-history__time">@order.Time</div>
                                        <div class="pos-history__method">@order.Method</div>
                                    </div>
                                </div>
                            </div>
                        }
                        @* EN: API orders from DB *@
                        @foreach (var order in FilteredApiOrders)
                        {
                            <div class="pos-history__card" @onclick="() => ViewOrderDetail(order.Id)">
                                <div class="pos-history__card-header">
                                    <span class="pos-history__order-id">@order.Id.ToString()[..8].ToUpper()</span>
                                    <span class="pos-history__status @(order.Status == "Completed" || order.Status == "Delivered" ? "pos-history__status--completed" : "pos-history__status--refunded")">
                                        @MapApiStatus(order.Status)
                                    </span>
                                </div>
                                <div class="pos-history__card-body">
                                    <span class="pos-history__items-preview">@order.ItemCount món</span>
                                    <div class="pos-history__card-meta">
                                        <div class="pos-history__total">@FormatPrice(order.TotalAmount)</div>
                                        <div class="pos-history__time">@order.CreatedAt.ToString("HH:mm dd/MM")</div>
                                        <div class="pos-history__method">@MapPaymentMethodLabel(order.PaymentMethod)</div>
                                    </div>
                                </div>
                            </div>
                        }
                        @if (!FilteredSessionOrders.Any() && !FilteredApiOrders.Any())
                        {
                            <div style="display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 0;color:var(--pos-text-tertiary);">
                                <i data-lucide="search" style="width:40px;height:40px;margin-bottom:12px;opacity:0.4;"></i>
                                <div style="font-size:14px;">Chưa có đơn hàng nào</div>
                            </div>
                        }
                    }
                </div>
                }
            </div>
            break;

        case PosTab.Dashboard:
            @* ═══ DASHBOARD TAB ═══ *@
            <div class="pos-dashboard" style="width:100%;">
                <div class="pos-dashboard__header" style="display:flex;align-items:center;justify-content:space-between;">
                    <div>
                        <div class="pos-dashboard__title">Dashboard bán hàng</div>
                        <div class="pos-dashboard__subtitle">@(_dashPeriod switch { "7d" => "7 ngày gần nhất", "30d" => "30 ngày gần nhất", _ => DateTime.Now.ToString("dd/MM/yyyy") + " — Hôm nay" })</div>
                    </div>
                    <div style="display:flex;gap:4px;background:var(--pos-bg-secondary, rgba(255,255,255,0.05));border-radius:8px;padding:3px;">
                        @foreach (var (label, val) in new[] { ("Hôm nay", "today"), ("7 ngày", "7d"), ("30 ngày", "30d") })
                        {
                            <button @onclick="@(() => SwitchDashPeriod(val))"
                                style="padding:6px 12px;border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;border:none;
                                    background:@(_dashPeriod == val ? "var(--pos-orange-primary, #FF5C00)" : "transparent");
                                    color:@(_dashPeriod == val ? "#FFF" : "var(--pos-text-tertiary, #888)");">
                                @label
                            </button>
                        }
                    </div>
                </div>

                @if (_dashLoading)
                {
                    <div style="display:flex;align-items:center;justify-content:center;padding:60px 0;color:var(--pos-text-tertiary);">
                        <div style="font-size:14px;">Đang tải thống kê...</div>
                    </div>
                }
                else
                {
                    <div class="pos-dashboard__stats">
                        <div class="pos-dashboard__stat-card">
                            <div class="pos-dashboard__stat-label">Doanh thu</div>
                            <div class="pos-dashboard__stat-value" style="color:var(--pos-orange-primary);">@FormatPrice(_dashboard.Revenue)</div>
                            <div class="pos-dashboard__stat-sub">TB @FormatPrice(_dashboard.AvgOrderValue)/đơn</div>
                        </div>
                        <div class="pos-dashboard__stat-card">
                            <div class="pos-dashboard__stat-label">Đơn hàng</div>
                            <div class="pos-dashboard__stat-value" style="color:var(--pos-success);">@_dashboard.OrderCount</div>
                            <div class="pos-dashboard__stat-sub">Hôm nay</div>
                        </div>
                        <div class="pos-dashboard__stat-card">
                            <div class="pos-dashboard__stat-label">Món bán ra</div>
                            <div class="pos-dashboard__stat-value" style="color:var(--pos-warning);">@_dashboard.ItemsSold</div>
                            <div class="pos-dashboard__stat-sub">@(_dashboard.OrderCount > 0 ? $"{(double)_dashboard.ItemsSold / _dashboard.OrderCount:F1} món/đơn" : "—")</div>
                        </div>
                    </div>

                    <div class="pos-dashboard__grid">
                        @* Popular items *@
                        <div class="pos-dashboard__section">
                            <div class="pos-dashboard__section-title">Món bán chạy</div>
                            @if (_dashboard.PopularItems.Any())
                            {
                                @foreach (var item in _dashboard.PopularItems)
                                {
                                    <div class="pos-dashboard__popular-item">
                                        <div>
                                            <div style="font-size:13px;font-weight:500;">@item.Name</div>
                                            <div style="font-size:11px;color:var(--pos-text-tertiary);">@item.Qty đã bán</div>
                                        </div>
                                        <span style="font-size:13px;font-weight:600;color:var(--pos-orange-primary);">@FormatPrice(item.Revenue)</span>
                                    </div>
                                }
                            }
                            else
                            {
                                <div style="font-size:13px;color:var(--pos-text-tertiary);padding:16px 0;">Chưa có dữ liệu</div>
                            }
                        </div>

                        @* Payment breakdown + Hourly chart *@
                        <div class="pos-dashboard__section">
                            <div class="pos-dashboard__section-title">Hình thức thanh toán</div>
                            @if (_dashboard.PaymentBreakdown.Any())
                            {
                                @foreach (var p in _dashboard.PaymentBreakdown)
                                {
                                    <div class="pos-dashboard__payment-row">
                                        <div class="pos-dashboard__payment-header">
                                            <span>@MapPaymentMethodLabel(p.Method)</span>
                                            <span style="font-weight:600;">@FormatPrice(p.Amount)</span>
                                        </div>
                                        <div class="pos-dashboard__payment-bar">
                                            <div class="pos-dashboard__payment-fill" style="width:@(p.Pct)%;background:var(--pos-orange-primary);"></div>
                                        </div>
                                    </div>
                                }
                            }
                            else
                            {
                                <div style="font-size:13px;color:var(--pos-text-tertiary);padding:16px 0;">Chưa có dữ liệu</div>
                            }

                            <div class="pos-dashboard__section-title" style="margin-top:20px;">Doanh thu theo giờ</div>
                            @if (_dashboard.HourlyRevenue.Any())
                            {
                                <div class="pos-dashboard__hourly-chart">
                                    @foreach (var h in _dashboard.HourlyRevenue)
                                    {
                                        <div class="pos-dashboard__hourly-bar">
                                            <div class="pos-dashboard__hourly-fill" style="height:@(h.Pct)%;opacity:@(h.Pct > 0 ? 1 : 0.3);"></div>
                                            <span class="pos-dashboard__hourly-label">@h.HourLabel</span>
                                        </div>
                                    }
                                </div>
                            }
                            else
                            {
                                <div style="font-size:13px;color:var(--pos-text-tertiary);padding:16px 0;">Chưa có dữ liệu</div>
                            }
                        </div>
                    </div>
                }
            </div>
            break;

        case PosTab.Settings:
            @* ═══ PAYMENT SETTINGS TAB ═══ *@
            <div style="width:100%;max-width:560px;margin:0 auto;padding:16px;">
                <div style="font-size:18px;font-weight:700;color:var(--pos-text-primary);margin-bottom:16px;">Cài đặt thanh toán</div>

                @* ─── Card ─── *@
                <div style="background:var(--pos-bg-card);border:1px solid var(--pos-border-subtle);border-radius:var(--pos-radius);margin-bottom:12px;overflow:hidden;">
                    <div style="display:flex;align-items:center;justify-content:space-between;padding:14px 16px;cursor:pointer;" @onclick="() => _settingsCardOpen = !_settingsCardOpen">
                        <div style="display:flex;align-items:center;gap:10px;">
                            <i data-lucide="credit-card" style="width:20px;height:20px;color:var(--pos-orange-primary);"></i>
                            <span style="font-weight:600;font-size:14px;">Thẻ (Card)</span>
                        </div>
                        <div style="display:flex;align-items:center;gap:12px;">
                            <button class="pos-toggle @(_payCardEnabled ? "pos-toggle--on" : "")" @onclick="ToggleCard" @onclick:stopPropagation="true">
                                <span class="pos-toggle__knob"></span>
                            </button>
                            <i data-lucide="@(_settingsCardOpen ? "chevron-up" : "chevron-down")" style="width:16px;height:16px;color:var(--pos-text-tertiary);"></i>
                        </div>
                    </div>
                    @if (_settingsCardOpen && _payCardEnabled)
                    {
                        <div style="padding:0 16px 14px;border-top:1px solid var(--pos-border-subtle);">
                            <label style="font-size:12px;color:var(--pos-text-tertiary);display:block;margin:12px 0 4px;">Terminal ID</label>
                            <input type="text" class="pos-settings-input" placeholder="Nhập mã terminal..." @bind="_cardTerminalId" />
                        </div>
                    }
                </div>

                @* ─── QR ─── *@
                <div style="background:var(--pos-bg-card);border:1px solid var(--pos-border-subtle);border-radius:var(--pos-radius);margin-bottom:12px;overflow:hidden;">
                    <div style="display:flex;align-items:center;justify-content:space-between;padding:14px 16px;cursor:pointer;" @onclick="() => _settingsQrOpen = !_settingsQrOpen">
                        <div style="display:flex;align-items:center;gap:10px;">
                            <i data-lucide="smartphone" style="width:20px;height:20px;color:var(--pos-orange-primary);"></i>
                            <span style="font-weight:600;font-size:14px;">Mã QR</span>
                        </div>
                        <div style="display:flex;align-items:center;gap:12px;">
                            <button class="pos-toggle @(_payQrEnabled ? "pos-toggle--on" : "")" @onclick="ToggleQr" @onclick:stopPropagation="true">
                                <span class="pos-toggle__knob"></span>
                            </button>
                            <i data-lucide="@(_settingsQrOpen ? "chevron-up" : "chevron-down")" style="width:16px;height:16px;color:var(--pos-text-tertiary);"></i>
                        </div>
                    </div>
                    @if (_settingsQrOpen && _payQrEnabled)
                    {
                        <div style="padding:0 16px 14px;border-top:1px solid var(--pos-border-subtle);">
                            <label style="font-size:12px;color:var(--pos-text-tertiary);display:block;margin:12px 0 4px;">Ngân hàng</label>
                            <input type="text" class="pos-settings-input" placeholder="VD: Vietcombank, MB Bank..." @bind="_qrBankName" />
                            <label style="font-size:12px;color:var(--pos-text-tertiary);display:block;margin:12px 0 4px;">Số tài khoản</label>
                            <input type="text" class="pos-settings-input" placeholder="Nhập số tài khoản..." @bind="_qrAccountNumber" />
                            <label style="font-size:12px;color:var(--pos-text-tertiary);display:block;margin:12px 0 4px;">Tên chủ tài khoản</label>
                            <input type="text" class="pos-settings-input" placeholder="Nhập tên chủ TK..." @bind="_qrAccountName" />
                        </div>
                    }
                </div>

                @* ─── Transfer ─── *@
                <div style="background:var(--pos-bg-card);border:1px solid var(--pos-border-subtle);border-radius:var(--pos-radius);margin-bottom:12px;overflow:hidden;">
                    <div style="display:flex;align-items:center;justify-content:space-between;padding:14px 16px;cursor:pointer;" @onclick="() => _settingsTransferOpen = !_settingsTransferOpen">
                        <div style="display:flex;align-items:center;gap:10px;">
                            <i data-lucide="building-2" style="width:20px;height:20px;color:var(--pos-orange-primary);"></i>
                            <span style="font-weight:600;font-size:14px;">Chuyển khoản</span>
                        </div>
                        <div style="display:flex;align-items:center;gap:12px;">
                            <button class="pos-toggle @(_payTransferEnabled ? "pos-toggle--on" : "")" @onclick="ToggleTransfer" @onclick:stopPropagation="true">
                                <span class="pos-toggle__knob"></span>
                            </button>
                            <i data-lucide="@(_settingsTransferOpen ? "chevron-up" : "chevron-down")" style="width:16px;height:16px;color:var(--pos-text-tertiary);"></i>
                        </div>
                    </div>
                    @if (_settingsTransferOpen && _payTransferEnabled)
                    {
                        <div style="padding:0 16px 14px;border-top:1px solid var(--pos-border-subtle);">
                            <label style="font-size:12px;color:var(--pos-text-tertiary);display:block;margin:12px 0 4px;">Ngân hàng</label>
                            <input type="text" class="pos-settings-input" placeholder="VD: Vietcombank, MB Bank..." @bind="_transferBankName" />
                            <label style="font-size:12px;color:var(--pos-text-tertiary);display:block;margin:12px 0 4px;">Số tài khoản</label>
                            <input type="text" class="pos-settings-input" placeholder="Nhập số tài khoản..." @bind="_transferAccountNumber" />
                            <label style="font-size:12px;color:var(--pos-text-tertiary);display:block;margin:12px 0 4px;">Tên chủ tài khoản</label>
                            <input type="text" class="pos-settings-input" placeholder="Nhập tên chủ TK..." @bind="_transferAccountName" />
                        </div>
                    }
                </div>

                <button style="width:100%;padding:12px;border-radius:var(--pos-radius);border:none;background:var(--pos-orange-primary);color:#fff;font-size:14px;font-weight:600;cursor:pointer;margin-top:8px;"
                        @onclick="SavePaymentSettings">
                    <i data-lucide="save" style="width:16px;height:16px;vertical-align:middle;margin-right:6px;"></i>Lưu cài đặt
                </button>
                @if (!string.IsNullOrEmpty(_settingsSaveMsg))
                {
                    <div style="text-align:center;font-size:13px;color:var(--pos-success);margin-top:8px;">@_settingsSaveMsg</div>
                }
            </div>
            break;
    }
</div>

@* ═══════════════ VERTICAL NAVIGATION (right sidebar) ═══════════════ *@
<div class="pos-bottom-nav">
    <button class="pos-bottom-nav__tab @(_activeTab == PosTab.Sale ? "pos-bottom-nav__tab--active" : "")"
            @onclick="() => SwitchTab(PosTab.Sale)">
        <i data-lucide="coffee" class="pos-bottom-nav__icon"></i>
        <span>Bán hàng</span>
    </button>
    <button class="pos-bottom-nav__tab @(_activeTab == PosTab.History ? "pos-bottom-nav__tab--active" : "")"
            @onclick="() => SwitchTab(PosTab.History)">
        <i data-lucide="clock" class="pos-bottom-nav__icon"></i>
        <span>Lịch sử</span>
    </button>
    <button class="pos-bottom-nav__tab @(_activeTab == PosTab.Dashboard ? "pos-bottom-nav__tab--active" : "")"
            @onclick="() => SwitchTab(PosTab.Dashboard)">
        <i data-lucide="bar-chart-3" class="pos-bottom-nav__icon"></i>
        <span>Dashboard</span>
    </button>
    <button class="pos-bottom-nav__tab @(_activeTab == PosTab.Settings ? "pos-bottom-nav__tab--active" : "")"
            @onclick="() => SwitchTab(PosTab.Settings)">
        <i data-lucide="settings" class="pos-bottom-nav__icon"></i>
        <span>Cài đặt</span>
    </button>
</div>
</div> @* close outer flex wrapper *@

@code {
    // ═══════════════ TAB SYSTEM ═══════════════
    private enum PosTab { Sale, History, Dashboard, Settings }
    private PosTab _activeTab = PosTab.Sale;

    private async Task SwitchTab(PosTab tab)
    {
        if (_paymentStep != PayStep.None && _paymentStep != PayStep.Success) return; // Block tab switch during payment
        _activeTab = tab;

        // EN: Lazy-load data when switching tabs / VI: Load dữ liệu khi chuyển tab
        if (tab == PosTab.History && !_historyLoaded)
            await LoadHistoryAsync();
        else if (tab == PosTab.Dashboard && !_dashLoaded)
            await LoadDashboardAsync();
    }

    // ═══════════════ SALE TAB — Product & Cart ═══════════════
    private bool _isLoading = true;
    private bool _loadError;
    private string[] _categories = { "Tất cả" };
    private string _selectedCategory = "Tất cả";
    private List<Product> _products = new();
    private readonly List<CartItem> _cartItems = new();
    private IEnumerable<Product> FilteredProducts =>
        _selectedCategory == "Tất cả" ? _products : _products.Where(p => p.Category == _selectedCategory);
    private decimal CartTotal => _cartItems.Sum(i => i.Price * i.Qty);
    private decimal FinalTotal => Math.Max(0, CartTotal - _discountAmount);

    // EN: Shop info for receipt printing / VI: Thông tin shop cho in hoá đơn
    private string? _shopName;
    private string? _shopAddress;
    private string? _shopPhone;

    // Voucher state
    private string _voucherCode = "";
    private string? _voucherMessage;
    private PosDataService.VoucherValidationInfo? _appliedVoucher;
    private decimal _discountAmount;

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        try
        {
            var productsTask = DataService.GetProductsAsync(ShopId);
            var categoriesTask = DataService.GetCategoriesAsync(ShopId);
            var shopTask = DataService.GetShopByIdAsync(ShopId);
            await Task.WhenAll(productsTask, categoriesTask, shopTask);

            // EN: Load shop info for receipt / VI: Tải thông tin shop cho hoá đơn
            var shop = await shopTask;
            if (shop != null) { _shopName = shop.Name; _shopPhone = shop.Phone; }

            var apiProducts = await productsTask;
            var apiCategories = await categoriesTask;

            _products = apiProducts.Select(p => new Product(p.Id, p.Name, p.Price, p.CategoryName ?? "Khác")).ToList();

            var catNames = apiCategories.Select(c => c.Name).ToList();
            if (catNames.Count > 0)
                _categories = new[] { "Tất cả" }.Concat(catNames).ToArray();
            else
            {
                var productCats = _products.Select(p => p.Category).Distinct().ToList();
                _categories = new[] { "Tất cả" }.Concat(productCats).ToArray();
            }
        }
        catch { _loadError = true; }
        finally { _isLoading = false; }

        await LoadPaymentSettings();
        await RestoreCartFromLocalStorage();
    }

    private async Task AddToCart(Product product)
    {
        if (_paymentStep != PayStep.None) return;
        var existing = _cartItems.FirstOrDefault(i => i.ProductId == product.Id);
        if (existing != null) existing.Qty++;
        else _cartItems.Add(new CartItem(product.Id, product.Name, product.Price));
        await SaveCartToLocalStorage();
    }

    private async Task ChangeQty(CartItem item, int delta)
    {
        item.Qty += delta;
        if (item.Qty <= 0) _cartItems.Remove(item);
        await SaveCartToLocalStorage();
    }

    // ═══════════════ VOUCHER ═══════════════
    private async Task ValidateVoucher()
    {
        _voucherMessage = null; _appliedVoucher = null; _discountAmount = 0;
        if (string.IsNullOrWhiteSpace(_voucherCode)) { _voucherMessage = "Vui lòng nhập mã voucher."; return; }
        var info = await DataService.ValidateVoucherAsync(_voucherCode.Trim());
        if (info == null) { _voucherMessage = "Không thể kiểm tra voucher."; return; }
        if (!info.IsValid) { _voucherMessage = info.ErrorMessage ?? "Mã voucher không hợp lệ."; return; }
        _appliedVoucher = info;
        // EN: Detect percentage-based voucher from campaign name containing [percentage]
        // VI: Nhận diện voucher theo % từ tên chiến dịch chứa [percentage]
        var isPercentage = (info.CampaignName ?? "").Contains("[percentage]", StringComparison.OrdinalIgnoreCase);
        if (isPercentage)
        {
            var pct = Math.Min(info.RemainingValue ?? 0, 100);
            _discountAmount = Math.Round(CartTotal * pct / 100, 0);
            _voucherMessage = $"Voucher {info.CampaignName?.Replace("[percentage]","").Trim()}: giảm {pct}% = {FormatPrice(_discountAmount)}";
        }
        else
        {
            _discountAmount = Math.Min(info.RemainingValue ?? 0, CartTotal);
            _voucherMessage = $"Voucher {info.CampaignName}: giảm {FormatPrice(_discountAmount)}";
        }
    }
    private void ClearVoucher() { _appliedVoucher = null; _discountAmount = 0; _voucherCode = ""; _voucherMessage = null; }

    // ═══════════════ INLINE PAYMENT ═══════════════
    private enum PayStep { None, MethodSelect, AmountInput, Processing, Success }
    private PayStep _paymentStep = PayStep.None;
    private string _selectedMethod = "";
    private decimal _receivedAmount;
    private string _customAmountInput = "";
    private decimal _lastOrderTotal;
    private string _lastTransactionId = "";
    private string _lastPaymentMethod = "";
    private List<(string Name, int Qty, decimal Price)> _lastReceiptItems = new();
    private decimal ChangeAmount => _receivedAmount - FinalTotal;

    // EN: Created order ID — set when order is submitted to API before payment
    // VI: ID đơn hàng đã tạo — gán khi đơn được gửi lên API trước thanh toán
    private Guid? _createdOrderId;
    private string? _orderError;
    private bool _orderCreating;

    private async Task StartPayment()
    {
        if (!_cartItems.Any()) return;
        if (_orderCreating) return;
        _orderCreating = true;
        _orderError = null;
        StateHasChanged();

        try
        {
            // EN: Create order in DB before proceeding to payment method selection
            // VI: Tạo đơn hàng trong DB trước khi chọn phương thức thanh toán
            var orderReq = new PosDataService.CreatePosOrderRequest(
                ShopId,
                null, // EN: Payment method not yet selected / VI: Chưa chọn phương thức thanh toán
                _cartItems.Select(i => new PosDataService.PosOrderItemRequest(
                    i.ProductId, i.Name, i.Qty, i.Price)).ToList(),
                _discountAmount > 0 ? _discountAmount : null,
                _appliedVoucher != null ? "voucher" : null,
                _appliedVoucher?.VoucherCode);

            var result = await DataService.CreatePosOrderAsync(orderReq);
            if (result != null)
            {
                _createdOrderId = result.OrderId;
                _paymentStep = PayStep.MethodSelect;
            }
            else
            {
                _orderError = "Không thể tạo đơn hàng. Vui lòng thử lại.";
            }
        }
        catch (Exception ex)
        {
            _orderError = $"Lỗi tạo đơn: {ex.Message}";
        }
        finally
        {
            _orderCreating = false;
            StateHasChanged();
        }
    }

    private async Task CancelPayment()
    {
        // EN: Cancel the created order if payment is abandoned
        // VI: Hủy đơn hàng đã tạo nếu bỏ thanh toán
        if (_createdOrderId.HasValue)
        {
            try { await DataService.CancelOrderAsync(_createdOrderId.Value); } catch { }
            _createdOrderId = null;
        }
        _paymentStep = PayStep.None;
        _selectedMethod = "";
        _receivedAmount = 0;
        _customAmountInput = "";
    }

    private void SelectPaymentMethod(string method)
    {
        _selectedMethod = method;
        _receivedAmount = 0;
        _customAmountInput = "";

        if (method == "cash")
            _paymentStep = PayStep.AmountInput;
        else
            _paymentStep = PayStep.Processing;
    }

    private string GetMethodLabel() => _selectedMethod switch
    {
        "cash" => "Tiền mặt",
        "card" => "Thẻ",
        "qr" => "Mã QR",
        "transfer" => "Chuyển khoản",
        _ => "Thanh toán"
    };

    private List<(string Label, decimal Value)> GetQuickAmounts()
    {
        var total = FinalTotal;
        var amounts = new List<(string, decimal)>();
        var roundUp = Math.Ceiling(total / 50_000) * 50_000;
        if (roundUp == total) roundUp += 50_000;
        amounts.Add(("Đúng tiền", total));
        amounts.Add((FormatPrice(roundUp), roundUp));
        amounts.Add((FormatPrice(roundUp + 50_000), roundUp + 50_000));
        amounts.Add((FormatPrice(500_000), 500_000));
        amounts.Add((FormatPrice(200_000), 200_000));
        amounts.Add((FormatPrice(1_000_000), 1_000_000));
        return amounts;
    }

    private void ApplyCustomAmount()
    {
        if (decimal.TryParse(_customAmountInput, out var val))
            _receivedAmount = val;
    }

    private bool _paymentProcessing;
    private string? _paymentError;

    private async Task ConfirmPayment()
    {
        if (_paymentProcessing) return;
        _paymentProcessing = true;
        _paymentError = null;
        StateHasChanged();

        _lastOrderTotal = FinalTotal;
        _lastPaymentMethod = _selectedMethod;
        _lastReceiptItems = _cartItems.Select(i => (i.Name, i.Qty, i.Price)).ToList();
        var methodLabel = _selectedMethod switch { "cash" => "Tiền mặt", "card" => "Thẻ", "qr" => "QR Code", _ => "Chuyển khoản" };

        // EN: Call API to mark order as paid (order was already created in StartPayment)
        // VI: Gọi API đánh dấu đơn đã thanh toán (đơn đã được tạo ở StartPayment)
        bool paymentSuccess = false;
        try
        {
            if (_createdOrderId.HasValue)
            {
                // EN: Pass amountTendered for cash (required by validator), use FinalTotal for non-cash
                // VI: Truyền amountTendered cho tiền mặt (validator yêu cầu), dùng FinalTotal cho phương thức khác
                var amount = _selectedMethod == "cash" ? _receivedAmount : FinalTotal;
                var result = await DataService.PayOrderWithDetailsAsync(
                    _createdOrderId.Value, ShopId, _selectedMethod, amount);
                paymentSuccess = result?.Success ?? false;
                _lastTransactionId = _createdOrderId.Value.ToString()[..8].ToUpper();
            }

            if (!paymentSuccess)
            {
                _paymentError = "Thanh toán thất bại. Vui lòng thử lại.";
                _paymentProcessing = false;
                StateHasChanged();
                return;
            }

            // EN: Redeem voucher if applied / VI: Sử dụng voucher nếu đã áp dụng
            if (_appliedVoucher?.VoucherId != null && _discountAmount > 0)
            {
                try { await DataService.RedeemVoucherAsync(_appliedVoucher.VoucherId.Value, _discountAmount); } catch { }
            }
        }
        catch (Exception ex)
        {
            _paymentError = $"Lỗi thanh toán: {ex.Message}. Vui lòng thử lại.";
            _paymentProcessing = false;
            StateHasChanged();
            return;
        }

        // EN: Save to session history (in-memory for this POS session)
        // VI: Lưu vào lịch sử phiên (in-memory cho phiên POS hiện tại)
        _sessionOrders.Insert(0, new SessionOrder(
            _lastTransactionId,
            string.Join(", ", _cartItems.Select(i => $"{i.Name} x{i.Qty}")),
            _lastOrderTotal,
            DateTime.Now.ToString("HH:mm"),
            methodLabel,
            "Hoàn thành"
        ));

        // EN: Invalidate caches so next view refreshes
        // VI: Xóa cache để refresh khi xem lại
        _dashLoaded = false;
        _historyLoaded = false;

        _paymentProcessing = false;
        _paymentStep = PayStep.Success;
        StateHasChanged();
    }

    private async Task ResetAfterPayment()
    {
        _cartItems.Clear();
        _paymentStep = PayStep.None;
        _selectedMethod = "";
        _receivedAmount = 0;
        _customAmountInput = "";
        _createdOrderId = null;
        _orderError = null;
        ClearVoucher();
        await SaveCartToLocalStorage();
    }

    /// <summary>
    /// EN: Print receipt — opens a new window with thermal-style receipt and triggers print dialog.
    /// VI: In hóa đơn — mở cửa sổ mới với hóa đơn kiểu máy in nhiệt và kích hoạt in.
    /// </summary>
    private async Task PrintReceipt()
    {
        var payLabel = _lastPaymentMethod switch { "cash" => "Tiền mặt", "card" => "Thẻ", "qr" => "QR Code", _ => "Chuyển khoản" };

        // EN: Use ReceiptPrintService to generate HTML from saved template
        // VI: Dùng ReceiptPrintService để tạo HTML từ mẫu đã lưu
        await ReceiptPrint.PrintAsync(ShopId, new ReceiptData
        {
            ShopName = _shopName ?? "Cửa hàng",
            ShopAddress = _shopAddress,
            ShopPhone = _shopPhone,
            OrderNumber = _lastTransactionId,
            OrderDate = DateTime.Now,
            Items = _lastReceiptItems.Select(i => new ReceiptItem(i.Name, i.Qty, i.Price)).ToList(),
            Subtotal = _lastReceiptItems.Sum(i => i.Qty * i.Price),
            DiscountAmount = _discountAmount,
            Total = _lastOrderTotal,
            PaymentMethod = payLabel,
            AmountTendered = _lastPaymentMethod == "cash" ? _receivedAmount : null,
            ChangeAmount = _lastPaymentMethod == "cash" && _receivedAmount > _lastOrderTotal ? _receivedAmount - _lastOrderTotal : null,
            TransactionId = _lastTransactionId
        });
    }

    // ═══════════════ HISTORY TAB — API-driven ═══════════════
    private string _historySearch = "";
    private string _historyFilter = "today";
    private SessionOrder? _selectedOrder;
    private bool _historyLoading;
    private bool _historyLoaded;
    private PosDataService.OrderDetailResponse? _selectedOrderDetail;
    private bool _orderDetailLoading;

    // EN: Session orders created during this POS session (in-memory, real-time)
    // VI: Đơn hàng tạo trong phiên POS này (in-memory, real-time)
    private readonly List<SessionOrder> _sessionOrders = new();

    // EN: API orders fetched from DB
    // VI: Đơn hàng từ API (DB)
    private List<PosDataService.OrderInfo> _apiOrders = new();

    private readonly List<HistoryFilter> _historyFilters = new()
    {
        new("today", "Hôm nay"),
        new("week", "7 ngày"),
        new("month", "30 ngày"),
    };

    private async Task LoadHistoryAsync()
    {
        _historyLoading = true;
        StateHasChanged();
        try
        {
            _apiOrders = await DataService.GetOrdersAsync(ShopId, _historyFilter);
        }
        catch { _apiOrders = new(); }
        _historyLoaded = true;
        _historyLoading = false;
        StateHasChanged();
    }

    /// <summary>
    /// EN: Change history date filter and reload from API.
    /// VI: Thay đổi filter ngày và tải lại từ API.
    /// </summary>
    private async Task ChangeHistoryFilter(string filterKey)
    {
        if (_historyFilter == filterKey) return;
        _historyFilter = filterKey;
        _historyLoaded = false;
        await LoadHistoryAsync();
    }

    private IEnumerable<SessionOrder> FilteredSessionOrders =>
        string.IsNullOrWhiteSpace(_historySearch)
            ? _sessionOrders
            : _sessionOrders.Where(o =>
                o.Id.Contains(_historySearch, StringComparison.OrdinalIgnoreCase) ||
                o.Items.Contains(_historySearch, StringComparison.OrdinalIgnoreCase));

    private IEnumerable<PosDataService.OrderInfo> FilteredApiOrders =>
        string.IsNullOrWhiteSpace(_historySearch)
            ? _apiOrders
            : _apiOrders.Where(o =>
                o.Id.ToString().Contains(_historySearch, StringComparison.OrdinalIgnoreCase) ||
                (o.Status?.Contains(_historySearch, StringComparison.OrdinalIgnoreCase) ?? false));

    private static string MapApiStatus(string? status) => status switch
    {
        "Draft" => "Nháp",
        "Validated" => "Chờ thanh toán",
        "Paid" => "Đã thanh toán",
        "Completed" or "Delivered" => "Hoàn thành",
        "Cancelled" => "Đã hủy",
        "Refunded" => "Hoàn trả",
        "Processing" => "Đang xử lý",
        "Pending" or "PaymentPending" => "Chờ xác nhận TT",
        _ => status ?? "—"
    };

    private static string MapPaymentMethodLabel(string? method) => method switch
    {
        "cash" => "Tiền mặt",
        "card" => "Thẻ",
        "qr" => "Mã QR",
        "transfer" or "bank_transfer" => "Chuyển khoản",
        "vnpay" => "VNPay",
        "momo" => "MoMo",
        _ => string.IsNullOrEmpty(method) ? "Chưa thanh toán" : method
    };

    private async Task ViewOrderDetail(Guid orderId)
    {
        _orderDetailLoading = true;
        StateHasChanged();
        try { _selectedOrderDetail = await DataService.GetOrderDetailAsync(orderId, ShopId); }
        catch { _selectedOrderDetail = null; }
        _orderDetailLoading = false;
        StateHasChanged();
    }

    private void CloseOrderDetail()
    {
        _selectedOrderDetail = null;
        _selectedOrder = null;
    }

    private async Task PrintOrderDetail()
    {
        if (_selectedOrderDetail?.Order == null) return;
        var od = _selectedOrderDetail.Order;
        var payLabel = MapPaymentMethodLabel(od.PaymentMethod);
        var items = (_selectedOrderDetail.Items ?? new())
            .Select(i => new ReceiptItem(i.ProductName ?? "—", i.Quantity, i.UnitPrice)).ToList();

        await ReceiptPrint.PrintAsync(ShopId, new ReceiptData
        {
            ShopName = _shopName ?? "Cửa hàng",
            ShopAddress = _shopAddress,
            ShopPhone = _shopPhone,
            OrderNumber = od.Id.ToString()[..8].ToUpper(),
            OrderDate = od.CreatedAt,
            Items = items,
            Subtotal = items.Sum(i => i.Qty * i.Price),
            Total = od.TotalAmount,
            PaymentMethod = payLabel,
            TransactionId = od.Id.ToString()[..8].ToUpper()
        });
    }

    private async Task PrintSessionOrderDetail()
    {
        if (_selectedOrder == null) return;
        var so = _selectedOrder;

        await ReceiptPrint.PrintAsync(ShopId, new ReceiptData
        {
            ShopName = _shopName ?? "Cửa hàng",
            ShopAddress = _shopAddress,
            ShopPhone = _shopPhone,
            OrderNumber = so.Id,
            OrderDate = DateTime.Now,
            Items = new(), // session order doesn't have item detail
            Subtotal = so.Total,
            Total = so.Total,
            PaymentMethod = so.Method,
            TransactionId = so.Id
        });
    }

    // ═══════════════ DASHBOARD TAB — API-driven ═══════════════
    private bool _dashLoading;
    private bool _dashLoaded;
    private string _dashPeriod = "today";
    private PosDataService.PosDashboardInfo _dashboard = new(0, 0, 0, 0, new(), new(), new(), new());

    private async Task SwitchDashPeriod(string period)
    {
        _dashPeriod = period;
        _dashLoaded = false;
        await LoadDashboardAsync();
    }

    private async Task LoadDashboardAsync()
    {
        _dashLoading = true;
        StateHasChanged();
        try
        {
            var data = await DataService.GetPosDashboardAsync(ShopId, _dashPeriod);
            var payments = data.PaymentBreakdown ?? new();
            var hourly = data.HourlyRevenue ?? new();

            // EN: Compute percentage for payment breakdown
            // VI: Tính phần trăm cho breakdown thanh toán
            var totalPayments = payments.Sum(p => p.Amount);
            foreach (var p in payments)
                p.Pct = totalPayments > 0 ? (int)(p.Amount / totalPayments * 100) : 0;

            // EN: Compute percentage for hourly revenue (relative to max)
            // VI: Tính phần trăm cho doanh thu theo giờ (tương đối so với max)
            var maxHourlyRevenue = hourly.Any() ? hourly.Max(h => h.Revenue) : 0;
            foreach (var h in hourly)
                h.Pct = maxHourlyRevenue > 0 ? (int)(h.Revenue / maxHourlyRevenue * 100) : 0;

            _dashboard = new PosDataService.PosDashboardInfo(
                data.Revenue, data.OrderCount, data.ItemsSold, data.AvgOrderValue,
                data.PopularItems ?? new(),
                payments,
                hourly,
                data.RecentOrders ?? new());
        }
        catch
        {
            _dashboard = new(0, 0, 0, 0, new(), new(), new(), new());
        }
        _dashLoaded = true;
        _dashLoading = false;
        StateHasChanged();
    }

    // ═══════════════ PAYMENT SETTINGS ═══════════════
    private bool _payCardEnabled = true;
    private bool _payQrEnabled = true;
    private bool _payTransferEnabled = true;
    private string _cardTerminalId = "";
    private string _qrBankName = "";
    private string _qrAccountNumber = "";
    private string _qrAccountName = "";
    private string _transferBankName = "";
    private string _transferAccountNumber = "";
    private string _transferAccountName = "";
    private bool _settingsCardOpen;
    private bool _settingsQrOpen;
    private bool _settingsTransferOpen;
    private string? _settingsSaveMsg;

    private void ToggleCard() => _payCardEnabled = !_payCardEnabled;
    private void ToggleQr() => _payQrEnabled = !_payQrEnabled;
    private void ToggleTransfer() => _payTransferEnabled = !_payTransferEnabled;

    private async Task LoadPaymentSettings()
    {
        try
        {
            var json = await JS.InvokeAsync<string?>("localStorage.getItem", "pos_payment_settings");
            if (!string.IsNullOrEmpty(json))
            {
                var doc = System.Text.Json.JsonDocument.Parse(json);
                var r = doc.RootElement;
                if (r.TryGetProperty("cardEnabled", out var ce)) _payCardEnabled = ce.GetBoolean();
                if (r.TryGetProperty("qrEnabled", out var qe)) _payQrEnabled = qe.GetBoolean();
                if (r.TryGetProperty("transferEnabled", out var te)) _payTransferEnabled = te.GetBoolean();
                if (r.TryGetProperty("cardTerminalId", out var ct)) _cardTerminalId = ct.GetString() ?? "";
                if (r.TryGetProperty("qrBankName", out var qb)) _qrBankName = qb.GetString() ?? "";
                if (r.TryGetProperty("qrAccountNumber", out var qa)) _qrAccountNumber = qa.GetString() ?? "";
                if (r.TryGetProperty("qrAccountName", out var qn)) _qrAccountName = qn.GetString() ?? "";
                if (r.TryGetProperty("transferBankName", out var tb)) _transferBankName = tb.GetString() ?? "";
                if (r.TryGetProperty("transferAccountNumber", out var ta)) _transferAccountNumber = ta.GetString() ?? "";
                if (r.TryGetProperty("transferAccountName", out var tn)) _transferAccountName = tn.GetString() ?? "";
            }
        }
        catch { /* first load — no settings yet */ }
    }

    private async Task SavePaymentSettings()
    {
        var settings = new
        {
            cardEnabled = _payCardEnabled,
            qrEnabled = _payQrEnabled,
            transferEnabled = _payTransferEnabled,
            cardTerminalId = _cardTerminalId,
            qrBankName = _qrBankName,
            qrAccountNumber = _qrAccountNumber,
            qrAccountName = _qrAccountName,
            transferBankName = _transferBankName,
            transferAccountNumber = _transferAccountNumber,
            transferAccountName = _transferAccountName
        };
        var json = System.Text.Json.JsonSerializer.Serialize(settings);
        await JS.InvokeVoidAsync("localStorage.setItem", "pos_payment_settings", json);
        _settingsSaveMsg = "Đã lưu cài đặt!";
        StateHasChanged();
        await Task.Delay(2000);
        _settingsSaveMsg = null;
        StateHasChanged();
    }

    // ═══════════════ LOCALSTORAGE PERSISTENCE ═══════════════
    private string CartStorageKey => $"pos_cafe_cart_{ShopId}";

    private async Task SaveCartToLocalStorage()
    {
        try
        {
            var cartData = _cartItems.Select(i => new { i.ProductId, i.Name, i.Price, i.Qty }).ToList();
            await JS.InvokeVoidAsync("localStorage.setItem", CartStorageKey,
                System.Text.Json.JsonSerializer.Serialize(cartData));
        }
        catch { }
    }

    private async Task RestoreCartFromLocalStorage()
    {
        try
        {
            var cartJson = await JS.InvokeAsync<string?>("localStorage.getItem", CartStorageKey);
            if (!string.IsNullOrEmpty(cartJson))
            {
                var items = System.Text.Json.JsonSerializer.Deserialize<List<StoredCartItem>>(cartJson, _lsJsonOptions);
                if (items != null)
                    foreach (var i in items)
                        _cartItems.Add(new CartItem(i.ProductId, i.Name, i.Price) { Qty = i.Qty });
            }
        }
        catch { }
    }

    private static readonly System.Text.Json.JsonSerializerOptions _lsJsonOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    private record StoredCartItem(Guid ProductId, string Name, decimal Price, int Qty);

    // ═══════════════ RECORDS ═══════════════
    private record Product(Guid Id, string Name, decimal Price, string Category);
    private class CartItem(Guid productId, string name, decimal price)
    {
        public Guid ProductId { get; set; } = productId;
        public string Name { get; set; } = name;
        public decimal Price { get; set; } = price;
        public int Qty { get; set; } = 1;
    }
    private record SessionOrder(string Id, string Items, decimal Total, string Time, string Method, string Status);
    private record HistoryFilter(string Key, string Label);
}
