@page "/galaxy"
@inherits DashboardPageBase
@using ZB.MOM.WW.MxGateway.Server.Galaxy

<PageTitle>Dashboard Galaxy</PageTitle>

@if (Snapshot is null)
{
    <div class="empty-state">Loading Galaxy summary.</div>
}
else
{
    <div class="dashboard-page-header">
        <div>
            <h1>Galaxy Repository</h1>
            <div class="text-secondary">@RefreshHeading()</div>
        </div>
        <StatusBadge Text="@Snapshot.Galaxy.Status.ToString()" />
    </div>

    <section class="metric-grid">
        <MetricCard Label="Last Deploy" Value="@DashboardDisplay.DateTime(Snapshot.Galaxy.LastDeployTime)" Detail="@DeployAge()" Wide="true" />
        <MetricCard Label="Last Refresh" Value="@DashboardDisplay.DateTime(Snapshot.Galaxy.LastSuccessAt)" Detail="@LastAttemptDetail()" Wide="true" />
        <MetricCard Label="Objects" Value="@DashboardDisplay.Count(Snapshot.Galaxy.ObjectCount)" Detail="@($"{Snapshot.Galaxy.AreaCount:N0} areas")" />
        <MetricCard Label="Attributes" Value="@DashboardDisplay.Count(Snapshot.Galaxy.AttributeCount)" Detail="dynamic, deployed" />
        <MetricCard Label="Historized" Value="@DashboardDisplay.Count(Snapshot.Galaxy.HistorizedAttributeCount)" />
        <MetricCard Label="Alarms" Value="@DashboardDisplay.Count(Snapshot.Galaxy.AlarmAttributeCount)" />
    </section>

    @if (Snapshot.Galaxy.Status == DashboardGalaxyStatus.Unknown)
    {
        <section class="dashboard-section">
            <div class="empty-state">
                Galaxy summary has not been collected yet. The dashboard refreshes the
                summary every @RefreshIntervalSeconds() seconds via the
                <code>GalaxyRepository</code> service.
            </div>
        </section>
    }

    @if (!string.IsNullOrWhiteSpace(Snapshot.Galaxy.LastError))
    {
        <section class="dashboard-section">
            <div class="section-heading">
                <h2>Last Error</h2>
            </div>
            <div class="empty-state">@Snapshot.Galaxy.LastError</div>
        </section>
    }

    <section class="dashboard-section">
        <div class="section-heading">
            <h2>Object Categories</h2>
        </div>
        @if (Snapshot.Galaxy.ObjectCategories.Count == 0)
        {
            <div class="empty-state">No deployed objects observed.</div>
        }
        else
        {
            <div class="table-responsive">
                <table class="table table-sm dashboard-table">
                    <thead>
                        <tr>
                            <th scope="col">Category</th>
                            <th scope="col">Category ID</th>
                            <th scope="col">Objects</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (DashboardGalaxyCategoryCount row in Snapshot.Galaxy.ObjectCategories)
                        {
                            <tr>
                                <td>@row.CategoryName</td>
                                <td><code>@row.CategoryId</code></td>
                                <td>@DashboardDisplay.Count(row.ObjectCount)</td>
                            </tr>
                        }
                    </tbody>
                </table>
            </div>
        }
    </section>

    <section class="dashboard-section">
        <div class="section-heading">
            <h2>Top Templates</h2>
        </div>
        @if (Snapshot.Galaxy.TopTemplates.Count == 0)
        {
            <div class="empty-state">No template usage observed.</div>
        }
        else
        {
            <div class="table-responsive">
                <table class="table table-sm dashboard-table">
                    <thead>
                        <tr>
                            <th scope="col">Template</th>
                            <th scope="col">Instances</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (DashboardGalaxyTemplateUsage row in Snapshot.Galaxy.TopTemplates)
                        {
                            <tr>
                                <td><code>@row.TemplateName</code></td>
                                <td>@DashboardDisplay.Count(row.InstanceCount)</td>
                            </tr>
                        }
                    </tbody>
                </table>
            </div>
        }
    </section>

    <section class="dashboard-section">
        <div class="section-heading">
            <h2>Sync Info</h2>
        </div>
        <div class="table-responsive">
            <table class="table table-sm dashboard-table details-table">
                <tbody>
                    <tr><th scope="row">Status</th><td><StatusBadge Text="@Snapshot.Galaxy.Status.ToString()" /></td></tr>
                    <tr><th scope="row">Last successful refresh</th><td>@DashboardDisplay.DateTime(Snapshot.Galaxy.LastSuccessAt)</td></tr>
                    <tr><th scope="row">Last attempt</th><td>@DashboardDisplay.DateTime(Snapshot.Galaxy.LastQueriedAt)</td></tr>
                    <tr><th scope="row">Galaxy <code>time_of_last_deploy</code></th><td>@DashboardDisplay.DateTime(Snapshot.Galaxy.LastDeployTime)</td></tr>
                    <tr><th scope="row">Refresh interval</th><td>@RefreshIntervalSeconds() seconds</td></tr>
                    <tr><th scope="row">Connection string</th><td><code>@DashboardDisplay.Text(GalaxyConnectionStringDisplay())</code></td></tr>
                    <tr><th scope="row">Command timeout</th><td>@CommandTimeoutSeconds() seconds</td></tr>
                </tbody>
            </table>
        </div>
        <div class="text-secondary small mt-2">
            Browse data is served by the <code>galaxy_repository.v1.GalaxyRepository</code> gRPC
            service. Clients call <code>DiscoverHierarchy</code> for the full tree and
            <code>GetLastDeployTime</code> to detect redeployments.
        </div>
    </section>
}

@code {
    [Inject]
    private IOptions<GalaxyRepositoryOptions> GalaxyOptions { get; set; } = null!;

    private string RefreshHeading()
    {
        DashboardGalaxySummary galaxy = Snapshot!.Galaxy;
        return galaxy.LastSuccessAt is null
            ? "Awaiting first successful refresh"
            : $"Refreshed {DashboardDisplay.DateTime(galaxy.LastSuccessAt)}";
    }

    private string? DeployAge()
    {
        DashboardGalaxySummary galaxy = Snapshot!.Galaxy;
        if (galaxy.LastDeployTime is null || galaxy.LastSuccessAt is null)
        {
            return null;
        }

        TimeSpan age = galaxy.LastSuccessAt.Value - galaxy.LastDeployTime.Value;
        if (age < TimeSpan.Zero)
        {
            return null;
        }

        return $"{DashboardDisplay.Duration(age)} ago";
    }

    private string? LastAttemptDetail()
    {
        DashboardGalaxySummary galaxy = Snapshot!.Galaxy;
        if (galaxy.LastQueriedAt is null)
        {
            return "never queried";
        }

        if (galaxy.LastSuccessAt is null)
        {
            return "no successful refresh yet";
        }

        return galaxy.LastQueriedAt > galaxy.LastSuccessAt
            ? $"last attempt {DashboardDisplay.DateTime(galaxy.LastQueriedAt)}"
            : null;
    }

    private int RefreshIntervalSeconds() => Math.Max(1, GalaxyOptions.Value.DashboardRefreshIntervalSeconds);

    private int CommandTimeoutSeconds() => GalaxyOptions.Value.CommandTimeoutSeconds;

    private string GalaxyConnectionStringDisplay()
    {
        return DashboardConnectionStringDisplay.GalaxyRepositoryConnectionString(GalaxyOptions.Value.ConnectionString);
    }
}
