@*
    EN: Restaurant POS Desktop — Table map + dine-in order flow (order → kitchen → add more → pay).
    VI: POS Nhà hàng Desktop — Sơ đồ bàn + luồng dine-in (gọi món → bếp → gọi thêm → thanh toán).
*@
@page "/pos/{ShopId:guid}/restaurant"
@layout PosLayout
@inherits PosBase
@using WebClientTpos.Client.Services
@inject PosDataService DataService
@inject IJSRuntime JS

@* ═══ LEFT PANEL ═══ *@
<div class="pos-product-panel @(_paymentStep != PayStep.None ? "pos-product-panel--dimmed" : "")" style="padding:16px;overflow-y:auto;">
    @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 if (_viewMode == ViewMode.TableMap)
    {
        @* ═══ TABLE MAP VIEW ═══ *@
        <div class="pos-category-tabs">
            @foreach (var section in _sections)
            {
                <button class="pos-category-tab @(section == _activeSection ? "pos-category-tab--active" : "")"
                        @onclick="() => _activeSection = section">
                    @(section)
                </button>
            }
        </div>

        @if (!_tables.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="grid-3x3" style="width:48px;height:48px;margin-bottom:12px;opacity:0.3;"></i>
                <div style="font-size:15px;font-weight:600;margin-bottom:4px;">Chưa có bàn nào</div>
                <div style="font-size:13px;">Vui lòng thêm bàn trong phần Quản lý cửa hàng</div>
            </div>
        }
        else
        {
        <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:12px;padding:8px 0;">
            @foreach (var table in FilteredTables)
            {
                var effectiveStatus = GetEffectiveStatus(table);
                var hasReservation = GetTableReservation(table) is not null;
                <div @onclick="() => SelectTable(table)"
                     style="background:@GetStatusColor(effectiveStatus);border-radius:var(--pos-radius);
                            padding:16px;text-align:center;cursor:pointer;border:2px solid @(SelectedTable?.Id == table.Id ? "var(--pos-orange-primary)" : "transparent");
                            transition:all .2s ease;position:relative;">
                    <div style="font-size:20px;font-weight:700;">@table.Name</div>
                    <div style="font-size:12px;color:rgba(255,255,255,.7);margin-top:4px;">@table.Seats chỗ</div>
                    <div style="font-size:11px;margin-top:6px;font-weight:600;text-transform:uppercase;">
                        @GetStatusLabel(effectiveStatus)
                    </div>
                    @if (hasReservation)
                    {
                        var res = GetTableReservation(table)!;
                        <div style="position:absolute;top:4px;right:4px;background:rgba(99,102,241,.9);color:#fff;font-size:9px;padding:2px 6px;border-radius:4px;font-weight:600;">
                            @res.ReservationTime.ToString("HH:mm")
                        </div>
                    }
                    @if (HasPendingOrder(table))
                    {
                        <div style="position:absolute;top:4px;left:4px;background:rgba(255,92,0,.9);color:#fff;font-size:9px;padding:2px 6px;border-radius:4px;font-weight:600;">
                            @FormatPrice(GetTableOrderTotal(table))
                        </div>
                    }
                </div>
            }
        </div>
        }
    }
    else if (_viewMode == ViewMode.Menu)
    {
        @* ═══ PRODUCT CATALOG VIEW ═══ *@
        <div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
            <button @onclick="BackToTableMap" style="padding:6px 12px;border-radius:8px;border:1px solid var(--pos-border-default);background:transparent;color:var(--pos-text-primary);cursor:pointer;font-size:12px;font-weight:600;display:flex;align-items:center;gap:4px;">
                <i data-lucide="arrow-left" style="width:14px;height:14px;"></i> Sơ đồ bàn
            </button>
            <span style="font-weight:700;font-size:14px;">@SelectedTable?.Name</span>
            <span style="font-size:12px;color:var(--pos-text-tertiary);">— Đặt món</span>
        </div>

        <div class="pos-category-tabs">
            @foreach (var cat in _menuCategories)
            {
                <button class="pos-category-tab @(cat == _selectedCategory ? "pos-category-tab--active" : "")"
                        @onclick="() => _selectedCategory = cat">
                    @cat
                </button>
            }
        </div>

        @if (!_products.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="utensils" style="width:48px;height:48px;margin-bottom:12px;opacity:0.3;"></i>
                <div style="font-size:15px;font-weight:600;margin-bottom:4px;">Chưa có món nào</div>
                <div style="font-size:13px;">Vui lòng thêm món trong phần Quản lý cửa hàng</div>
            </div>
        }
        else
        {
        <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="utensils" 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>

@* ═══ RIGHT PANEL — CART + SENT ITEMS + PAYMENT ═══ *@
<div class="pos-cart-panel">
    @if (_paymentStep == PayStep.None)
    {
        @* ─── CART MODE ─── *@
        @if (SelectedTable is not null)
        {
            <div class="pos-cart-header">
                <span class="pos-cart-header__title">@SelectedTable.Name</span>
                <span style="font-size:12px;color:var(--pos-text-tertiary);">@SelectedTable.Seats chỗ</span>
            </div>

            <div class="pos-cart-items">
                @* ─── SENT ITEMS (already in kitchen) ─── *@
                @{ var sentForTable = GetSentItemsForTable(SelectedTable); }
                @if (sentForTable.Any())
                {
                    <div style="padding:8px 12px;background:rgba(255,92,0,.08);border-radius:8px;margin-bottom:8px;">
                        <div style="font-size:11px;font-weight:700;color:var(--pos-orange-primary);margin-bottom:6px;display:flex;align-items:center;gap:4px;">
                            <i data-lucide="chef-hat" style="width:12px;height:12px;"></i> Đã gửi bếp
                        </div>
                        @foreach (var item in sentForTable)
                        {
                            <div style="display:flex;justify-content:space-between;padding:3px 0;font-size:12px;color:var(--pos-text-secondary);">
                                <span>@item.Name x@item.Qty</span>
                                <span>@FormatPrice(item.Price * item.Qty)</span>
                            </div>
                        }
                        <div style="display:flex;justify-content:space-between;padding-top:6px;border-top:1px dashed var(--pos-border-subtle);font-size:12px;font-weight:600;color:var(--pos-orange-primary);">
                            <span>Tạm tính</span>
                            <span>@FormatPrice(sentForTable.Sum(i => i.Price * i.Qty))</span>
                        </div>
                    </div>
                }

                @* ─── CURRENT CART (not yet sent) ─── *@
                @if (_cartItems.Any())
                {
                    @if (sentForTable.Any())
                    {
                        <div style="font-size:11px;font-weight:700;color:var(--pos-text-tertiary);margin-bottom:4px;padding:0 4px;display:flex;align-items:center;gap:4px;">
                            <i data-lucide="plus-circle" style="width:12px;height:12px;"></i> Món mới
                        </div>
                    }
                    @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>
                    }
                }
                else if (!sentForTable.Any())
                {
                    <div style="text-align:center;padding:32px 16px;color:var(--pos-text-tertiary);font-size:13px;">
                        @if (_viewMode == ViewMode.TableMap)
                        {
                            <span>Nhấn <b>Đặt món</b> để chọn món</span>
                        }
                        else
                        {
                            <span>Chọn món từ thực đơn bên trái</span>
                        }
                    </div>
                }
            </div>

            <div class="pos-cart-footer">
                <div class="pos-cart-total">
                    <span class="pos-cart-total__label">Tổng cộng</span>
                    <span class="pos-cart-total__value">@FormatPrice(GrandTotal)</span>
                </div>
                <div style="display:flex;gap:8px;">
                    @if (_viewMode == ViewMode.TableMap)
                    {
                        <button style="flex:1;padding:12px;border-radius:var(--pos-radius);background:var(--pos-bg-interactive);border:1px solid var(--pos-border-default);color:var(--pos-text-primary);cursor:pointer;font-size:13px;font-weight:600;"
                                @onclick="OpenMenu">
                            <i data-lucide="utensils" style="width:16px;height:16px;display:inline;vertical-align:middle;margin-right:4px;"></i>Đặt món
                        </button>
                    }
                    @if (_cartItems.Any())
                    {
                        <button style="flex:1;padding:12px;border-radius:var(--pos-radius);background:rgba(34,197,94,.15);border:1px solid rgba(34,197,94,.3);color:var(--pos-success);cursor:pointer;font-size:13px;font-weight:600;"
                                @onclick="SendToKitchen" disabled="@_sendingToKitchen">
                            <i data-lucide="chef-hat" style="width:16px;height:16px;display:inline;vertical-align:middle;margin-right:4px;"></i>
                            @(_sendingToKitchen ? "Đang gửi..." : "Gửi bếp")
                        </button>
                    }
                    @if (sentForTable.Any() && !_cartItems.Any())
                    {
                        <button class="pos-btn-checkout" style="flex:1;" @onclick="StartPayment">
                            <i data-lucide="credit-card" style="width:18px;height:18px;"></i> Thanh toán
                        </button>
                    }
                </div>
                @if (!string.IsNullOrEmpty(_kitchenMessage))
                {
                    <div style="margin-top:8px;padding:8px 12px;border-radius:8px;font-size:12px;
                                background:@(_kitchenSuccess ? "rgba(34,197,94,.12)" : "rgba(239,68,68,.12)");
                                color:@(_kitchenSuccess ? "var(--pos-success)" : "var(--pos-danger)");">
                        @_kitchenMessage
                    </div>
                }
            </div>
        }
        else
        {
            <div style="flex:1;display:flex;align-items:center;justify-content:center;color:var(--pos-text-tertiary);font-size:14px;">
                Chọn bàn để bắt đầu
            </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 — @SelectedTable?.Name</span>
                <span style="margin-left:auto;font-size:18px;font-weight:700;color:var(--pos-orange-primary);">@FormatPrice(GrandTotal)</span>
            </div>
            <div style="padding:12px 16px;">
                <div style="font-size:12px;font-weight:600;color:var(--pos-text-tertiary);margin-bottom:8px;">Chi tiết đơn</div>
                @{ var allItems = GetSentItemsForTable(SelectedTable!); }
                @foreach (var item in allItems)
                {
                    <div style="display:flex;justify-content:space-between;padding:4px 0;font-size:13px;">
                        <span>@item.Name x@item.Qty</span>
                        <span style="font-weight:600;">@FormatPrice(item.Price * item.Qty)</span>
                    </div>
                }
                <div style="display:flex;justify-content:space-between;padding-top:8px;border-top:1px solid var(--pos-border-subtle);font-weight:700;font-size:14px;margin-top:8px;">
                    <span>Tổng</span>
                    <span style="color:var(--pos-orange-primary);">@FormatPrice(GrandTotal)</span>
                </div>
            </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>
                <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>
                <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>
                <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 ─── *@
        <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(GrandTotal)</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);">
                <button class="pos-btn-checkout" @onclick="ConfirmPayment" disabled="@(_receivedAmount < GrandTotal)">
                    Xác nhận thanh toán
                </button>
            </div>
        </div>
    }
    else if (_paymentStep == PayStep.Processing)
    {
        @* ─── PAYMENT: QR/CARD/TRANSFER ─── *@
        <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(GrandTotal)</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);">
                <button class="pos-btn-checkout" @onclick="ConfirmPayment">
                    Xác nhận đã thanh toán
                </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);">@SelectedTable?.Name — @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>

