@page "/clusters/{ClusterId}"
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.SignalR.Client
@using ZB.MOM.WW.OtOpcUa.Admin.Hubs
@using ZB.MOM.WW.OtOpcUa.Admin.Services
@using ZB.MOM.WW.OtOpcUa.Configuration.Entities
@using ZB.MOM.WW.OtOpcUa.Configuration.Enums
@implements IAsyncDisposable
@rendermode RenderMode.InteractiveServer
@inject ClusterService ClusterSvc
@inject GenerationService GenerationSvc
@inject NavigationManager Nav

@if (_cluster is null)
{
    <p>Loading…</p>
}
else
{
    @if (_liveBanner is not null)
    {
        <div class="alert alert-info py-2 small">
            <strong>Live update:</strong> @_liveBanner
            <button type="button" class="btn-close float-end" @onclick="() => _liveBanner = null"></button>
        </div>
    }
    <div class="d-flex justify-content-between align-items-center mb-3">
        <div>
            <h1 class="mb-0">@_cluster.Name</h1>
            <code class="text-muted">@_cluster.ClusterId</code>
            @if (!_cluster.Enabled) { <span class="badge bg-secondary ms-2">Disabled</span> }
        </div>
        <div>
            @if (_currentDraft is not null)
            {
                <a href="/clusters/@ClusterId/draft/@_currentDraft.GenerationId" class="btn btn-outline-primary">
                    Edit current draft (gen @_currentDraft.GenerationId)
                </a>
            }
            else
            {
                <button class="btn btn-primary" @onclick="CreateDraftAsync" disabled="@_busy">New draft</button>
            }
        </div>
    </div>

    <ul class="nav nav-tabs mb-3">
        <li class="nav-item"><button class="nav-link @Tab("overview")" @onclick='() => _tab = "overview"'>Overview</button></li>
        <li class="nav-item"><button class="nav-link @Tab("generations")" @onclick='() => _tab = "generations"'>Generations</button></li>
        <li class="nav-item"><button class="nav-link @Tab("equipment")" @onclick='() => _tab = "equipment"'>Equipment</button></li>
        <li class="nav-item"><button class="nav-link @Tab("uns")" @onclick='() => _tab = "uns"'>UNS Structure</button></li>
        <li class="nav-item"><button class="nav-link @Tab("namespaces")" @onclick='() => _tab = "namespaces"'>Namespaces</button></li>
        <li class="nav-item"><button class="nav-link @Tab("drivers")" @onclick='() => _tab = "drivers"'>Drivers</button></li>
        <li class="nav-item"><button class="nav-link @Tab("acls")" @onclick='() => _tab = "acls"'>ACLs</button></li>
        <li class="nav-item"><button class="nav-link @Tab("redundancy")" @onclick='() => _tab = "redundancy"'>Redundancy</button></li>
        <li class="nav-item"><button class="nav-link @Tab("audit")" @onclick='() => _tab = "audit"'>Audit</button></li>
    </ul>

    @if (_tab == "overview")
    {
        <dl class="row">
            <dt class="col-sm-3">Enterprise / Site</dt><dd class="col-sm-9">@_cluster.Enterprise / @_cluster.Site</dd>
            <dt class="col-sm-3">Redundancy</dt><dd class="col-sm-9">@_cluster.RedundancyMode (@_cluster.NodeCount node@(_cluster.NodeCount == 1 ? "" : "s"))</dd>
            <dt class="col-sm-3">Current published</dt>
            <dd class="col-sm-9">
                @if (_currentPublished is not null) { <span>@_currentPublished.GenerationId (@_currentPublished.PublishedAt?.ToString("u"))</span> }
                else { <span class="text-muted">none published yet</span> }
            </dd>
            <dt class="col-sm-3">Created</dt><dd class="col-sm-9">@_cluster.CreatedAt.ToString("u") by @_cluster.CreatedBy</dd>
        </dl>
    }
    else if (_tab == "generations")
    {
        <Generations ClusterId="@ClusterId"/>
    }
    else if (_tab == "equipment" && _currentDraft is not null)
    {
        <EquipmentTab GenerationId="@_currentDraft.GenerationId"/>
    }
    else if (_tab == "uns" && _currentDraft is not null)
    {
        <UnsTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
    }
    else if (_tab == "namespaces" && _currentDraft is not null)
    {
        <NamespacesTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
    }
    else if (_tab == "drivers" && _currentDraft is not null)
    {
        <DriversTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
    }
    else if (_tab == "acls" && _currentDraft is not null)
    {
        <AclsTab GenerationId="@_currentDraft.GenerationId" ClusterId="@ClusterId"/>
    }
    else if (_tab == "redundancy")
    {
        <RedundancyTab ClusterId="@ClusterId"/>
    }
    else if (_tab == "audit")
    {
        <AuditTab ClusterId="@ClusterId"/>
    }
    else
    {
        <p class="text-muted">Open a draft to edit this cluster's content.</p>
    }
}

@code {
    [Parameter] public string ClusterId { get; set; } = string.Empty;
    private ServerCluster? _cluster;
    private ConfigGeneration? _currentDraft;
    private ConfigGeneration? _currentPublished;
    private string _tab = "overview";
    private bool _busy;
    private HubConnection? _hub;
    private string? _liveBanner;

    private string Tab(string key) => _tab == key ? "active" : string.Empty;

    protected override async Task OnInitializedAsync()
    {
        await LoadAsync();
        await ConnectHubAsync();
    }

    private async Task LoadAsync()
    {
        _cluster = await ClusterSvc.FindAsync(ClusterId, CancellationToken.None);
        var gens = await GenerationSvc.ListRecentAsync(ClusterId, 50, CancellationToken.None);
        _currentDraft = gens.FirstOrDefault(g => g.Status == GenerationStatus.Draft);
        _currentPublished = gens.FirstOrDefault(g => g.Status == GenerationStatus.Published);
    }

    private async Task ConnectHubAsync()
    {
        _hub = new HubConnectionBuilder()
            .WithUrl(Nav.ToAbsoluteUri("/hubs/fleet"))
            .WithAutomaticReconnect()
            .Build();

        _hub.On<NodeStateChangedMessage>("NodeStateChanged", async msg =>
        {
            if (msg.ClusterId != ClusterId) return;
            _liveBanner = $"Node {msg.NodeId}: {msg.LastAppliedStatus ?? "seen"} at {msg.LastAppliedAt?.ToString("u") ?? msg.LastSeenAt?.ToString("u") ?? "-"}";
            await LoadAsync();
            await InvokeAsync(StateHasChanged);
        });

        await _hub.StartAsync();
        await _hub.SendAsync("SubscribeCluster", ClusterId);
    }

    private async Task CreateDraftAsync()
    {
        _busy = true;
        try
        {
            var draft = await GenerationSvc.CreateDraftAsync(ClusterId, createdBy: "admin-ui", CancellationToken.None);
            Nav.NavigateTo($"/clusters/{ClusterId}/draft/{draft.GenerationId}");
        }
        finally { _busy = false; }
    }

    public async ValueTask DisposeAsync()
    {
        if (_hub is not null) await _hub.DisposeAsync();
    }
}
