@rendermode InteractiveServer
@attribute [Authorize]

@using Microsoft.AspNetCore.Authorization
@using MudBlazor
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Identity
@using Microsoft.AspNetCore.Components
@using OpenIddict.Abstractions
@using RobotNet.IdentityServer.Data
@using Microsoft.EntityFrameworkCore
@using System.Threading
@using static OpenIddict.Abstractions.OpenIddictConstants

@inherits LayoutComponentBase

@inject AuthenticationStateProvider AuthenticationStateProvider
@inject ISnackbar Snackbar
@inject IDialogService DialogService
@inject NavigationManager NavigationManager
@inject IOpenIddictApplicationManager ApplicationManager
@inject IOpenIddictScopeManager ScopeManager

<MudDialogProvider />
<MudSnackbarProvider />

<MudContainer MaxWidth="MaxWidth.ExtraLarge" Style="padding: 1rem;">
    <div class="header-gradient">
        <div class="header-content">
            <div style="display: flex; align-items: center;">
                <MudStack Spacing="1">
                    <div style="display: flex; align-items: center;">
                        <MudIcon Icon="@Icons.Material.Filled.Security" Class="scope-icon" />
                        <MudText Typo="Typo.h4" Style="padding-right:2px; font-weight: 700;">
                            OpenIddict Scopes
                        </MudText>
                    </div>
                    <div>
                        <MudText Typo="Typo.subtitle2" Style="opacity: 0.7; ">
                            Quản lý phạm vi truy cập OAuth2 & OpenID Connect
                        </MudText>
                    </div>
                </MudStack>
            </div>
            <div class="stats-badge">
                <MudIcon Icon="@Icons.Material.Filled.Dataset" Style="margin-right: 0.5rem;" />
                <MudText Typo="Typo.body1" Style="font-weight: 600;">
                    @filteredScopes.Count Scopes
                </MudText>
            </div>
        </div>
    </div>

    <div class="scope-card">
        <div style="padding: 1.5rem; border-bottom: 1px solid #e2e8f0; background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <MudText Typo="Typo.h6" Style="margin: 0; color: #334155; font-weight: 600;">
                    Danh sách Scopes
                </MudText>
                <div style="display: flex; gap: 1rem; align-items: center;">
                    <MudButton Variant="Variant.Outlined"
                               StartIcon="@Icons.Material.Filled.Refresh"
                               OnClick="@(() => RefreshScopesAsync())"
                               Style="text-transform: none; font-weight: 500;">
                        Làm mới
                    </MudButton>
                    <MudButton Variant="Variant.Filled"
                               StartIcon="@Icons.Material.Filled.Add"
                               OnClick="@(() => OpenScopeDialog())"
                               Class="add-scope-btn"
                               Style="text-transform: none; font-weight: 500;">
                        Thêm Scope
                    </MudButton>
                </div>
            </div>
        </div>

        <MudTable Items="filteredScopes"
                  Class="scope-table"
                  Hover="true"
                  Dense="true"
                  FixedHeader="true"
                  Loading="@loadingScopes"
                  Style="background: transparent;">
            <HeaderContent>
                <MudTh Style="width: 30%;">Tên hiển thị</MudTh>
                <MudTh Style="width: 30%;">Tên Scope</MudTh>
                <MudTh Style="width: 25%;">Resources</MudTh>
                <MudTh Style="width: 25%; text-align: center;">Thao tác</MudTh>
            </HeaderContent>
            <RowTemplate>
                <MudTd DataLabel="Display Name">
                    <MudStack Spacing="1">
                        <MudText Typo="Typo.body1" Style="font-weight: 500; color: #1f2937;">
                            @(string.IsNullOrEmpty(context.DisplayName) ? context.Name : context.DisplayName)
                        </MudText>
                        <MudText Typo="Typo.caption" Class="textid">@context.Id[..12]...</MudText>
                    </MudStack>
                </MudTd>
                <MudTd DataLabel="Name">
                    <MudChip T="string"
                             Text="@context.Name"
                             Size="Size.Small"
                             Style="background: #f3f4f6; color: #374151; font-weight: 500;" />
                </MudTd>
                <MudTd DataLabel="Resources">
                    @{
                        var validResources = GetValidResources(context.Resources);
                    }
                    @if (validResources.Any())
                    {
                        <MudTooltip Text="@string.Join(", ", validResources.Select(r => GetResourceDisplayName(r)))">
                            <MudChip T="string" Color="Color.Tertiary"
                                     Text="@($"{validResources.Count} resource{(validResources.Count > 1 ? "s" : "")}")"
                                     Size="Size.Small"
                                     Class="resource-chip" />
                        </MudTooltip>
                        @if (context.Resources.Count > validResources.Count)
                        {
                            <MudTooltip Text="@($"{context.Resources.Count - validResources.Count} resource(s) không tồn tại")">
                                <MudChip T="string" Color="Color.Warning"
                                         Text="@($"{context.Resources.Count - validResources.Count} invalid")"
                                         Size="Size.Small"
                                         Style="margin-left: 0.25rem;" />
                            </MudTooltip>
                        }
                    }
                    else if (context.Resources.Any())
                    {
                        <MudTooltip Text="Tất cả resources không tồn tại">
                            <MudChip T="string" Color="Color.Error"
                                     Text="All invalid"
                                     Size="Size.Small" />
                        </MudTooltip>
                    }
                    else
                    {
                        <MudText Typo="Typo.caption" Style="color: #9ca3af; font-style: italic;">
                            Không có resources
                        </MudText>
                    }
                </MudTd>
                <MudTd DataLabel="Actions">
                    <div class="action-buttons" style="justify-content: center;">
                        <MudIconButton Icon="@Icons.Material.Filled.Visibility"
                                       Size="Size.Small"
                                       Style="color: #3b82f6;"
                                       OnClick="@(() => ViewScopeDetails(context))"
                                       aria-label="Xem chi tiết" />
                        <MudIconButton Icon="@Icons.Material.Filled.Edit"
                                       Size="Size.Small"
                                       Style="color: #059669;"
                                       OnClick="@(() => EditScope(context))"
                                       aria-label="Chỉnh sửa" />
                        @if (HasInvalidResources(context.Resources))
                        {
                            <MudIconButton Icon="@Icons.Material.Filled.CleaningServices"
                                           Size="Size.Small"
                                           Style="color: #f59e0b;"
                                           OnClick="@(() => CleanupScopeResources(context))"
                                           aria-label="Dọn dẹp resources không hợp lệ" />
                        }
                        <MudIconButton Icon="@Icons.Material.Filled.Delete"
                                       Size="Size.Small"
                                       Style="color: #dc2626;"
                                       OnClick="@(() => DeleteScope(context.Name))"
                                       aria-label="Xóa" />
                    </div>
                </MudTd>
            </RowTemplate>
            <PagerContent>
                <MudTablePager PageSizeOptions="new int[] { 5, 10, 25, 50, 100, int.MaxValue }" />
            </PagerContent>
            <LoadingContent>
                <div style="text-align: center; padding: 2rem;">
                    <MudProgressCircular Color="Color.Primary" Indeterminate="true" />
                    <MudText Typo="Typo.body1" Style="margin-top: 1rem; color: #6b7280;">
                        Đang tải dữ liệu...
                    </MudText>
                </div>
            </LoadingContent>
        </MudTable>
    </div>

    <MudDialog @bind-Visible="showScopeDialog" Options="@(new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true, CloseButton = true })">
        <TitleContent>
            <div style="display: flex; align-items: center;">
                <MudIcon Icon="@Icons.Material.Filled.Security" Style="margin-right: 0.5rem; color: #4f46e5;" />
                <MudText Typo="Typo.h6" Style="margin: 0;">
                    @(editingScope?.Name != null ? "Chỉnh sửa Scope" : "Thêm Scope mới")
                </MudText>
            </div>
        </TitleContent>
        <DialogContent>
            <div class="dialog-content">
                <MudGrid Spacing="3">
                    <MudItem xs="12" md="6">
                        <MudTextField @bind-Value="scopeForm.Name"
                                      Label="Tên Scope"
                                      Required="true"
                                      Variant="Variant.Outlined"
                                      Style="background: white;" />
                    </MudItem>
                    <MudItem xs="12" md="6">
                        <MudTextField @bind-Value="scopeForm.DisplayName"
                                      Label="Tên hiển thị"
                                      Variant="Variant.Outlined"
                                      Style="background: white;" />
                    </MudItem>
                    <MudItem xs="12">
                        <div class="resource-selection">
                            <MudText Typo="Typo.subtitle1" Style="margin-bottom: 1rem; color: #374151; font-weight: 600;">
                                <MudIcon Icon="@Icons.Material.Filled.Storage" Style="margin-right: 0.5rem;" />
                                Chọn Resources
                            </MudText>
                            <MudSelect T="string"
                                       Label="Chọn Resources"
                                       Variant="Variant.Outlined"
                                       MultiSelection="true"
                                       SelectAll="true"
                                       SelectAllText="Chọn tất cả"
                                       Dense="true"
                                       MaxHeight="250"
                                       Style="background: white; margin-bottom: 1rem;"
                                       SelectedValuesChanged="@OnResourceSelectionChanged"
                                       SelectedValues="@GetSelectedResources()">
                                @foreach (var resource in availableResources)
                                {
                                    <MudSelectItem Value="@resource.ClientId">
                                        <div style="display: flex; align-items: center;">
                                            <MudIcon Icon="@Icons.Material.Filled.Apps" Style="margin-right: 0.5rem; color: #6b7280;" />
                                            <div>
                                                <MudText Typo="Typo.body1">@resource.DisplayName</MudText>
                                                <MudText Typo="Typo.caption" Style="color: #9ca3af;">@resource.ClientId</MudText>
                                            </div>
                                        </div>
                                    </MudSelectItem>
                                }
                            </MudSelect>

                            @if (GetSelectedResources().Any())
                            {
                                <MudText Typo="Typo.subtitle2" Style="margin-bottom: 0.5rem; color: #374151;">
                                    Resources đã chọn:
                                </MudText>
                                <div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
                                    @foreach (var selectedResource in GetSelectedResources())
                                    {
                                        var resourceInfo = availableResources.FirstOrDefault(r => r.ClientId == selectedResource);
                                        <MudChip T="string"
                                                 Text="@(resourceInfo?.DisplayName ?? selectedResource)"
                                                 OnClose="@(() => RemoveResource(selectedResource))"
                                                 Class="selected-resource-chip"
                                                 Size="Size.Small" />
                                    }
                                </div>
                            }
                        </div>
                    </MudItem>
                </MudGrid>
            </div>
        </DialogContent>
        <DialogActions>
            <MudButton OnClick="CancelScopeDialog" Style="text-transform: none;">
                Hủy
            </MudButton>
            <MudButton Color="Color.Primary"
                       Variant="Variant.Filled"
                       OnClick="SaveScope"
                       Style="background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%); text-transform: none;">
                <MudIcon Icon="@Icons.Material.Filled.Save" Style="margin-right: 0.5rem;" />
                Lưu
            </MudButton>
        </DialogActions>
    </MudDialog>

    <MudDialog @bind-Visible="ShowDetailsDialog" Options="@(new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true, CloseButton = true })">
        <TitleContent>
            <div style="display: flex; align-items: center;">
                <MudIcon Icon="@Icons.Material.Filled.Info" Style="margin-right: 0.5rem; color: #3b82f6;" />
                <MudText Typo="Typo.h6" Style="margin: 0;">Chi tiết Scope</MudText>
            </div>
        </TitleContent>
        <DialogContent>
            @if (selectedScope != null)
            {
                <div style="background: #f8fafc; border-radius: 12px; padding: 1.5rem;">
                    <MudGrid Spacing="2">
                        <MudItem xs="12" md="6">
                            <div style="background: white; padding: 1rem; border-radius: 8px; border-left: 4px solid #3b82f6;">
                                <MudText Typo="Typo.caption" Style="color: #6b7280; margin-bottom: 0.25rem;">ID</MudText>
                                <MudText Typo="Typo.body2" Style="font-family: monospace; word-break: break-all;">@selectedScope.Id</MudText>
                            </div>
                        </MudItem>
                        <MudItem xs="12" md="6">
                            <div style="background: white; padding: 1rem; border-radius: 8px; border-left: 4px solid #059669;">
                                <MudText Typo="Typo.caption" Style="color: #6b7280; margin-bottom: 0.25rem;">Tên</MudText>
                                <MudText Typo="Typo.body1" Style="font-weight: 500;">@selectedScope.Name</MudText>
                            </div>
                        </MudItem>
                        <MudItem xs="12">
                            <div style="background: white; padding: 1rem; border-radius: 8px; border-left: 4px solid #7c3aed;">
                                <MudText Typo="Typo.caption" Style="color: #6b7280; margin-bottom: 0.25rem;">Tên hiển thị</MudText>
                                <MudText Typo="Typo.body1">@(string.IsNullOrEmpty(selectedScope.DisplayName) ? "Không có" : selectedScope.DisplayName)</MudText>
                            </div>
                        </MudItem>
                        <MudItem xs="12">
                            <div style="background: white; padding: 1rem; border-radius: 8px; border-left: 4px solid #f59e0b;">
                                <MudText Typo="Typo.caption" Style="color: #6b7280; margin-bottom: 0.5rem;">Resources</MudText>
                                <div>
                                    @if (selectedScope.Resources.Any())
                                    {
                                        var validResources = GetValidResources(selectedScope.Resources);
                                        var invalidResources = selectedScope.Resources.Except(validResources).ToList();

                                        @if (validResources.Any())
                                        {
                                            <MudText Typo="Typo.caption" Style="color: #059669; margin-bottom: 0.5rem; font-weight: 600;">Resources hợp lệ:</MudText>
                                            <div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem;">
                                                @foreach (var resource in validResources)
                                                {
                                                    <MudChip T="string" Text="@GetResourceDisplayName(resource)" Size="Size.Small" Style="background: #dcfce7; color: #166534;" />
                                                }
                                            </div>
                                        }

                                        @if (invalidResources.Any())
                                        {
                                            <MudText Typo="Typo.caption" Style="color: #dc2626; margin-bottom: 0.5rem; font-weight: 600;">Resources không hợp lệ:</MudText>
                                            <div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
                                                @foreach (var resource in invalidResources)
                                                {
                                                    <MudChip T="string" Text="@resource" Size="Size.Small" Style="background: #fecaca; color: #991b1b;" />
                                                }
                                            </div>
                                        }
                                    }
                                    else
                                    {
                                        <MudText Style="color: #9ca3af; font-style: italic;">Không có resources</MudText>
                                    }
                                </div>
                            </div>
                        </MudItem>
                    </MudGrid>
                </div>
            }
        </DialogContent>
        <DialogActions>
            <MudButton OnClick="CloseDetailsDialog" Color="Color.Primary" Style="text-transform: none;">
                <MudIcon Icon="@Icons.Material.Filled.Close" Style="margin-right: 0.5rem;" />
                Đóng
            </MudButton>
        </DialogActions>
    </MudDialog>
