@page "/admin/spa/appointments"
@layout AdminLayout
@inherits AdminBase
@inject PosDataService DataService
@inject IDialogService DialogService
@inject ISnackbar Snackbar
@using WebClientTpos.Client.Services
@using MudBlazor

@*
    EN: Appointment Calendar page — daily timeline view of spa/beauty appointments grouped by therapist.
    VI: Trang lich hen — hien thi lich hen spa/beauty theo ngay, nhom theo nhan vien tri lieu.
*@

<PageTitle>Lich hen — aPOS POS</PageTitle>

@* ═══ TOP BAR ═══ *@
<div class="admin-topbar">
    <div class="admin-topbar__left">
        <h1 class="admin-topbar__title">Lich hen</h1>
        <p class="admin-topbar__subtitle">Quan ly lich hen hang ngay cho nhan vien</p>
    </div>
    <div class="admin-topbar__right" style="display:flex;align-items:center;gap:12px;">
        <MudDatePicker @bind-Date="_selectedDate"
                       @bind-Date:after="OnDateChanged"
                       Label="Ngay"
                       Variant="Variant.Outlined"
                       DateFormat="dd/MM/yyyy"
                       Style="max-width:180px;"
                       Color="Color.Primary"
                       Class="mud-input-dark" />
        <MudButton Variant="Variant.Filled"
                   Color="Color.Primary"
                   OnClick="LoadAppointmentsAsync"
                   Disabled="_loading"
                   StartIcon="@Icons.Material.Filled.Refresh">
            @if (_loading)
            {
                <MudProgressCircular Size="Size.Small" Indeterminate="true" Color="Color.Surface" Class="mr-2" />
            }
            Tai lai
        </MudButton>
        <MudButton Variant="Variant.Filled"
                   Color="Color.Primary"
                   OnClick="OpenCreateAppointmentDialog"
                   StartIcon="@Icons.Material.Filled.Add">
            Dat lich moi
        </MudButton>
    </div>
</div>

