@page "/admin/api-keys"
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Security
@attribute [Authorize(Policy = AuthorizationPolicies.RequireAdmin)]
@inject IInboundApiKeyAdmin ApiKeyAdmin
@inject NavigationManager NavigationManager
@inject IDialogService Dialog

<div class="container-fluid mt-3">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h4 class="mb-0">API Key Management</h4>
        <button class="btn btn-primary btn-sm" @onclick='() => NavigationManager.NavigateTo("/admin/api-keys/create")'>Add API Key</button>
    </div>

    <ToastNotification @ref="_toast" />

    @if (_loading)
    {
        <LoadingSpinner IsLoading="true" />
    }
    else if (_errorMessage != null)
    {
        <div class="alert alert-danger">@_errorMessage</div>
    }
    else
    {
        <div class="mb-3" style="max-width: 320px;">
            <input class="form-control form-control-sm"
                   placeholder="Filter by name…"
                   @bind="_search" @bind:event="oninput" />
        </div>

        @if (_keys.Count == 0)
        {
            <p class="text-muted text-center">No API keys configured.</p>
        }
        else if (!FilteredKeys.Any())
        {
            <p class="text-muted small">No API keys match the filter.</p>
        }
        else
        {
            <table class="table table-sm table-striped table-hover">
                <thead class="table-dark">
                    <tr>
                        <th>Key ID</th>
                        <th>Name</th>
                        <th>Methods</th>
                        <th style="width: 160px;">Actions</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var key in FilteredKeys)
                    {
                        <tr @key="key.KeyId">
                            <td><code>@TruncateKeyId(key.KeyId)</code></td>
                            <td>
                                @key.Name
                                @if (!key.Enabled)
                                {
                                    <span class="badge bg-secondary ms-1">Disabled</span>
                                }
                            </td>
                            <td>@key.Methods.Count</td>
                            <td>
                                <div class="d-flex gap-1">
                                    <button class="btn btn-outline-primary btn-sm py-0 px-2"
                                            @onclick='() => NavigationManager.NavigateTo($"/admin/api-keys/{key.KeyId}/edit")'>Edit</button>
                                    <div class="dropdown">
                                        <button class="btn btn-outline-secondary btn-sm py-0 px-2"
                                                data-bs-toggle="dropdown"
                                                aria-label="@($"More actions for {key.Name}")">⋮</button>
                                        <ul class="dropdown-menu dropdown-menu-end">
                                            <li>
                                                <button class="dropdown-item"
                                                        @onclick="() => ToggleKey(key)">
                                                    @(key.Enabled ? "Disable" : "Enable")
                                                </button>
                                            </li>
                                            <li><hr class="dropdown-divider" /></li>
                                            <li>
                                                <button class="dropdown-item text-danger"
                                                        @onclick="() => DeleteKey(key)">
                                                    Delete
                                                </button>
                                            </li>
                                        </ul>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
        }
    }
</div>

@code {
    // Inbound-API key re-arch (C3): this page reads keys from the IInboundApiKeyAdmin seam
    // (string KeyId, method-scopes) rather than the SQL Server ApiKey entity. The seam has no
    // retrievable hash, so the old masked Key-Hash column is gone; KeyId identifies each row.
    private List<InboundApiKeyInfo> _keys = new();
    private bool _loading = true;
    private string? _errorMessage;
    private string _search = string.Empty;

    private ToastNotification _toast = default!;

    private IEnumerable<InboundApiKeyInfo> FilteredKeys =>
        string.IsNullOrWhiteSpace(_search)
            ? _keys
            : _keys.Where(k =>
                k.Name?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false);

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

    private async Task LoadDataAsync()
    {
        _loading = true;
        _errorMessage = null;
        try
        {
            _keys = (await ApiKeyAdmin.ListAsync()).ToList();
        }
        catch (Exception ex)
        {
            _errorMessage = $"Failed to load API keys: {ex.Message}";
        }
        _loading = false;
    }

    // Show a short, recognizable prefix of the opaque KeyId rather than the full 32-char value.
    private static string TruncateKeyId(string keyId)
    {
        if (string.IsNullOrEmpty(keyId)) return keyId;
        return keyId.Length <= 12 ? keyId : keyId[..12] + "…";
    }

    private async Task ToggleKey(InboundApiKeyInfo key)
    {
        try
        {
            var newEnabled = !key.Enabled;
            // The seam persists; there is no separate SaveChangesAsync.
            var ok = await ApiKeyAdmin.SetEnabledAsync(key.KeyId, newEnabled);
            if (!ok)
            {
                _toast.ShowError($"API key '{key.Name}' was not found — it may have been removed. Refreshing.");
                await LoadDataAsync();
                return;
            }
            _toast.ShowSuccess($"API key '{key.Name}' {(newEnabled ? "enabled" : "disabled")}.");
            await LoadDataAsync();
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Toggle failed: {ex.Message}");
        }
    }

    private async Task DeleteKey(InboundApiKeyInfo key)
    {
        var confirmed = await Dialog.ConfirmAsync(
            "Delete API Key",
            $"Delete API key '{key.Name}'? This cannot be undone.",
            danger: true);
        if (!confirmed) return;

        try
        {
            var ok = await ApiKeyAdmin.DeleteAsync(key.KeyId);
            if (!ok)
            {
                _toast.ShowError($"API key '{key.Name}' was not found — it may have been removed. Refreshing.");
                await LoadDataAsync();
                return;
            }
            _toast.ShowSuccess($"API key '{key.Name}' deleted.");
            await LoadDataAsync();
        }
        catch (Exception ex)
        {
            _toast.ShowError($"Delete failed: {ex.Message}");
        }
    }

}
