@*
    EN: Course Timing — Multi-course meal timing management with fire buttons and timeline.
        Connected to kitchen tickets API for real course data and status updates.
    VI: Quan ly thoi gian course — Quan ly thoi gian tiec nhieu mon voi nut fire va timeline.
        Ket noi API kitchen tickets cho du lieu course thuc va cap nhat trang thai.
*@
@page "/pos/{ShopId:guid}/restaurant/course-timing/{OrderId:guid}"
@page "/pos/{ShopId:guid}/restaurant/course-timing"
@layout PosLayout
@inherits PosBase
@using WebClientTpos.Client.Services
@inject PosDataService DataService
@implements IDisposable

<div style="flex:1;display:flex;flex-direction:column;overflow:hidden;">
    @* ═══ HEADER / TIEU DE ═══ *@
    <div style="padding:12px 16px;border-bottom:1px solid var(--pos-border-subtle);display:flex;align-items:center;gap:12px;">
        <button class="pos-category-tab" @onclick="@(() => NavigateTo("restaurant"))">
            <i data-lucide="arrow-left" style="width:14px;"></i> Quay lai
        </button>
        <span style="font-size:16px;font-weight:700;">
            <i data-lucide="timer" style="width:18px;height:18px;display:inline;"></i>
            @(_headerTitle)
        </span>
        <span style="flex:1;"></span>
        <span style="font-size:12px;color:var(--pos-text-tertiary);">
            <i data-lucide="clock" style="width:12px;height:12px;display:inline;"></i> Bat dau: @(_startTime?.ToString("HH:mm") ?? "--:--")
        </span>
    </div>

    @if (_isLoading)
    {
        <div style="flex:1;display:flex;align-items:center;justify-content:center;color:var(--pos-text-tertiary);">
            Dang tai...
        </div>
    }
    else if (_loadError)
    {
        <div style="flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;color:var(--pos-text-tertiary);">
            <span>Khong the tai du lieu</span>
            <button style="padding:8px 16px;border-radius:8px;border:none;background:var(--pos-orange-primary);color:#fff;cursor:pointer;"
                    @onclick="async () => await LoadDataAsync()">Thu lai</button>
        </div>
    }
    else
    {
    @* ═══ AUTO-FIRE RULE / QUY TAC TU DONG ═══ *@
    <div style="padding:10px 16px;border-bottom:1px solid var(--pos-border-subtle);">
        <div style="background:rgba(59,130,246,.1);border:1px solid rgba(59,130,246,.3);border-radius:8px;padding:10px 14px;
                    display:flex;align-items:center;gap:8px;">
            <i data-lucide="zap" style="width:14px;height:14px;color:var(--pos-info);"></i>
            <span style="font-size:12px;color:var(--pos-info);font-weight:600;">Tu dong: Phuc vu moi mon cach 15 phut</span>
        </div>
    </div>

    @* ═══ COURSE LIST / DANH SACH COURSE ═══ *@
    <div style="flex:1;overflow-y:auto;padding:16px;">
        <div style="display:flex;flex-direction:column;gap:12px;">
            @foreach (var course in _courses)
            {
                var statusColor = CourseStatusColor(course.Status);
                var statusLabel = CourseStatusLabel(course.Status);

                <div style="background:var(--pos-bg-elevated);border-radius:var(--pos-radius);padding:16px;
                            border-left:4px solid @statusColor;">
                    @* EN: Course header / VI: Tieu de course *@
                    <div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
                        <div style="width:36px;height:36px;border-radius:50%;background:@CourseStatusBg(course.Status);
                                    display:flex;align-items:center;justify-content:center;">
                            <i data-lucide="@course.Icon" style="width:16px;height:16px;color:@statusColor;"></i>
                        </div>
                        <div style="flex:1;">
                            <div style="font-size:14px;font-weight:700;">@course.Name</div>
                            <div style="font-size:12px;color:var(--pos-text-tertiary);">@course.Items</div>
                        </div>
                        <div style="text-align:right;">
                            <span style="font-size:12px;font-weight:600;padding:4px 10px;border-radius:6px;
                                        background:@CourseStatusBg(course.Status);color:@statusColor;">
                                @statusLabel
                            </span>
                        </div>
                    </div>

                    @* EN: Timeline bar / VI: Thanh thoi gian *@
                    <div style="margin-bottom:10px;">
                        <div style="display:flex;justify-content:space-between;font-size:11px;color:var(--pos-text-tertiary);margin-bottom:4px;">
                            <span>@course.EstTime phut</span>
                            <span>@course.Progress%</span>
                        </div>
                        <div style="height:6px;border-radius:3px;background:var(--pos-bg-interactive);overflow:hidden;">
                            <div style="height:100%;width:@(course.Progress)%;border-radius:3px;background:@statusColor;
                                        transition:width .3s ease;"></div>
                        </div>
                    </div>

                    @* EN: Fire button / VI: Nut kich hoat *@
                    @if (course.Status == "queued")
                    {
                        <button style="width:100%;padding:8px;border-radius:8px;border:1px solid @statusColor;
                                       background:@CourseStatusBg(course.Status);color:@statusColor;font-size:13px;font-weight:600;cursor:pointer;"
                                disabled="@course.IsUpdating"
                                @onclick="() => FireCourse(course)">
                            @if (course.IsUpdating)
                            {
                                <span>Dang xu ly...</span>
                            }
                            else
                            {
                                <i data-lucide="flame" style="width:14px;height:14px;display:inline;"></i>
                                <span>Fire — Bat dau nau</span>
                            }
                        </button>
                    }
                    else if (course.Status == "cooking")
                    {
                        <button style="width:100%;padding:8px;border-radius:8px;border:none;
                                       background:rgba(34,197,94,.15);color:var(--pos-success);font-size:13px;font-weight:600;cursor:pointer;"
                                disabled="@course.IsUpdating"
                                @onclick="() => ServeCourse(course)">
                            @if (course.IsUpdating)
                            {
                                <span>Dang xu ly...</span>
                            }
                            else
                            {
                                <i data-lucide="check" style="width:14px;height:14px;display:inline;"></i>
                                <span>Da phuc vu</span>
                            }
                        </button>
                    }
                </div>
            }
        </div>
    </div>

    @* ═══ FOOTER STATS / THONG KE ═══ *@
    <div style="padding:10px 16px;border-top:1px solid var(--pos-border-subtle);display:flex;gap:20px;font-size:12px;color:var(--pos-text-secondary);">
        <span style="color:var(--pos-success);">Da phuc vu: @_courses.Count(c => c.Status == "served")</span>
        <span style="color:var(--pos-warning);">Dang nau: @_courses.Count(c => c.Status == "cooking")</span>
        <span style="color:var(--pos-text-tertiary);">Cho: @_courses.Count(c => c.Status == "queued")</span>
        <span style="margin-left:auto;font-weight:600;">Tong: @_courses.Count course</span>
    </div>
    }