@* ═══ CONTENT ═══ *@
<div class="admin-content" style="display:flex;flex-direction:column;gap:20px;">

    @if (_loading)
    {
        <div style="display:flex;justify-content:center;padding:48px;">
            <MudProgressCircular Size="Size.Large" Indeterminate="true" Color="Color.Primary" />
        </div>
    }
    else if (!_appointments.Any())
    {
        <MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Class="mb-4">
            Khong co lich hen nao trong ngay @(_selectedDate?.ToString("dd/MM/yyyy") ?? "hom nay"). Nhan "Dat lich moi" de tao lich hen.
        </MudAlert>
    }
    else
    {
        @* ── SUMMARY CARDS ── *@
        <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px;">
            <div class="admin-stat-card">
                <div class="admin-stat-card__content">
                    <span class="admin-stat-card__value">@_appointments.Count</span>
                    <span class="admin-stat-card__label">Tong lich hen</span>
                </div>
            </div>
            <div class="admin-stat-card">
                <div class="admin-stat-card__content">
                    <span class="admin-stat-card__value" style="color:#F59E0B;">@_appointments.Count(a => a.Status.Equals("Pending", StringComparison.OrdinalIgnoreCase))</span>
                    <span class="admin-stat-card__label">Cho xac nhan</span>
                </div>
            </div>
            <div class="admin-stat-card">
                <div class="admin-stat-card__content">
                    <span class="admin-stat-card__value" style="color:#3B82F6;">@_appointments.Count(a => a.Status.Equals("Confirmed", StringComparison.OrdinalIgnoreCase))</span>
                    <span class="admin-stat-card__label">Da xac nhan</span>
                </div>
            </div>
            <div class="admin-stat-card">
                <div class="admin-stat-card__content">
                    <span class="admin-stat-card__value" style="color:#22C55E;">@_appointments.Count(a => a.Status.Equals("InProgress", StringComparison.OrdinalIgnoreCase) || a.Status.Equals("Completed", StringComparison.OrdinalIgnoreCase))</span>
                    <span class="admin-stat-card__label">Dang/Da hoan thanh</span>
                </div>
            </div>
        </div>

        @* ── APPOINTMENTS GROUPED BY THERAPIST ── *@
        @foreach (var group in GroupedAppointments)
        {
            <div class="admin-panel">
                <div class="admin-panel__header" style="display:flex;align-items:center;gap:10px;">
                    <div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg, #FF5C00 0%, #FF8A3D 100%);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;color:#fff;flex-shrink:0;">
                        @GetInitials(group.Key)
                    </div>
                    <h3 class="admin-panel__title" style="margin:0;">@group.Key</h3>
                    <MudChip T="string" Size="Size.Small" Variant="Variant.Outlined" Color="Color.Default"
                             Style="font-size:11px;margin-left:auto;">@group.Count() lich hen</MudChip>
                </div>
                <div class="admin-panel__body" style="padding:0;">
                    @foreach (var appt in group.OrderBy(a => a.StartTime))
                    {
                        <div style="display:flex;align-items:center;gap:16px;padding:14px 20px;border-bottom:1px solid var(--admin-border-subtle);">
                            @* Time *@
                            <div style="min-width:100px;text-align:center;">
                                <div style="font-size:14px;font-weight:700;color:var(--admin-text-primary);">
                                    @appt.StartTime.ToString("HH:mm")
                                </div>
                                <div style="font-size:11px;color:var(--admin-text-tertiary);">
                                    @appt.EndTime.ToString("HH:mm")
                                </div>
                            </div>

                            @* Info *@
                            <div style="flex:1;min-width:0;">
                                <div style="font-weight:600;font-size:14px;color:var(--admin-text-primary);">
                                    @(appt.ServiceName ?? "Dich vu")
                                </div>
                                <div style="font-size:12px;color:var(--admin-text-secondary);margin-top:2px;">
                                    @if (!string.IsNullOrEmpty(appt.CustomerName))
                                    {
                                        <span><i data-lucide="user" style="width:12px;height:12px;display:inline;vertical-align:middle;margin-right:4px;"></i>@appt.CustomerName</span>
                                    }
                                    @if (!string.IsNullOrEmpty(appt.Notes))
                                    {
                                        <span style="margin-left:12px;"><i data-lucide="message-square" style="width:12px;height:12px;display:inline;vertical-align:middle;margin-right:4px;"></i>@appt.Notes</span>
                                    }
                                </div>
                            </div>

                            @* Status Badge *@
                            <div style="min-width:110px;text-align:center;">
                                <MudChip T="string"
                                         Size="Size.Small"
                                         Variant="Variant.Filled"
                                         Style="@GetStatusChipStyle(appt.Status)"
                                         >@GetStatusLabel(appt.Status)</MudChip>
                            </div>

                            @* Actions *@
                            <div style="display:flex;gap:4px;flex-shrink:0;">
                                @if (appt.Status.Equals("Pending", StringComparison.OrdinalIgnoreCase))
                                {
                                    <MudButton Size="Size.Small" Variant="Variant.Outlined" Color="Color.Info"
                                               OnClick="@(() => UpdateStatusAsync(appt.Id, "confirm"))"
                                               Style="font-size:11px;min-width:0;padding:4px 8px;">
                                        Xac nhan
                                    </MudButton>
                                }
                                @if (appt.Status.Equals("Confirmed", StringComparison.OrdinalIgnoreCase))
                                {
                                    <MudButton Size="Size.Small" Variant="Variant.Outlined" Color="Color.Success"
                                               OnClick="@(() => UpdateStatusAsync(appt.Id, "start"))"
                                               Style="font-size:11px;min-width:0;padding:4px 8px;">
                                        Bat dau
                                    </MudButton>
                                }
                                @if (appt.Status.Equals("InProgress", StringComparison.OrdinalIgnoreCase))
                                {
                                    <MudButton Size="Size.Small" Variant="Variant.Outlined" Color="Color.Success"
                                               OnClick="@(() => UpdateStatusAsync(appt.Id, "complete"))"
                                               Style="font-size:11px;min-width:0;padding:4px 8px;">
                                        Hoan thanh
                                    </MudButton>
                                }
                                @if (!appt.Status.Equals("Completed", StringComparison.OrdinalIgnoreCase)
                                     && !appt.Status.Equals("Cancelled", StringComparison.OrdinalIgnoreCase)
                                     && !appt.Status.Equals("NoShow", StringComparison.OrdinalIgnoreCase))
                                {
                                    <MudIconButton Icon="@Icons.Material.Filled.PersonOff"
                                                   Size="Size.Small"
                                                   Color="Color.Dark"
                                                   OnClick="@(() => UpdateStatusAsync(appt.Id, "noshow"))"
                                                   Title="Vang mat" />
                                    <MudIconButton Icon="@Icons.Material.Filled.Cancel"
                                                   Size="Size.Small"
                                                   Color="Color.Error"
                                                   OnClick="@(() => OpenCancelDialog(appt))"
                                                   Title="Huy lich" />
                                }
                            </div>
                        </div>
                    }
                </div>
            </div>
        }
    }
