@using EntKube.Web.Data
@using EntKube.Web.Services
@using Microsoft.EntityFrameworkCore
@inject PrometheusService PrometheusService
@inject IncidentService IncidentService
@inject IDbContextFactory<ApplicationDbContext> DbFactory
@implements IAsyncDisposable

<div class="d-flex justify-content-between align-items-center mb-3">
    <div>
        @if (lastRefreshed.HasValue)
        {
            <span class="text-muted small">Last refreshed: @lastRefreshed.Value.ToLocalTime().ToString("HH:mm:ss")</span>
        }
    </div>
    <button class="btn btn-sm btn-outline-secondary" @onclick="Refresh" disabled="@isLoading">
        <span class="bi bi-arrow-clockwise @(isLoading ? "spin" : "")"></span> Refresh
    </button>
</div>

@if (clusterSummaries.Count > 0)
{
    <div class="row g-2 mb-4">
        <div class="col-auto">
            <div class="card text-center border-0 bg-light px-3 py-2">
                <div class="fw-bold fs-4">@clusterSummaries.Count</div>
                <div class="text-muted small">Clusters</div>
            </div>
        </div>
        <div class="col-auto">
            <div class="card text-center border-0 bg-light px-3 py-2">
                <div class="fw-bold fs-4">@clusterSummaries.Sum(s => s.Health?.TotalNodes ?? 0)</div>
                <div class="text-muted small">Nodes</div>
            </div>
        </div>
        <div class="col-auto">
            <div class="card text-center border-0 bg-light px-3 py-2">
                <div class="fw-bold fs-4">@clusterSummaries.Sum(s => s.Health?.RunningPods ?? 0)</div>
                <div class="text-muted small">Running Pods</div>
            </div>
        </div>
        <div class="col-auto">
            <div class="card text-center border-0 bg-light px-3 py-2">
                <div class="fw-bold fs-4 @(tenantActiveAlerts > 0 ? "text-danger" : "text-success")">@tenantActiveAlerts</div>
                <div class="text-muted small">Active Alerts</div>
            </div>
        </div>
    </div>
}

<div class="row g-3">
    @foreach (ClusterSummaryVm vm in clusterSummaries)
    {
        <div class="col-12 col-md-6 col-xl-4">
            <div class="card h-100 border-@ClusterBorderColor(vm)">
                <div class="card-header d-flex align-items-center gap-2 py-2">
                    <span class="bi bi-hdd-rack-fill text-@ClusterBorderColor(vm)"></span>
                    <strong class="me-auto">@vm.Cluster.Name</strong>
                    @if (vm.ActiveAlerts > 0)
                    {
                        <span class="badge bg-danger">@vm.ActiveAlerts alert@(vm.ActiveAlerts == 1 ? "" : "s")</span>
                    }
                    else
                    {
                        <span class="badge bg-success">Healthy</span>
                    }
                </div>
                <div class="card-body py-2">
                    @if (vm.Health is null)
                    {
                        <div class="text-muted small text-center py-2">
                            <span class="bi bi-exclamation-triangle me-1"></span>
                            @(vm.Error ?? "Prometheus not available")
                        </div>
                    }
                    else
                    {
                        <div class="row g-2 mb-2">
                            <div class="col-6">
                                <div class="small text-muted">CPU</div>
                                <div class="progress" style="height:8px">
                                    <div class="progress-bar bg-@UtilColor(vm.Health.CpuUsagePercent)"
                                         style="width:@((int)Math.Min(vm.Health.CpuUsagePercent,100))%"></div>
                                </div>
                                <div class="small fw-semibold">@vm.Health.CpuUsagePercent.ToString("F1")%</div>
                            </div>
                            <div class="col-6">
                                <div class="small text-muted">Memory</div>
                                <div class="progress" style="height:8px">
                                    <div class="progress-bar bg-@UtilColor(vm.Health.MemoryUsagePercent)"
                                         style="width:@((int)Math.Min(vm.Health.MemoryUsagePercent,100))%"></div>
                                </div>
                                <div class="small fw-semibold">@vm.Health.MemoryUsagePercent.ToString("F1")%</div>
                            </div>
                        </div>
                        <div class="small text-muted">
                            <span class="bi bi-server me-1"></span>@vm.Health.ReadyNodes/@vm.Health.TotalNodes nodes ready
                            &nbsp;·&nbsp;
                            <span class="bi bi-box me-1"></span>@vm.Health.RunningPods pods running
                        </div>
                    }
                </div>
                <div class="card-footer py-1 bg-transparent border-0">
                    <a href="tenants/@TenantSlug/clusters/@vm.Cluster.Id/monitoring" class="btn btn-sm btn-link p-0 text-decoration-none">
                        <span class="bi bi-graph-up me-1"></span>View monitoring
                    </a>
                </div>
            </div>
        </div>
    }
</div>

@code {
    [Parameter] public required Guid TenantId { get; set; }
    [Parameter] public required string TenantSlug { get; set; }

    private List<ClusterSummaryVm> clusterSummaries = [];
    private int tenantActiveAlerts;
    private DateTime? lastRefreshed;
    private bool isLoading;
    private Timer? refreshTimer;

    protected override async Task OnInitializedAsync()
    {
        await Refresh();
        refreshTimer = new Timer(_ => InvokeAsync(async () =>
        {
            await Refresh();
            StateHasChanged();
        }), null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
    }

    private async Task Refresh()
    {
        isLoading = true;
        StateHasChanged();

        List<KubernetesCluster> clusters;
        using (ApplicationDbContext db = DbFactory.CreateDbContext())
        {
            clusters = await db.KubernetesClusters
                .Include(c => c.Components)
                .Where(c => c.TenantId == TenantId)
                .OrderBy(c => c.Name)
                .ToListAsync();
        }

        tenantActiveAlerts = await IncidentService.GetActiveAlertCountForTenantAsync(TenantId);

        List<Task<ClusterSummaryVm>> tasks = clusters
            .Select(c => LoadClusterSummaryAsync(c))
            .ToList();

        clusterSummaries = [.. await Task.WhenAll(tasks)];

        lastRefreshed = DateTime.UtcNow;
        isLoading = false;
    }

    private async Task<ClusterSummaryVm> LoadClusterSummaryAsync(KubernetesCluster cluster)
    {
        bool hasPrometheus = cluster.Components.Any(c =>
            c.HelmChartName == "kube-prometheus-stack" && c.Status == ComponentStatus.Installed);

        if (!hasPrometheus)
            return new ClusterSummaryVm(cluster, null, null, 0);

        KubernetesOperationResult<ClusterHealthSummary> result =
            await PrometheusService.GetClusterHealthAsync(cluster.Id);

        return new ClusterSummaryVm(
            cluster,
            result.IsSuccess ? result.Data : null,
            result.IsSuccess ? null : result.Error,
            0);
    }

    private static string UtilColor(double pct) =>
        pct >= 90 ? "danger" : pct >= 70 ? "warning" : "success";

    private static string ClusterBorderColor(ClusterSummaryVm vm)
    {
        if (vm.ActiveAlerts > 0) return "danger";
        if (vm.Health is null) return "secondary";
        if (vm.Health.CpuUsagePercent >= 90 || vm.Health.MemoryUsagePercent >= 90) return "warning";
        return "success";
    }

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

    private record ClusterSummaryVm(
        KubernetesCluster Cluster,
        ClusterHealthSummary? Health,
        string? Error,
        int ActiveAlerts);
}