</div>

@code {
    // EN: Optional route parameter for specific order / VI: Tham so route tuy chon cho don cu the
    [Parameter] public Guid OrderId { get; set; }

    // EN: Loading & error states / VI: Trang thai tai & loi
    private bool _isLoading = true;
    private bool _loadError;

    // EN: Auto-refresh timer (5 seconds) / VI: Timer tu dong refresh (5 giay)
    private Timer? _refreshTimer;

    // EN: Header info / VI: Thong tin tieu de
    private string _headerTitle = "Quan ly course";
    private DateTime? _startTime;

    // EN: Course list from API / VI: Danh sach course tu API
    private readonly List<CourseInfo> _courses = new();

    // EN: Ticket ID mapping for API calls / VI: Anh xa ID ticket cho API call
    private readonly Dictionary<string, List<PosDataService.KitchenTicketInfo>> _courseTicketMap = new();

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

        // EN: Start auto-refresh timer / VI: Bat dau timer tu dong refresh
        _refreshTimer = new Timer(async _ =>
        {
            await InvokeAsync(async () =>
            {
                await LoadDataAsync(silent: true);
                StateHasChanged();
            });
        }, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
    }

    private async Task LoadDataAsync(bool silent = false)
    {
        if (!silent) { _isLoading = true; _loadError = false; }

        try
        {
            // EN: Fetch all kitchen tickets / VI: Lay tat ca kitchen tickets
            var pendingTask = DataService.GetKitchenTicketsAsync(ShopId, "Pending");
            var inProgressTask = DataService.GetKitchenTicketsAsync(ShopId, "InProgress");
            var completedTask = DataService.GetKitchenTicketsAsync(ShopId, "Completed");
            await Task.WhenAll(pendingTask, inProgressTask, completedTask);

            var allTickets = (await pendingTask).Concat(await inProgressTask).Concat(await completedTask).ToList();

            // EN: Filter by order if OrderId provided / VI: Loc theo don neu co OrderId
            if (OrderId != Guid.Empty)
            {
                // EN: Try to match tickets by loading order detail
                // VI: Thu khop tickets bang cach tai chi tiet don
                var orderDetail = await DataService.GetOrderDetailAsync(OrderId, ShopId);
                if (orderDetail?.Items != null)
                {
                    var orderItemIds = orderDetail.Items.Select(i => i.Id).ToHashSet();
                    var orderItemNames = orderDetail.Items.Select(i => i.ProductName).Where(n => n != null).ToHashSet();
                    allTickets = allTickets.Where(t => orderItemIds.Contains(t.OrderItemId) || orderItemNames.Contains(t.ItemName)).ToList();
                    _headerTitle = $"Don #{OrderId.ToString()[..6].ToUpper()} — {orderDetail.Items.Count} mon";
                }
            }
            else
            {
                _headerTitle = $"Tat ca — {allTickets.Count} ticket";
            }

            if (allTickets.Any())
            {
                _startTime = allTickets.Min(t => t.CreatedAt);
            }

            // EN: Group tickets by station/category, or by creation time if no station
            // VI: Nhom tickets theo station/danh muc, hoac theo thoi gian tao neu khong co station
            BuildCourses(allTickets);
        }
        catch
        {
            if (!silent) _loadError = true;
        }
        finally
        {
            if (!silent) _isLoading = false;
        }
    }

    private void BuildCourses(List<PosDataService.KitchenTicketInfo> tickets)
    {
        if (!tickets.Any()) return;

        // EN: Group by station if available, otherwise group by time batches (15 min intervals)
        // VI: Nhom theo station neu co, neu khong nhom theo dot thoi gian (moi 15 phut)
        var groups = tickets
            .GroupBy(t => !string.IsNullOrEmpty(t.Station) ? t.Station : $"Course {((t.CreatedAt - tickets.Min(x => x.CreatedAt)).TotalMinutes / 15) + 1:F0}")
            .ToList();

        _courses.Clear();
        _courseTicketMap.Clear();

        var icons = new[] { "salad", "soup", "beef", "carrot", "ice-cream-cone", "utensils", "fish", "egg" };
        int iconIdx = 0;

        foreach (var group in groups)
        {
            var groupTickets = group.ToList();
            var itemNames = string.Join(", ", groupTickets.Select(t => t.ItemName).Distinct().Take(3));
            if (groupTickets.Count > 3) itemNames += $" (+{groupTickets.Count - 3})";

            // EN: Determine course status from ticket statuses
            // VI: Xac dinh trang thai course tu trang thai ticket
            string status;
            int progress;
            if (groupTickets.All(t => t.Status == "Completed"))
            {
                status = "served";
                progress = 100;
            }
            else if (groupTickets.Any(t => t.Status is "InProgress" or "Completed"))
            {
                status = "cooking";
                var completedCount = groupTickets.Count(t => t.Status == "Completed");
                progress = groupTickets.Count > 0 ? (completedCount * 100 / groupTickets.Count) : 0;
                progress = Math.Max(progress, 20); // EN: At least 20% if cooking / VI: It nhat 20% neu dang nau
            }
            else
            {
                status = "queued";
                progress = 0;
            }

            var courseKey = group.Key;
            var estTime = groupTickets.Count * 5; // EN: Estimate 5 min per item / VI: Uoc tinh 5 phut moi mon

            // EN: Preserve existing course if it exists (to keep IsUpdating state)
            // VI: Giu course hien tai neu ton tai (de giu trang thai IsUpdating)
            var existing = _courses.FirstOrDefault(c => c.Key == courseKey);
            if (existing != null)
            {
                existing.Status = status;
                existing.Progress = progress;
                existing.Items = itemNames;
            }
            else
            {
                _courses.Add(new CourseInfo(courseKey, group.Key, itemNames, icons[iconIdx % icons.Length], estTime, status, progress));
            }

            _courseTicketMap[courseKey] = groupTickets;
            iconIdx++;
        }

        // EN: Remove courses that no longer exist / VI: Xoa course khong con ton tai
        _courses.RemoveAll(c => !_courseTicketMap.ContainsKey(c.Key));
    }

    private async void FireCourse(CourseInfo course)
    {
        if (!_courseTicketMap.TryGetValue(course.Key, out var tickets)) return;

        course.IsUpdating = true;
        StateHasChanged();

        try
        {
            // EN: Update all pending tickets in this course to InProgress
            // VI: Cap nhat tat ca ticket cho trong course nay sang InProgress
            var pendingTickets = tickets.Where(t => t.Status == "Pending").ToList();
            var tasks = pendingTickets.Select(t =>
                DataService.UpdateTicketStatusAsync(t.Id, new PosDataService.UpdateTicketStatusRequest("InProgress"))
            );
            await Task.WhenAll(tasks);

            course.Status = "cooking";
            course.Progress = 20;
        }
        catch
        {
            // EN: Fallback — update locally / VI: Du phong — cap nhat cuc bo
            course.Status = "cooking";
            course.Progress = 20;
        }
        finally
        {
            course.IsUpdating = false;
            StateHasChanged();
        }
    }

    private async void ServeCourse(CourseInfo course)
    {
        if (!_courseTicketMap.TryGetValue(course.Key, out var tickets)) return;

        course.IsUpdating = true;
        StateHasChanged();

        try
        {
            // EN: Update all tickets in this course to Completed
            // VI: Cap nhat tat ca ticket trong course nay sang Completed
            var nonCompletedTickets = tickets.Where(t => t.Status != "Completed").ToList();
            var tasks = nonCompletedTickets.Select(t =>
                DataService.UpdateTicketStatusAsync(t.Id, new PosDataService.UpdateTicketStatusRequest("Completed"))
            );
            await Task.WhenAll(tasks);

            course.Status = "served";
            course.Progress = 100;
        }
        catch
        {
            // EN: Fallback — update locally / VI: Du phong — cap nhat cuc bo
            course.Status = "served";
            course.Progress = 100;
        }
        finally
        {
            course.IsUpdating = false;
            StateHasChanged();
        }
    }

    private static string CourseStatusColor(string s) => s switch
    {
        "served" => "var(--pos-success)", "cooking" => "var(--pos-warning)",
        "queued" => "var(--pos-text-tertiary)", _ => "var(--pos-text-tertiary)"
    };

    private static string CourseStatusBg(string s) => s switch
    {
        "served" => "rgba(34,197,94,.15)", "cooking" => "rgba(245,158,11,.15)",
        "queued" => "var(--pos-bg-interactive)", _ => "var(--pos-bg-interactive)"
    };

    private static string CourseStatusLabel(string s) => s switch
    {
        "served" => "Da phuc vu", "cooking" => "Dang nau", "queued" => "Cho", _ => s
    };

    public void Dispose()
    {
        _refreshTimer?.Dispose();
    }

    private class CourseInfo(string key, string name, string items, string icon, int estTime, string status, int progress)
    {
        public string Key { get; set; } = key;
        public string Name { get; set; } = name;
        public string Items { get; set; } = items;
        public string Icon { get; set; } = icon;
        public int EstTime { get; set; } = estTime;
        public string Status { get; set; } = status;
        public int Progress { get; set; } = progress;
        public bool IsUpdating { get; set; }
    }
}