</div>

@* ═══ CANCEL DIALOG ═══ *@
<MudDialog @bind-Visible="_cancelDialogVisible" Options="_smallDialogOptions">
    <TitleContent>
        <MudText Typo="Typo.h6">Huy lich hen</MudText>
    </TitleContent>
    <DialogContent>
        <MudText Typo="Typo.body2" Class="mb-3" Style="color:var(--admin-text-secondary);">
            Vui long nhap ly do huy lich hen nay.
        </MudText>
        <MudTextField @bind-Value="_cancelReason"
                      Label="Ly do huy"
                      Variant="Variant.Outlined"
                      Lines="3"
                      Required="true"
                      RequiredError="Vui long nhap ly do" />
    </DialogContent>
    <DialogActions>
        <MudButton OnClick="@(() => _cancelDialogVisible = false)" Variant="Variant.Text">Quay lai</MudButton>
        <MudButton OnClick="ConfirmCancelAsync"
                   Variant="Variant.Filled"
                   Color="Color.Error"
                   Disabled="@(string.IsNullOrWhiteSpace(_cancelReason) || _saving)">
            @if (_saving)
            {
                <MudProgressCircular Size="Size.Small" Indeterminate="true" Color="Color.Surface" Class="mr-2" />
            }
            Xac nhan huy
        </MudButton>
    </DialogActions>
</MudDialog>

@* ═══ CREATE APPOINTMENT DIALOG ═══ *@
<MudDialog @bind-Visible="_createDialogVisible" Options="_dialogOptions">
    <TitleContent>
        <MudText Typo="Typo.h6">Dat lich moi</MudText>
    </TitleContent>
    <DialogContent>
        <MudForm @ref="_createForm">
            <MudSelect T="Guid?" @bind-Value="_newApptTherapistId"
                       Label="Nhan vien"
                       Variant="Variant.Outlined"
                       AnchorOrigin="Origin.BottomCenter"
                       Class="mb-3">
                <MudSelectItem T="Guid?" Value="@((Guid?)null)">-- Chua chon --</MudSelectItem>
                @foreach (var t in _therapists.Where(t => t.IsActive))
                {
                    <MudSelectItem T="Guid?" Value="@((Guid?)t.Id)">@t.Name</MudSelectItem>
                }
            </MudSelect>

            <MudTextField @bind-Value="_newApptServiceName"
                          Label="Dich vu"
                          Required="true"
                          RequiredError="Vui long nhap ten dich vu"
                          Variant="Variant.Outlined"
                          Class="mb-3" />

            <MudTextField @bind-Value="_newApptCustomerName"
                          Label="Ten khach hang"
                          Variant="Variant.Outlined"
                          Class="mb-3" />

            <div style="display:flex;gap:12px;">
                <MudTimePicker @bind-Time="_newApptStartTime"
                               Label="Gio bat dau"
                               Variant="Variant.Outlined"
                               Class="mb-3"
                               Style="flex:1;" />
                <MudTimePicker @bind-Time="_newApptEndTime"
                               Label="Gio ket thuc"
                               Variant="Variant.Outlined"
                               Class="mb-3"
                               Style="flex:1;" />
            </div>

            <MudTextField @bind-Value="_newApptNotes"
                          Label="Ghi chu"
                          Variant="Variant.Outlined"
                          Lines="2"
                          Class="mb-3" />
        </MudForm>
    </DialogContent>
    <DialogActions>
        <MudButton OnClick="@(() => _createDialogVisible = false)" Variant="Variant.Text">Huy</MudButton>
        <MudButton OnClick="CreateAppointmentAsync"
                   Variant="Variant.Filled"
                   Color="Color.Primary"
                   Disabled="_saving">
            @if (_saving)
            {
                <MudProgressCircular Size="Size.Small" Indeterminate="true" Color="Color.Surface" Class="mr-2" />
            }
            Dat lich
        </MudButton>
    </DialogActions>
</MudDialog>