</MudContainer>


@code {
    private string resourceInput = string.Empty;
    private List<ScopeInfo> filteredScopes = new();
    private List<ResourceInfo> availableResources = new();
    private Dictionary<string, bool> resourceChecks = new();
    private bool loadingScopes = false;
    private bool showScopeDialog = false;
    private bool ShowDetailsDialog = false;
    private ScopeInfo? editingScope = null;
    private ScopeInfo? selectedScope = null;
    private ScopeForm scopeForm = new();

    

    public class ScopeInfo
    {
        public string Id { get; set; } = string.Empty;
        public string Name { get; set; } = string.Empty;
        public string DisplayName { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public List<string> Resources { get; set; } = new();
        public Dictionary<string, string> Properties { get; set; } = new();
    }

    public class ScopeForm
    {
        public string Name { get; set; } = string.Empty;
        public string DisplayName { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public List<string> Resources { get; set; } = new();
    }

    public class ResourceInfo
    {
        public string ClientId { get; set; } = string.Empty;
        public string DisplayName { get; set; } = string.Empty;
    }

    protected override async Task OnInitializedAsync()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        if (authState.User.Identity?.IsAuthenticated == true)
        {
            await LoadAvailableResourcesAsync();
            await LoadScopesAsync();
        }
    }

    private async Task LoadAvailableResourcesAsync()
    {
        try
        {
            availableResources.Clear();

            await foreach (var app in ApplicationManager.ListAsync())
            {
                var clientType = await ApplicationManager.GetClientTypeAsync(app);
                if (clientType == ClientTypes.Confidential)
                {
                    var clientId = await ApplicationManager.GetClientIdAsync(app);
                    var displayName = await ApplicationManager.GetDisplayNameAsync(app);

                    if (!string.IsNullOrEmpty(clientId))
                    {
                        availableResources.Add(new ResourceInfo
                        {
                            ClientId = clientId,
                            DisplayName = string.IsNullOrEmpty(displayName) ? clientId : displayName
                        });
                    }
                }
            }

            resourceChecks.Clear();
            foreach (var resource in availableResources)
            {
                resourceChecks[resource.ClientId] = false;
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Lỗi khi tải resources: {ex.Message}", Severity.Error);
        }
    }

    
    private List<string> GetValidResources(List<string> resources)
    {
        var validResourceIds = availableResources.Select(r => r.ClientId).ToHashSet();
        return resources.Where(r => validResourceIds.Contains(r)).ToList();
    }

    
    private bool HasInvalidResources(List<string> resources)
    {
        var validResourceIds = availableResources.Select(r => r.ClientId).ToHashSet();
        return resources.Any(r => !validResourceIds.Contains(r));
    }

    
    private string GetResourceDisplayName(string clientId)
    {
        var resource = availableResources.FirstOrDefault(r => r.ClientId == clientId);
        return resource?.DisplayName ?? clientId;
    }

    
    private async Task CleanupScopeResources(ScopeInfo scope)
    {
        var confirm = await DialogService.ShowMessageBox(
            "Xác nhận dọn dẹp",
            $"Bạn có muốn xóa các resources không hợp lệ khỏi scope '{scope.Name}'?",
            yesText: "Dọn dẹp",
            cancelText: "Hủy"
        );

        if (confirm == true)
        {
            try
            {
                var existingScope = await ScopeManager.FindByNameAsync(scope.Name);
                if (existingScope != null)
                {
                    var validResources = GetValidResources(scope.Resources);

                    var descriptor = new OpenIddictScopeDescriptor
                    {
                        Name = scope.Name,
                        DisplayName = scope.DisplayName,
                        Description = scope.Description
                    };

                    foreach (var resource in validResources)
                    {
                        descriptor.Resources.Add(resource);
                    }

                    await ScopeManager.PopulateAsync(existingScope, descriptor);
                    await ScopeManager.UpdateAsync(existingScope);

                    Snackbar.Add($"Đã dọn dẹp {scope.Resources.Count - validResources.Count} resources không hợp lệ", Severity.Success);
                    await LoadScopesAsync();
                }
            }
            catch (Exception ex)
            {
                Snackbar.Add($"Lỗi khi dọn dẹp resources: {ex.Message}", Severity.Error);
            }
        }
    }

    
    private async Task RefreshScopesAsync()
    {
        await LoadAvailableResourcesAsync();
        await LoadScopesAsync();
        Snackbar.Add("Đã làm mới danh sách scopes", Severity.Success);
    }

    private void AddResource()
    {
        if (!string.IsNullOrWhiteSpace(resourceInput) && !scopeForm.Resources.Contains(resourceInput))
        {
            scopeForm.Resources.Add(resourceInput);
            resourceInput = string.Empty;
            StateHasChanged();
        }
    }

    private void OnResourceSelectionChanged(IEnumerable<string> selectedValues)
    {
        foreach (var key in resourceChecks.Keys.ToList())
        {
            resourceChecks[key] = false;
        }

        foreach (var value in selectedValues)
        {
            if (resourceChecks.ContainsKey(value))
            {
                resourceChecks[value] = true;
            }
        }

        scopeForm.Resources = selectedValues.ToList();
        StateHasChanged();
    }

    private IEnumerable<string> GetSelectedResources()
    {
        return resourceChecks.Where(x => x.Value).Select(x => x.Key);
    }

    private void RemoveResource(string resource)
    {
        if (resourceChecks.ContainsKey(resource))
        {
            resourceChecks[resource] = false;
            scopeForm.Resources.Remove(resource);
            StateHasChanged();
        }
    }

    private async Task LoadScopesAsync()
    {
        try
        {
            loadingScopes = true;
            filteredScopes.Clear();

            await foreach (var scope in ScopeManager.ListAsync())
            {
                var id = await ScopeManager.GetIdAsync(scope);
                var name = await ScopeManager.GetNameAsync(scope);
                var displayName = await ScopeManager.GetDisplayNameAsync(scope);
                var description = await ScopeManager.GetDescriptionAsync(scope);
                var resources = await ScopeManager.GetResourcesAsync(scope);
                var properties = await ScopeManager.GetPropertiesAsync(scope);

                filteredScopes.Add(new ScopeInfo
                {
                    Id = id ?? string.Empty,
                    Name = name ?? string.Empty,
                    DisplayName = displayName ?? string.Empty,
                    Description = description ?? string.Empty,
                    Resources = resources.ToList(),
                    Properties = properties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString() ?? string.Empty)
                });
            }
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Lỗi khi tải scopes: {ex.Message}", Severity.Error);
        }
        finally
        {
            loadingScopes = false;
            StateHasChanged();
        }
    }

    private void ViewScopeDetails(ScopeInfo scope)
    {
        selectedScope = scope;
        ShowDetailsDialog = true;
    }

    private void CloseDetailsDialog()
    {
        ShowDetailsDialog = false;
        selectedScope = null;
    }

    private async Task OpenScopeDialog(ScopeInfo? scope = null)
    {
        editingScope = scope;
        ResetScopeForm();

        if (scope != null)
        {
            scopeForm.Name = scope.Name;
            scopeForm.DisplayName = scope.DisplayName;
            scopeForm.Description = scope.Description;

            
            var validResources = GetValidResources(scope.Resources);
            scopeForm.Resources = new List<string>(validResources);

            foreach (var key in resourceChecks.Keys.ToList())
            {
                resourceChecks[key] = validResources.Contains(key);
            }

            
            if (scope.Resources.Count > validResources.Count)
            {
                var invalidCount = scope.Resources.Count - validResources.Count;
                Snackbar.Add($"Đã loại bỏ {invalidCount} resource không hợp lệ khỏi form chỉnh sửa", Severity.Warning);
            }
        }

        showScopeDialog = true;
        await Task.CompletedTask;
    }

    private async void EditScope(ScopeInfo scope)
    {
        await OpenScopeDialog(scope);
    }

    private void ResetScopeForm()
    {
        scopeForm = new ScopeForm();

        foreach (var key in resourceChecks.Keys.ToList())
        {
            resourceChecks[key] = false;
        }
    }

    private async Task SaveScope()
    {
        try
        {
            if (string.IsNullOrWhiteSpace(scopeForm.Name))
            {
                Snackbar.Add("Name là bắt buộc", Severity.Error);
                return;
            }

            var descriptor = new OpenIddictScopeDescriptor
            {
                Name = scopeForm.Name,
                DisplayName = scopeForm.DisplayName,
                Description = scopeForm.Description
            };

            
            var validResources = GetValidResources(scopeForm.Resources);
            foreach (var resource in validResources)
            {
                descriptor.Resources.Add(resource);
            }

            if (editingScope != null)
            {
                var existingScope = await ScopeManager.FindByNameAsync(editingScope.Name);
                if (existingScope != null)
                {
                    await ScopeManager.PopulateAsync(existingScope, descriptor);
                    await ScopeManager.UpdateAsync(existingScope);
                }
            }
            else
            {
                await ScopeManager.CreateAsync(descriptor);
            }

            Snackbar.Add(editingScope != null ? "Cập nhật scope thành công" : "Tạo scope thành công", Severity.Success);
            showScopeDialog = false;
            await LoadScopesAsync();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Lỗi khi lưu scope: {ex.Message}", Severity.Error);
        }
    }

    private void CancelScopeDialog()
    {
        showScopeDialog = false;
        ResetScopeForm();
    }

    private async Task DeleteScope(string name)
    {
        var confirm = await DialogService.ShowMessageBox("Xác nhận xóa", $"Bạn có chắc chắn muốn xóa scope '{name}'?", yesText: "Xóa", cancelText: "Hủy");
        if (confirm == true)
        {
            try
            {
                var scope = await ScopeManager.FindByNameAsync(name);
                if (scope != null)
                {
                    await ScopeManager.DeleteAsync(scope);
                    Snackbar.Add("Xóa scope thành công", Severity.Success);
                    await LoadScopesAsync();
                }
            }
            catch (Exception ex)
            {
                Snackbar.Add($"Lỗi khi xóa scope: {ex.Message}", Severity.Error);
            }
        }
    }
}