@code {

    // ═══ VIEW STATE ═══
    private enum ViewMode { TableMap, Menu }
    private ViewMode _viewMode = ViewMode.TableMap;

    // ═══ LOADING ═══
    private bool _isLoading = true;
    private bool _loadError;

    // ═══ TABLES ═══
    private string _activeSection = "Tất cả";
    private string[] _sections = { "Tất cả" };
    private TableInfo? SelectedTable { get; set; }
    private List<TableInfo> _tables = new();
    private IEnumerable<TableInfo> FilteredTables =>
        _activeSection == "Tất cả" ? _tables : _tables.Where(t => t.Section == _activeSection);

    // ═══ RESERVATIONS ═══
    private List<PosDataService.ReservationInfo> _reservations = new();

    // ═══ PRODUCTS & CART ═══
    private List<Product> _products = new();
    private string[] _menuCategories = { "Tất cả" };
    private string _selectedCategory = "Tất cả";
    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);

    // ═══ SENT ITEMS (per table — items sent to kitchen, not yet paid) ═══
    private readonly Dictionary<string, List<SentItem>> _tableOrders = new();
    private readonly Dictionary<string, List<Guid>> _tableOrderIds = new();
    private bool _sendingToKitchen;
    private string? _kitchenMessage;
    private bool _kitchenSuccess;

    private decimal GrandTotal
    {
        get
        {
            var sentTotal = SelectedTable != null ? GetSentItemsForTable(SelectedTable).Sum(i => i.Price * i.Qty) : 0;
            return sentTotal + CartTotal;
        }
    }

    // ═══ 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<SentItem> _lastReceiptItems = new();
    private decimal ChangeAmount => _receivedAmount - GrandTotal;
    private bool _paymentProcessing;

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

        try
        {
            var tablesTask = DataService.GetTablesAsync(ShopId);
            var productsTask = DataService.GetProductsAsync(ShopId);
            var categoriesTask = DataService.GetCategoriesAsync(ShopId);
            var reservationsTask = DataService.GetReservationsAsync(ShopId, DateTime.Today.ToString("yyyy-MM-dd"));
            await Task.WhenAll(tablesTask, productsTask, categoriesTask, reservationsTask);

            var apiTables = await tablesTask;
            _tables = apiTables.Select(t => new TableInfo(
                t.Id.ToString(),
                $"Bàn {t.TableNumber}",
                t.Capacity,
                t.Status ?? "available",
                t.Zone ?? "Trong nhà"
            )).ToList();

            var zones = _tables.Select(t => t.Section).Distinct().ToList();
            _sections = new[] { "Tất cả" }.Concat(zones).ToArray();

            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)
                _menuCategories = new[] { "Tất cả" }.Concat(catNames).ToArray();
            else
            {
                var productCats = _products.Select(p => p.Category).Distinct().ToList();
                _menuCategories = new[] { "Tất cả" }.Concat(productCats).ToArray();
            }

            _reservations = await reservationsTask;

            // Load active table orders from DB (orders with table_id, status=Validated)
            await LoadTableOrdersFromDb();

            // Restore cart and selected table from localStorage
            await RestoreStateFromLocalStorage();
        }
        catch
        {
            _loadError = true;
        }
        finally
        {
            _isLoading = false;
        }
    }

    // ═══ TABLE ACTIONS ═══
    private async Task SelectTable(TableInfo table)
    {
        SelectedTable = table;
        _kitchenMessage = null;
        await SaveStateToLocalStorage();
    }

    private void OpenMenu()
    {
        if (SelectedTable == null) return;
        _viewMode = ViewMode.Menu;
        _selectedCategory = "Tất cả";
    }

    private void BackToTableMap()
    {
        _viewMode = ViewMode.TableMap;
    }

    // ═══ CART ═══
    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 SaveStateToLocalStorage();
    }

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

    // ═══ SEND TO KITCHEN ═══
    private async Task SendToKitchen()
    {
        if (!_cartItems.Any() || SelectedTable == null || _sendingToKitchen) return;
        _sendingToKitchen = true;
        _kitchenMessage = null;
        StateHasChanged();

        try
        {
            var tableGuid = Guid.TryParse(SelectedTable.Id, out var tg) ? tg : (Guid?)null;
            var orderReq = new PosDataService.CreatePosOrderRequest(
                ShopId,
                null,
                _cartItems.Select(i => new PosDataService.PosOrderItemRequest(
                    i.ProductId, i.Name, i.Qty, i.Price, "PreparedFood")).ToList(),
                null, null, null, tableGuid);

            var result = await DataService.CreatePosOrderAsync(orderReq);

            _cartItems.Clear();

            // Reload table orders from DB to reflect the new order
            await LoadTableOrdersFromDb();

            _kitchenMessage = "Đã gửi bếp thành công!";
            _kitchenSuccess = true;
            await SaveStateToLocalStorage();

            // Auto-clear message after 3s
            _ = Task.Delay(3000).ContinueWith(_ => InvokeAsync(() => { _kitchenMessage = null; StateHasChanged(); }));
        }
        catch
        {
            _kitchenMessage = "Không thể gửi bếp. Vui lòng thử lại.";
            _kitchenSuccess = false;
        }
        finally
        {
            _sendingToKitchen = false;
        }
    }

    // ═══ TABLE ORDER HELPERS ═══
    private List<SentItem> GetSentItemsForTable(TableInfo table) =>
        _tableOrders.TryGetValue(table.Id, out var items) ? items : new();

    private bool HasPendingOrder(TableInfo table) =>
        _tableOrders.ContainsKey(table.Id) && _tableOrders[table.Id].Any();

    private decimal GetTableOrderTotal(TableInfo table) =>
        _tableOrders.TryGetValue(table.Id, out var items) ? items.Sum(i => i.Price * i.Qty) : 0;

    // ═══ RESERVATION HELPERS ═══
    private PosDataService.ReservationInfo? GetTableReservation(TableInfo table)
    {
        if (!Guid.TryParse(table.Id, out var tableGuid)) return null;
        var now = DateTime.Now;
        return _reservations.FirstOrDefault(r =>
            r.TableId == tableGuid &&
            r.Status is "confirmed" or "pending" &&
            Math.Abs((r.ReservationTime - now).TotalHours) < 2);
    }

    private string GetEffectiveStatus(TableInfo table)
    {
        if (HasPendingOrder(table)) return "occupied";
        if (GetTableReservation(table) != null) return "reserved";
        return table.Status;
    }

    // ═══ PAYMENT FLOW ═══
    private void StartPayment()
    {
        if (SelectedTable == null || !HasPendingOrder(SelectedTable)) return;
        _paymentStep = PayStep.MethodSelect;
    }

    private void CancelPayment()
    {
        _paymentStep = PayStep.None;
        _selectedMethod = "";
        _receivedAmount = 0;
        _customAmountInput = "";
    }

    private void SelectPaymentMethod(string method)
    {
        _selectedMethod = method;
        _receivedAmount = 0;
        _customAmountInput = "";
        _paymentStep = method == "cash" ? PayStep.AmountInput : 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 = GrandTotal;
        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 string? _paymentError;

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

        _lastOrderTotal = GrandTotal;
        _lastPaymentMethod = _selectedMethod;
        _lastReceiptItems = GetSentItemsForTable(SelectedTable).ToList();
        _lastTransactionId = $"POS-{DateTime.Now:yyyyMMdd}-{DateTime.Now:HHmmss}";

        // Pay all orders for this table in the backend
        bool allPaid = true;
        try
        {
            if (_tableOrderIds.TryGetValue(SelectedTable.Id, out var orderIds))
            {
                var amount = _selectedMethod == "cash" ? _receivedAmount : GrandTotal;
                foreach (var orderId in orderIds)
                {
                    var result = await DataService.PayOrderWithDetailsAsync(
                        orderId, ShopId, _selectedMethod, amount);
                    if (result?.Success != true) allPaid = false;
                }
            }

            if (!allPaid)
            {
                _paymentError = "Thanh toán thất bại. Vui lòng thử lại.";
                _paymentProcessing = false;
                StateHasChanged();
                return;
            }
        }
        catch (Exception ex)
        {
            _paymentError = $"Lỗi thanh toán: {ex.Message}. Vui lòng thử lại.";
            _paymentProcessing = false;
            StateHasChanged();
            return;
        }

        _paymentProcessing = false;
        _paymentStep = PayStep.Success;

        // Reload table orders from DB (paid orders no longer Validated → removed)
        await LoadTableOrdersFromDb();
        await SaveStateToLocalStorage();
        StateHasChanged();
    }

    private async Task ResetAfterPayment()
    {
        _cartItems.Clear();
        _paymentStep = PayStep.None;
        _selectedMethod = "";
        _receivedAmount = 0;
        _customAmountInput = "";
        _viewMode = ViewMode.TableMap;
        SelectedTable = null;
        await SaveStateToLocalStorage();
    }

    private async Task PrintReceipt()
    {
        var itemsHtml = string.Join("", _lastReceiptItems.Select(i =>
            $"<div style='display:flex;justify-content:space-between;padding:4px 0;font-size:13px;'>" +
            $"<span>{i.Name} x{i.Qty}</span><span>{i.Price * i.Qty:N0}₫</span></div>"));
        var html = "<!DOCTYPE html><html><head><meta charset='utf-8'/>" +
            $"<title>Hóa đơn - {_lastTransactionId}</title>" +
            "<style>body{font-family:sans-serif;max-width:300px;margin:0 auto;padding:20px;}" +
            "h2{text-align:center;margin:0 0 10px;font-size:18px;}" +
            ".divider{border-top:1px dashed #ccc;margin:10px 0;}</style></head><body>" +
            "<h2>HÓA ĐƠN</h2>" +
            $"<div style='text-align:center;font-size:12px;color:#666;'>Bàn: {SelectedTable?.Name}</div>" +
            $"<div style='text-align:center;font-size:12px;color:#666;'>Mã: {_lastTransactionId}</div>" +
            $"<div style='text-align:center;font-size:12px;color:#666;'>{DateTime.Now:dd/MM/yyyy HH:mm}</div>" +
            "<div class='divider'></div>" + itemsHtml + "<div class='divider'></div>" +
            $"<div style='display:flex;justify-content:space-between;font-size:14px;font-weight:bold;'><span>TỔNG CỘNG</span><span>{_lastOrderTotal:N0}₫</span></div>" +
            $"<div style='text-align:center;font-size:11px;color:#999;margin-top:16px;'>Cảm ơn quý khách!</div>" +
            "</body></html>";
        await JS.InvokeVoidAsync("eval", $"var w=window.open('','_blank','width=350,height=500');w.document.write(`{html.Replace("`", "\\`")}`);w.document.close();w.print();");
    }

    // ═══ HELPERS ═══
    private static string GetStatusColor(string status) => status switch
    {
        "available" => "rgba(34,197,94,.15)", "occupied" => "rgba(255,92,0,.18)",
        "reserved" => "rgba(99,102,241,.18)", _ => "var(--pos-bg-interactive)"
    };

    private static string GetStatusLabel(string status) => status switch
    {
        "available" => "Trống", "occupied" => "Đang phục vụ", "reserved" => "Đã đặt", _ => status
    };

    // ═══ LOAD TABLE ORDERS FROM DB ═══
    private async Task LoadTableOrdersFromDb()
    {
        try
        {
            var activeOrders = await DataService.GetActiveTableOrdersAsync(ShopId);
            _tableOrders.Clear();
            _tableOrderIds.Clear();
            foreach (var order in activeOrders)
            {
                if (order.TableId == null) continue;
                var tableKey = order.TableId.Value.ToString();
                if (!_tableOrders.ContainsKey(tableKey))
                    _tableOrders[tableKey] = new();
                if (!_tableOrderIds.ContainsKey(tableKey))
                    _tableOrderIds[tableKey] = new();
                _tableOrderIds[tableKey].Add(order.OrderId);
                foreach (var item in order.Items)
                {
                    var existing = _tableOrders[tableKey].FirstOrDefault(s => s.ProductId == item.ProductId);
                    if (existing != null)
                        existing.Qty += item.Quantity;
                    else
                        _tableOrders[tableKey].Add(new SentItem(item.ProductId, item.ProductName, item.UnitPrice, item.Quantity));
                }
            }
        }
        catch { /* silently ignore — table orders will be empty */ }
    }

    // ═══ LOCALSTORAGE PERSISTENCE (cart + selected table only) ═══
    private string CartStorageKey => $"pos_cart_{ShopId}";
    private string SelectedTableStorageKey => $"pos_selected_table_{ShopId}";

    private async Task SaveStateToLocalStorage()
    {
        try
        {
            // Save cart items
            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));

            // Save selected table ID
            if (SelectedTable != null)
                await JS.InvokeVoidAsync("localStorage.setItem", SelectedTableStorageKey, SelectedTable.Id);
            else
                await JS.InvokeVoidAsync("localStorage.removeItem", SelectedTableStorageKey);
        }
        catch { /* localStorage may be unavailable */ }
    }

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

            // Restore selected table
            var savedTableId = await JS.InvokeAsync<string?>("localStorage.getItem", SelectedTableStorageKey);
            if (!string.IsNullOrEmpty(savedTableId))
            {
                SelectedTable = _tables.FirstOrDefault(t => t.Id == savedTableId);
                if (SelectedTable != null && _cartItems.Any())
                    _viewMode = ViewMode.Menu;
            }
        }
        catch { /* silently ignore corrupt localStorage */ }
    }

    private async Task ClearStateFromLocalStorage()
    {
        try
        {
            await JS.InvokeVoidAsync("localStorage.removeItem", CartStorageKey);
            await JS.InvokeVoidAsync("localStorage.removeItem", SelectedTableStorageKey);
        }
        catch { }
    }

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

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

    // ═══ MODELS ═══
    private record TableInfo(string Id, string Name, int Seats, string Status, string Section);
    private record Product(Guid Id, string Name, decimal Price, string Category);
    private class CartItem(Guid productId, string name, decimal price)
    {
        public Guid ProductId { get; } = productId;
        public string Name { get; } = name;
        public decimal Price { get; } = price;
        public int Qty { get; set; } = 1;
    }
    private class SentItem(Guid productId, string name, decimal price, int qty)
    {
        public Guid ProductId { get; } = productId;
        public string Name { get; } = name;
        public decimal Price { get; } = price;
        public int Qty { get; set; } = qty;
    }
}