@code {
    // EN: Page state / VI: Trang thai trang
    private bool _loading = true;
    private bool _saving = false;
    private DateTime? _selectedDate = DateTime.Today;
    private List<PosDataService.AppointmentInfo> _appointments = new();
    private List<PosDataService.TherapistInfo> _therapists = new();

    // EN: Cancel dialog / VI: Dialog huy
    private bool _cancelDialogVisible = false;
    private Guid? _cancellingApptId;
    private string _cancelReason = string.Empty;

    // EN: Create dialog / VI: Dialog tao moi
    private bool _createDialogVisible = false;
    private MudForm? _createForm;
    private Guid? _newApptTherapistId;
    private string _newApptServiceName = string.Empty;
    private string _newApptCustomerName = string.Empty;
    private TimeSpan? _newApptStartTime = new TimeSpan(9, 0, 0);
    private TimeSpan? _newApptEndTime = new TimeSpan(10, 0, 0);
    private string _newApptNotes = string.Empty;

    private static readonly DialogOptions _dialogOptions = new()
    {
        MaxWidth = MaxWidth.Small,
        FullWidth = true,
        CloseOnEscapeKey = true
    };

    private static readonly DialogOptions _smallDialogOptions = new()
    {
        MaxWidth = MaxWidth.ExtraSmall,
        FullWidth = true,
        CloseOnEscapeKey = true
    };

    // EN: Group appointments by therapist name / VI: Nhom lich hen theo ten nhan vien
    private IEnumerable<IGrouping<string, PosDataService.AppointmentInfo>> GroupedAppointments =>
        _appointments
            .GroupBy(a => a.TherapistName ?? "Chua phan cong")
            .OrderBy(g => g.Key);

    /// <summary>
    /// EN: Get the current shop ID from query string.
    /// VI: Lay shop ID tu query string.
    /// </summary>
    private Guid? GetCurrentShopId()
    {
        var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
        var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
        if (Guid.TryParse(query["shopId"], out var qsShopId))
            return qsShopId;
        return null;
    }

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

    /// <summary>
    /// EN: Load appointments and therapists in parallel.
    /// VI: Tai lich hen va nhan vien dong thoi.
    /// </summary>
    private async Task LoadDataAsync()
    {
        var shopId = GetCurrentShopId();
        if (!shopId.HasValue)
        {
            Snackbar.Add("Vui long chon shop truoc.", Severity.Warning);
            _loading = false;
            return;
        }

        _loading = true;
        StateHasChanged();

        try
        {
            var date = _selectedDate ?? DateTime.Today;
            var apptTask = DataService.GetAppointmentsByDateAsync(shopId.Value, date);
            var therapistTask = DataService.GetTherapistsAsync(shopId.Value);

            await Task.WhenAll(apptTask, therapistTask);

            _appointments = apptTask.Result;
            _therapists = therapistTask.Result;
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Loi tai du lieu: {ex.Message}", Severity.Error);
            _appointments = new();
            _therapists = new();
        }
        finally
        {
            _loading = false;
            StateHasChanged();
        }
    }

    private async Task LoadAppointmentsAsync()
    {
        await LoadDataAsync();
    }

    private async Task OnDateChanged()
    {
        await LoadDataAsync();
    }

    // ═══ STATUS ACTIONS ═══

    /// <summary>
    /// EN: Update appointment status (confirm/start/complete/noshow).
    /// VI: Cap nhat trang thai lich hen (xac nhan/bat dau/hoan thanh/vang mat).
    /// </summary>
    private async Task UpdateStatusAsync(Guid appointmentId, string action)
    {
        try
        {
            var success = await DataService.UpdateAppointmentStatusAsync(appointmentId, action);
            if (success)
            {
                var label = action switch
                {
                    "confirm" => "Da xac nhan",
                    "start" => "Da bat dau",
                    "complete" => "Da hoan thanh",
                    "noshow" => "Da danh dau vang mat",
                    _ => "Da cap nhat"
                };
                Snackbar.Add($"{label} lich hen.", Severity.Success);
                await LoadAppointmentsAsync();
            }
            else
            {
                Snackbar.Add("Cap nhat trang thai that bai.", Severity.Error);
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Loi: {ex.Message}", Severity.Error);
        }
    }

    // ═══ CANCEL FLOW ═══

    private void OpenCancelDialog(PosDataService.AppointmentInfo appt)
    {
        _cancellingApptId = appt.Id;
        _cancelReason = string.Empty;
        _cancelDialogVisible = true;
    }

    private async Task ConfirmCancelAsync()
    {
        if (!_cancellingApptId.HasValue || string.IsNullOrWhiteSpace(_cancelReason)) return;

        _saving = true;
        StateHasChanged();

        try
        {
            var success = await DataService.CancelAppointmentWithReasonAsync(_cancellingApptId.Value, _cancelReason.Trim());
            if (success)
            {
                Snackbar.Add("Da huy lich hen.", Severity.Success);
                _cancelDialogVisible = false;
                await LoadAppointmentsAsync();
            }
            else
            {
                Snackbar.Add("Huy lich hen that bai.", Severity.Error);
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Loi: {ex.Message}", Severity.Error);
        }
        finally
        {
            _saving = false;
            StateHasChanged();
        }
    }

    // ═══ CREATE APPOINTMENT ═══

    private void OpenCreateAppointmentDialog()
    {
        _newApptTherapistId = null;
        _newApptServiceName = string.Empty;
        _newApptCustomerName = string.Empty;
        _newApptStartTime = new TimeSpan(9, 0, 0);
        _newApptEndTime = new TimeSpan(10, 0, 0);
        _newApptNotes = string.Empty;
        _createDialogVisible = true;
    }

    private async Task CreateAppointmentAsync()
    {
        if (_createForm != null)
        {
            await _createForm.Validate();
            if (!_createForm.IsValid) return;
        }

        if (string.IsNullOrWhiteSpace(_newApptServiceName))
        {
            Snackbar.Add("Vui long nhap ten dich vu.", Severity.Warning);
            return;
        }

        var shopId = GetCurrentShopId();
        if (!shopId.HasValue)
        {
            Snackbar.Add("Vui long chon shop truoc.", Severity.Warning);
            return;
        }

        if (!_newApptStartTime.HasValue || !_newApptEndTime.HasValue)
        {
            Snackbar.Add("Vui long chon gio bat dau va ket thuc.", Severity.Warning);
            return;
        }

        _saving = true;
        StateHasChanged();

        try
        {
            var date = _selectedDate ?? DateTime.Today;
            var startTime = date.Add(_newApptStartTime.Value);
            var endTime = date.Add(_newApptEndTime.Value);

            var req = new PosDataService.CreateAppointmentRequest(
                ShopId: shopId.Value,
                CustomerId: null,
                StaffId: _newApptTherapistId,
                ResourceId: null,
                ServiceId: null,
                StartTime: startTime,
                EndTime: endTime,
                Status: "Pending"
            );

            var success = await DataService.CreateAppointmentAsync(req);
            if (success)
            {
                Snackbar.Add("Da dat lich hen moi.", Severity.Success);
                _createDialogVisible = false;
                await LoadAppointmentsAsync();
            }
            else
            {
                Snackbar.Add("Dat lich that bai. Vui long thu lai.", Severity.Error);
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Loi: {ex.Message}", Severity.Error);
        }
        finally
        {
            _saving = false;
            StateHasChanged();
        }
    }

    // ═══ HELPERS ═══

    /// <summary>
    /// EN: Get Vietnamese status label.
    /// VI: Lay nhan trang thai tieng Viet.
    /// </summary>
    private static string GetStatusLabel(string status) => status.ToLowerInvariant() switch
    {
        "pending" => "Cho xac nhan",
        "confirmed" => "Da xac nhan",
        "inprogress" => "Dang thuc hien",
        "completed" => "Hoan thanh",
        "cancelled" => "Da huy",
        "noshow" => "Vang mat",
        _ => status
    };

    /// <summary>
    /// EN: Get inline style for status chip based on status value.
    /// VI: Lay style inline cho chip trang thai dua tren gia tri trang thai.
    /// </summary>
    private static string GetStatusChipStyle(string status) => status.ToLowerInvariant() switch
    {
        "pending" => "background:rgba(245,158,11,0.15);color:#F59E0B;font-size:11px;",
        "confirmed" => "background:rgba(59,130,246,0.15);color:#3B82F6;font-size:11px;",
        "inprogress" => "background:rgba(34,197,94,0.15);color:#22C55E;font-size:11px;",
        "completed" => "background:rgba(156,163,175,0.15);color:#9CA3AF;font-size:11px;",
        "cancelled" => "background:rgba(239,68,68,0.15);color:#EF4444;font-size:11px;",
        "noshow" => "background:rgba(107,114,128,0.25);color:#6B7280;font-size:11px;",
        _ => "font-size:11px;"
    };

    private static string GetInitials(string name)
    {
        if (string.IsNullOrWhiteSpace(name)) return "??";
        var parts = name.Split(' ', StringSplitOptions.RemoveEmptyEntries);
        if (parts.Length >= 2)
            return $"{parts[0][0]}{parts[^1][0]}".ToUpper();
        return name[..Math.Min(2, name.Length)].ToUpper();
    }
}
