@*
    EN: Restaurant POS Tablet — Touch-optimized table map with order sidebar.
    VI: POS Nhà hàng Tablet — Sơ đồ bàn tối ưu cảm ứng với sidebar đặt món.
*@
@page "/pos/{ShopId:guid}/restaurant/tablet"
@layout PosLayout
@inherits PosBase
@inject WebClientTpos.Client.Services.PosDataService DataService

<div class="pos-product-panel" 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
    {
        @* ═══ SECTION FILTER / LỌC KHU VỰC ═══ *@
        <div class="pos-category-tabs">
            @foreach (var s in _sections)
            {
                <button class="pos-category-tab @(s == _activeSection ? "pos-category-tab--active" : "")"
                        style="padding:12px 20px;font-size:15px;"
                        @onclick="() => _activeSection = s">@s</button>
            }
        </div>

        @* ═══ TABLE MAP / SƠ ĐỒ BÀN ═══ *@
        <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:16px;padding:12px 0;">
            @foreach (var t in FilteredTables)
            {
                var effectiveStatus = GetEffectiveStatus(t);
                var hasReservation = GetTableReservation(t) is not null;
                <div @onclick="() => SelectTable(t)"
                     style="background:@StatusBg(effectiveStatus);border-radius:var(--pos-radius);padding:20px;
                            text-align:center;cursor:pointer;min-height:100px;display:flex;flex-direction:column;
                            align-items:center;justify-content:center;gap:6px;position:relative;
                            border:3px solid @(_selected?.Id == t.Id ? "var(--pos-orange-primary)" : "transparent");
                            transition:all .2s ease;">
                    <span style="font-size:22px;font-weight:700;">@t.Name</span>
                    <span style="font-size:13px;color:rgba(255,255,255,.65);">@t.Seats chỗ</span>
                    <span style="font-size:12px;font-weight:600;margin-top:4px;">@StatusLabel(effectiveStatus)</span>
                    @if (hasReservation)
                    {
                        var res = GetTableReservation(t)!;
                        <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(t))
                    {
                        <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(t))
                        </div>
                    }
                </div>
            }
        </div>
    }
</div>

@* ═══ ORDER SIDEBAR / SIDEBAR ĐẶT MÓN ═══ *@
<div class="pos-cart-panel" style="width:340px;min-width:340px;">
    @if (_selected is not null)
    {
        <div class="pos-cart-header">
            <span class="pos-cart-header__title">@_selected.Name — @_selected.Seats chỗ</span>
        </div>

        <div class="pos-cart-items">
            @if (HasPendingOrder(_selected))
            {
                @foreach (var item in _items)
                {
                    <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>
                        <span style="font-size:14px;font-weight:600;">x@item.Qty</span>
                    </div>
                }
            }
            else
            {
                <div style="text-align:center;padding:40px 16px;color:var(--pos-text-tertiary);">
                    Bàn trống — Chạm để tạo đơn
                </div>
            }
        </div>

        <div class="pos-cart-footer">
            <div class="pos-cart-total">
                <span class="pos-cart-total__label">Tổng</span>
                <span class="pos-cart-total__value">@FormatPrice(_items.Any() ? _items.Sum(i => i.Price * i.Qty) : 0)</span>
            </div>
            <button class="pos-btn-checkout" style="height:52px;font-size:16px;"
                    @onclick="@(() => NavigateTo("restaurant/waiter-pad"))">
                <i data-lucide="utensils"></i> Gọi món
            </button>
        </div>
    }
    else
    {
        <div style="flex:1;display:flex;align-items:center;justify-content:center;color:var(--pos-text-tertiary);font-size:15px;padding:20px;">
            Chọn bàn trên sơ đồ
        </div>
    }
</div>

@code {

    // EN: Loading state / VI: Trạng thái tải
    private bool _isLoading = true;
    private bool _loadError;

    // EN: Active section filter / VI: Bộ lọc khu vực
    private string _activeSection = "Tất cả";
    private string[] _sections = { "Tất cả" };

    // EN: Selected table reference / VI: Bàn đang chọn
    private TableInfo? _selected;

    // EN: Table data from API / VI: Dữ liệu bàn từ API
    private List<TableInfo> _tables = new();

    private IEnumerable<TableInfo> FilteredTables =>
        _activeSection == "Tất cả" ? _tables : _tables.Where(t => t.Section == _activeSection);

    // EN: Order items for selected table (from API) / VI: Món cho bàn đang chọn (từ API)
    private List<OrderItem> _items = new();

    // EN: All active table orders from API / VI: Tất cả đơn active từ API
    private Dictionary<string, List<OrderItem>> _tableOrderMap = new();

    // EN: Reservations / VI: Đặt bàn
    private List<WebClientTpos.Client.Services.PosDataService.ReservationInfo> _reservations = new();

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

        try
        {
            // EN: Load tables, active orders, and reservations in parallel / VI: Tải bàn, đơn active, và đặt bàn song song
            var tablesTask = DataService.GetTablesAsync(ShopId);
            var ordersTask = DataService.GetActiveTableOrdersAsync(ShopId);
            var reservationsTask = DataService.GetReservationsAsync(ShopId, DateTime.Today.ToString("yyyy-MM-dd"));
            await Task.WhenAll(tablesTask, ordersTask, reservationsTask);

            var apiTables = await tablesTask;
            var activeOrders = await ordersTask;
            _reservations = await reservationsTask;

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

            // EN: Build order map per table / VI: Tạo map đơn theo bàn
            foreach (var order in activeOrders)
            {
                if (order.TableId == null) continue;
                var tableKey = order.TableId.Value.ToString();
                if (!_tableOrderMap.ContainsKey(tableKey))
                    _tableOrderMap[tableKey] = new();
                foreach (var item in order.Items)
                {
                    var existing = _tableOrderMap[tableKey].FirstOrDefault(i => i.Name == item.ProductName);
                    if (existing != null)
                        existing.Qty += item.Quantity;
                    else
                        _tableOrderMap[tableKey].Add(new OrderItem(item.ProductName, item.UnitPrice, item.Quantity));
                }
            }

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

    private static string StatusBg(string s) => s switch
    {
        "available" => "rgba(34,197,94,.15)", "occupied" => "rgba(255,92,0,.18)",
        "reserved" => "rgba(59,130,246,.18)", _ => "var(--pos-bg-interactive)"
    };

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

    // EN: Select table and load its order items / VI: Chọn bàn và tải các món của bàn đó
    private void SelectTable(TableInfo table)
    {
        _selected = table;
        _items = _tableOrderMap.TryGetValue(table.Id, out var items) ? items : new();
    }

    // ═══ TABLE ORDER HELPERS (synced with Desktop) ═══
    private bool HasPendingOrder(TableInfo table) =>
        _tableOrderMap.ContainsKey(table.Id) && _tableOrderMap[table.Id].Any();

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

    // ═══ RESERVATION HELPERS (synced with Desktop) ═══
    private WebClientTpos.Client.Services.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;
    }

    private record TableInfo(string Id, string Name, int Seats, string Status, string Section);
    private class OrderItem(string name, decimal price, int qty)
    {
        public string Name { get; } = name;
        public decimal Price { get; } = price;
        public int Qty { get; set; } = qty;
    }
}
