@using EntKube.Web.Data
@using EntKube.Web.Services
@inject DatabaseService DatabaseService
@inject CnpgService CnpgService
@inject MongoService MongoService
@inject StorageService StorageService

@* ===========================================================================
   Databases Tab — shows CNPG PostgreSQL clusters and MongoDB clusters
   discovered across the tenant's Kubernetes clusters.
   Requires the respective operators (cloudnative-pg, mongodb-operator)
   to be installed on at least one cluster.
   =========================================================================== *@

@if (loading)
{
    <div class="text-center py-5">
        <div class="spinner-border text-primary" role="status"></div>
        <p class="text-muted mt-2">Discovering database clusters...</p>
    </div>
}
else if (operatorStatus is not null && !operatorStatus.CnpgAvailable && !operatorStatus.MongoDbAvailable)
{
    @* No operators installed — show helpful guidance *@
    <div class="alert alert-info d-flex align-items-start gap-3">
        <i class="bi bi-info-circle fs-4 mt-1"></i>
        <div>
            <h6 class="alert-heading mb-1">No Database Operators Installed</h6>
            <p class="mb-2">
                To use the Databases page, install at least one database operator on a cluster:
            </p>
            <ul class="mb-0 small">
                <li><strong>CloudNativePG</strong> — for managed PostgreSQL clusters</li>
                <li><strong>MongoDB Community Operator</strong> — for managed MongoDB replica sets</li>
            </ul>
            <p class="mt-2 mb-0 text-muted small">
                Go to <strong>Environments → Cluster → Components</strong> to install an operator.
            </p>
        </div>
    </div>
}
else
{
    @* ── Operator availability badges ── *@
    <div class="d-flex gap-2 mb-4">
        @if (operatorStatus!.CnpgAvailable)
        {
            <span class="badge bg-success-subtle text-success border border-success-subtle px-3 py-2">
                <i class="bi bi-database me-1"></i>PostgreSQL (CNPG)
                <small class="ms-1 opacity-75">on @operatorStatus.CnpgClusterName</small>
            </span>
        }
        else
        {
            <span class="badge bg-secondary-subtle text-secondary border px-3 py-2">
                <i class="bi bi-database me-1"></i>PostgreSQL (CNPG) — not installed
            </span>
        }

        @if (operatorStatus.MongoDbAvailable)
        {
            <span class="badge bg-success-subtle text-success border border-success-subtle px-3 py-2">
                <i class="bi bi-database-gear me-1"></i>MongoDB
                <small class="ms-1 opacity-75">on @operatorStatus.MongoDbClusterName</small>
            </span>
        }
        else
        {
            <span class="badge bg-secondary-subtle text-secondary border px-3 py-2">
                <i class="bi bi-database-gear me-1"></i>MongoDB — not installed
            </span>
        }
    </div>

    @* ── Environment Tabs ── *@
    @if (AllEnvironments.Count > 0)
    {
        <ul class="nav nav-pills mb-4 gap-1 flex-wrap">
            <li class="nav-item">
                <button class="nav-link @(selectedEnvironment is null ? "active" : "")"
                        @onclick="() => selectedEnvironment = null">
                    <i class="bi bi-layers me-1"></i>All
                </button>
            </li>
            @foreach (string env in AllEnvironments)
            {
                <li class="nav-item">
                    <button class="nav-link @(selectedEnvironment == env ? "active" : "")"
                            @onclick="() => selectedEnvironment = env">
                        @env
                    </button>
                </li>
            }
        </ul>
    }

    @* ── PostgreSQL Clusters ── *@
    @if (operatorStatus.CnpgAvailable)
    {
        <div class="mb-4">
            <h5 class="d-flex align-items-center gap-2 mb-3">
                <i class="bi bi-database text-primary"></i>PostgreSQL Clusters
                @if (FilteredCnpgClusters is not null)
                {
                    <span class="badge bg-primary rounded-pill">@FilteredCnpgClusters.Count</span>
                }
            </h5>

            @if (FilteredCnpgClusters is null)
            {
                <div class="text-center py-3">
                    <div class="spinner-border spinner-border-sm text-primary" role="status"></div>
                </div>
            }
            else if (FilteredCnpgClusters.Count == 0)
            {
                <div class="alert alert-light border">
                    <i class="bi bi-inbox me-2"></i>
                    No PostgreSQL clusters discovered on Kubernetes.
                </div>
            }
            else
            {
                <div class="row g-3">
                    @foreach (DatabaseClusterInfo dbCluster in FilteredCnpgClusters)
                    {
                        <div class="col-md-6 col-lg-4">
                            <div class="card h-100 shadow-sm">
                                <div class="card-header bg-white d-flex align-items-center justify-content-between py-2">
                                    <div class="d-flex align-items-center gap-2">
                                        <i class="bi bi-database text-primary"></i>
                                        <strong class="small">@dbCluster.Name</strong>
                                    </div>
                                    @(GetStatusBadge(dbCluster.Status))
                                </div>
                                <div class="card-body py-2">
                                    <div class="row small text-muted">
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-layers me-1"></i>@dbCluster.EnvironmentName
                                        </div>
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-server me-1"></i>@dbCluster.ClusterName
                                        </div>
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-box me-1"></i>@dbCluster.Namespace
                                        </div>
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-hdd-stack me-1"></i>@dbCluster.Instances instance(s)
                                        </div>
                                        @if (dbCluster.Storage is not null)
                                        {
                                            <div class="col-6 mb-1">
                                                <i class="bi bi-device-hdd me-1"></i>@dbCluster.Storage
                                            </div>
                                        }
                                        @if (dbCluster.Version is not null)
                                        {
                                            <div class="col-12 mb-1">
                                                <i class="bi bi-tag me-1"></i>@dbCluster.Version
                                            </div>
                                        }
                                    </div>

                                    @if (dbCluster.Databases.Count > 0)
                                    {
                                        <hr class="my-2" />
                                        <div class="small">
                                            <strong class="text-muted">Databases:</strong>
                                            @foreach (string dbName in dbCluster.Databases)
                                            {
                                                <span class="badge bg-light text-dark border me-1">@dbName</span>
                                            }
                                        </div>
                                    }

                                    @if (dbCluster.PrimaryPod is not null)
                                    {
                                        <div class="small text-muted mt-1">
                                            <i class="bi bi-star me-1"></i>Primary: <code>@dbCluster.PrimaryPod</code>
                                        </div>
                                    }
                                </div>
                                @if (dbCluster.CreatedAt.HasValue)
                                {
                                    <div class="card-footer bg-white py-1">
                                        <small class="text-muted">Created @dbCluster.CreatedAt.Value.ToString("yyyy-MM-dd HH:mm")</small>
                                    </div>
                                }
                            </div>
                        </div>
                    }
                </div>
            }
        </div>
    }

    @* ── Managed CNPG Clusters ── *@
    @if (operatorStatus!.CnpgAvailable)
    {
        <div class="mb-4">
            <h5 class="d-flex align-items-center gap-2 mb-3">
                <i class="bi bi-database-add text-primary"></i>Managed PostgreSQL Clusters
                @if (FilteredManagedClusters is not null)
                {
                    <span class="badge bg-primary rounded-pill">@FilteredManagedClusters.Count</span>
                }
                <button class="btn btn-sm btn-primary ms-auto" @onclick="ShowCreateForm" disabled="@showCreate">
                    <i class="bi bi-plus-lg me-1"></i>Create Cluster
                </button>
            </h5>

            @* ── Create Cluster Form ── *@
            @if (showCreate)
            {
                <div class="card shadow-sm mb-3 border-primary">
                    <div class="card-header bg-primary bg-opacity-10 d-flex align-items-center justify-content-between">
                        <h6 class="mb-0"><i class="bi bi-database-add me-2"></i>New CNPG Cluster</h6>
                        <button class="btn btn-sm btn-outline-secondary border-0" @onclick="CancelCreate"><i class="bi bi-x-lg"></i></button>
                    </div>
                    <div class="card-body">
                        <div class="row g-3">
                            <div class="col-md-6">
                                <label class="form-label small">Cluster Name</label>
                                <input class="form-control form-control-sm" @bind="createName" placeholder="my-postgres" />
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Namespace</label>
                                <input class="form-control form-control-sm" @bind="createNamespace" placeholder="databases" />
                            </div>
                            <div class="col-md-4">
                                <label class="form-label small">Target Cluster</label>
                                <select class="form-select form-select-sm" @bind="createClusterId">
                                    <option value="@Guid.Empty">Select cluster...</option>
                                    @if (availableClusters is not null)
                                    {
                                        @foreach (KubernetesCluster k in availableClusters)
                                        {
                                            <option value="@k.Id">@k.Name</option>
                                        }
                                    }
                                </select>
                            </div>
                            <div class="col-md-4">
                                <label class="form-label small">Instances (HA)</label>
                                <select class="form-select form-select-sm" @bind="createInstances">
                                    <option value="1">1 (Standalone)</option>
                                    <option value="2">2 (Primary + Replica)</option>
                                    <option value="3">3 (HA)</option>
                                </select>
                            </div>
                            <div class="col-md-4">
                                <label class="form-label small">Storage Size</label>
                                <input class="form-control form-control-sm" @bind="createStorageSize" placeholder="10Gi" />
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Backup S3 Bucket (optional)</label>
                                <select class="form-select form-select-sm" @bind="createStorageLinkId">
                                    <option value="@Guid.Empty">No backup</option>
                                    @if (storageLinks is not null)
                                    {
                                        @foreach (StorageLink sl in storageLinks)
                                        {
                                            <option value="@sl.Id">@sl.Name (@sl.BucketName)</option>
                                        }
                                    }
                                </select>
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Backup Schedule (cron, optional)</label>
                                <input class="form-control form-control-sm" @bind="createSchedule" placeholder="0 0 2 * * *" />
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Backup Retention (days)</label>
                                <input type="number" class="form-control form-control-sm" @bind="createRetentionDays" min="1" max="365" />
                            </div>
                        </div>
                        <div class="mt-3 d-flex align-items-center gap-2">
                            <button class="btn btn-sm btn-primary" @onclick="CreateCluster" disabled="@creating">
                                @if (creating)
                                {
                                    <span class="spinner-border spinner-border-sm me-1"></span>
                                    <text>Creating...</text>
                                }
                                else
                                {
                                    <i class="bi bi-plus-lg me-1"></i>
                                    <text>Create PostgreSQL 18 Cluster</text>
                                }
                            </button>
                            <button class="btn btn-sm btn-outline-secondary" @onclick="CancelCreate">Cancel</button>
                        </div>
                        @if (!string.IsNullOrEmpty(createError))
                        {
                            <div class="alert alert-danger small mt-2 mb-0 py-2">
                                <i class="bi bi-exclamation-triangle me-1"></i>@createError
                            </div>
                        }
                    </div>
                </div>
            }

            @* ── Managed Cluster Cards ── *@
            @if (FilteredManagedClusters is null)
            {
                <div class="text-center py-3">
                    <div class="spinner-border spinner-border-sm text-primary" role="status"></div>
                </div>
            }
            else if (FilteredManagedClusters.Count == 0 && !showCreate)
            {
                <div class="alert alert-light border">
                    <i class="bi bi-inbox me-2"></i>
                    No managed clusters yet. Click "Create Cluster" to provision a new PostgreSQL 18 cluster.
                </div>
            }
            else
            {
                @foreach (CnpgCluster mc in FilteredManagedClusters)
                {
                    <div class="card shadow-sm mb-3">
                        <div class="card-header bg-white d-flex align-items-center justify-content-between py-2">
                            <div class="d-flex align-items-center gap-2 cursor-pointer" @onclick="() => ToggleClusterDetail(mc)">
                                <i class="bi @(expandedClusterId == mc.Id ? "bi-chevron-down" : "bi-chevron-right") text-muted"></i>
                                <i class="bi bi-database text-primary"></i>
                                <strong>@mc.Name</strong>
                                <span class="badge bg-light text-dark border small">PG @mc.PostgresVersion</span>
                                @(GetManagedStatusBadge(mc.Status))
                                <span class="badge bg-primary-subtle text-primary border border-primary-subtle small">
                                    <i class="bi bi-layers me-1"></i>@mc.KubernetesCluster.Environment.Name
                                </span>
                                @if (mc.Databases.Count > 0)
                                {
                                    <span class="badge bg-secondary-subtle text-secondary">@mc.Databases.Count db(s)</span>
                                }
                            </div>
                            <div class="d-flex gap-1">
                                <button class="btn btn-sm btn-outline-primary border-0" title="Add Database"
                                        @onclick="() => ShowAddDatabase(mc)">
                                    <i class="bi bi-plus-circle"></i>
                                </button>
                                @if (mc.StorageLinkId.HasValue)
                                {
                                    <button class="btn btn-sm btn-outline-info border-0" title="Backup Now"
                                            @onclick="() => TriggerBackup(mc.Id)" disabled="@(backingUpId == mc.Id)">
                                        @if (backingUpId == mc.Id)
                                        {
                                            <span class="spinner-border spinner-border-sm"></span>
                                        }
                                        else
                                        {
                                            <i class="bi bi-cloud-arrow-up"></i>
                                        }
                                    </button>
                                    <button class="btn btn-sm btn-outline-info border-0"
                                            title="@(string.IsNullOrWhiteSpace(mc.BackupSchedule) ? "Configure Scheduled Backup" : $"Apply Scheduled Backup ({mc.BackupSchedule})")"
                                            @onclick="() => ToggleScheduleForm(mc)" disabled="@(applyingScheduledBackupId == mc.Id)">
                                        @if (applyingScheduledBackupId == mc.Id)
                                        {
                                            <span class="spinner-border spinner-border-sm"></span>
                                        }
                                        else
                                        {
                                            <i class="bi bi-calendar-check"></i>
                                        }
                                    </button>
                                    <button class="btn btn-sm btn-outline-warning border-0" title="Point-in-Time Restore"
                                            @onclick="() => ShowRestore(mc)">
                                        <i class="bi bi-clock-history"></i>
                                    </button>
                                }
                                <button class="btn btn-sm btn-outline-secondary border-0" title="Upgrade"
                                        @onclick="() => ShowUpgrade(mc)">
                                    <i class="bi bi-arrow-up-circle"></i>
                                </button>
                                <button class="btn btn-sm btn-outline-danger border-0" title="Delete Cluster"
                                        @onclick="() => DeleteCluster(mc.Id)" disabled="@(deletingId == mc.Id)">
                                    @if (deletingId == mc.Id)
                                    {
                                        <span class="spinner-border spinner-border-sm"></span>
                                    }
                                    else
                                    {
                                        <i class="bi bi-trash"></i>
                                    }
                                </button>
                            </div>
                        </div>

                        @* ── Expanded Detail Panel ── *@
                        @if (expandedClusterId == mc.Id)
                        {
                            <div class="card-body pt-2 pb-3">
                                @if (loadingDetail)
                                {
                                    <div class="text-center py-3">
                                        <div class="spinner-border spinner-border-sm text-primary"></div>
                                        <small class="text-muted ms-2">Querying cluster status...</small>
                                    </div>
                                }
                                else if (clusterDetail is not null)
                                {
                                    @* ── Cluster Overview ── *@
                                    <div class="row g-2 mb-3">
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">Phase</div>
                                                <div class="fw-semibold">
                                                    @if (clusterDetail.Phase.Contains("healthy", StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        <span class="text-success"><i class="bi bi-check-circle me-1"></i>@clusterDetail.Phase</span>
                                                    }
                                                    else if (clusterDetail.Phase.Contains("Creating", StringComparison.OrdinalIgnoreCase)
                                                             || clusterDetail.Phase.Contains("Setting", StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        <span class="text-warning"><i class="bi bi-hourglass me-1"></i>@clusterDetail.Phase</span>
                                                    }
                                                    else
                                                    {
                                                        <span>@clusterDetail.Phase</span>
                                                    }
                                                </div>
                                            </div>
                                        </div>
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">Ready</div>
                                                <div class="fw-semibold">@clusterDetail.ReadyInstances / @mc.Instances</div>
                                            </div>
                                        </div>
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">Primary</div>
                                                <div class="fw-semibold text-truncate">@(clusterDetail.CurrentPrimary ?? "—")</div>
                                            </div>
                                        </div>
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">Info</div>
                                                <div class="fw-semibold">
                                                    <span class="me-2"><i class="bi bi-server me-1"></i>@mc.KubernetesCluster.Name</span>
                                                    <span><i class="bi bi-box me-1"></i>@mc.Namespace</span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                    @* ── Pod Table ── *@
                                    <h6 class="small text-muted mb-2"><i class="bi bi-hdd-stack me-1"></i>Pods</h6>
                                    @if (clusterDetail.Pods.Count > 0)
                                    {
                                        <div class="table-responsive mb-3">
                                            <table class="table table-sm table-hover small mb-0">
                                                <thead class="table-light">
                                                    <tr>
                                                        <th>Pod</th>
                                                        <th>Role</th>
                                                        <th>Status</th>
                                                        <th>Ready</th>
                                                        <th>Node</th>
                                                        <th>Age</th>
                                                        <th>Restarts</th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    @foreach (CnpgPodInfo pod in clusterDetail.Pods)
                                                    {
                                                        <tr>
                                                            <td class="font-monospace">@pod.Name</td>
                                                            <td>
                                                                @if (pod.Role == "primary")
                                                                {
                                                                    <span class="badge bg-primary">
                                                                        <i class="bi bi-star-fill me-1"></i>Primary
                                                                    </span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="badge bg-secondary-subtle text-secondary">
                                                                        <i class="bi bi-arrow-repeat me-1"></i>Replica
                                                                    </span>
                                                                }
                                                            </td>
                                                            <td>
                                                                @if (pod.Status == "Running")
                                                                {
                                                                    <span class="text-success"><i class="bi bi-circle-fill me-1" style="font-size:0.5rem;"></i>Running</span>
                                                                }
                                                                else if (pod.Status == "Pending")
                                                                {
                                                                    <span class="text-warning"><i class="bi bi-circle-fill me-1" style="font-size:0.5rem;"></i>Pending</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="text-danger"><i class="bi bi-circle-fill me-1" style="font-size:0.5rem;"></i>@pod.Status</span>
                                                                }
                                                            </td>
                                                            <td>
                                                                @if (pod.Ready)
                                                                {
                                                                    <i class="bi bi-check-circle text-success"></i>
                                                                }
                                                                else
                                                                {
                                                                    <i class="bi bi-x-circle text-danger"></i>
                                                                }
                                                            </td>
                                                            <td class="text-truncate" style="max-width: 150px;">@(pod.Node ?? "—")</td>
                                                            <td>@FormatAge(pod.StartTime)</td>
                                                            <td>
                                                                @if (pod.Restarts > 0)
                                                                {
                                                                    <span class="text-warning">@pod.Restarts</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="text-muted">0</span>
                                                                }
                                                            </td>
                                                        </tr>
                                                    }
                                                </tbody>
                                            </table>
                                        </div>
                                    }
                                    else
                                    {
                                        <div class="alert alert-warning small py-2 mb-3">
                                            <i class="bi bi-exclamation-triangle me-1"></i>No pods found. Cluster may still be initializing.
                                        </div>
                                    }

                                    @* ── Databases ── *@
                                    <h6 class="small text-muted mb-2 d-flex align-items-center">
                                        <i class="bi bi-table me-1"></i>Databases
                                        <span class="badge bg-primary rounded-pill ms-2">@mc.Databases.Count</span>
                                    </h6>
                                    @if (mc.Databases.Count > 0)
                                    {
                                        <div class="table-responsive mb-3">
                                            <table class="table table-sm small mb-0">
                                                <thead class="table-light">
                                                    <tr>
                                                        <th>Database</th>
                                                        <th>Owner</th>
                                                        <th>Status</th>
                                                        <th>Created</th>
                                                        <th></th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    @foreach (CnpgDatabase cdb in mc.Databases)
                                                    {
                                                        <tr>
                                                            <td class="font-monospace">@cdb.Name</td>
                                                            <td class="font-monospace text-muted">@cdb.Owner</td>
                                                            <td>
                                                                @if (cdb.Status == CnpgDatabaseStatus.Ready)
                                                                {
                                                                    <span class="badge bg-success-subtle text-success">Ready</span>
                                                                }
                                                                else if (cdb.Status == CnpgDatabaseStatus.Creating)
                                                                {
                                                                    <span class="badge bg-warning-subtle text-warning">Creating</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="badge bg-danger-subtle text-danger">@cdb.Status</span>
                                                                }
                                                            </td>
                                                            <td class="text-muted">@cdb.CreatedAt.ToString("yyyy-MM-dd HH:mm")</td>
                                                            <td>
                                                                <button class="btn btn-link btn-sm text-info p-0 me-2" title="View credentials"
                                                                        @onclick="() => ToggleDatabaseCredentials(mc.Id, cdb.Id)">
                                                                    <i class="bi bi-key" style="font-size:0.8rem;"></i>
                                                                </button>
                                                                <button class="btn btn-link btn-sm text-primary p-0 me-2" title="Sync credentials to K8s Secret"
                                                                        @onclick="() => SyncDatabaseCredentialsToK8s(mc.Id, cdb.Id)">
                                                                    <i class="bi bi-cloud-arrow-up" style="font-size:0.8rem;"></i>
                                                                </button>
                                                                <button class="btn btn-link btn-sm text-warning p-0 me-2" title="Rotate password"
                                                                        disabled="@(rotatingDatabaseId == cdb.Id)"
                                                                        @onclick="() => RotateDatabasePassword(mc.Id, cdb.Id)">
                                                                    @if (rotatingDatabaseId == cdb.Id)
                                                                    {
                                                                        <span class="spinner-border spinner-border-sm" role="status" style="width:0.7rem;height:0.7rem;"></span>
                                                                    }
                                                                    else
                                                                    {
                                                                        <i class="bi bi-arrow-clockwise" style="font-size:0.8rem;"></i>
                                                                    }
                                                                </button>
                                                                <button class="btn btn-link btn-sm text-danger p-0" title="Drop database"
                                                                        @onclick="() => DeleteDatabase(mc.Id, cdb.Id)">
                                                                    <i class="bi bi-trash" style="font-size:0.8rem;"></i>
                                                                </button>
                                                            </td>
                                                        </tr>
                                                        @if (credentialsDatabaseId == cdb.Id && databaseCredentials is not null)
                                                        {
                                                            <tr>
                                                                <td colspan="5" class="bg-light p-0">
                                                                    <div class="p-2">
                                                                        <table class="table table-sm table-borderless mb-1" style="font-size:0.75rem;">
                                                                            <tbody>
                                                                                @foreach (KeyValuePair<string, string> cred in databaseCredentials)
                                                                                {
                                                                                    <tr>
                                                                                        <td class="text-muted fw-bold" style="width:100px;">@cred.Key</td>
                                                                                        <td><code class="user-select-all">@cred.Value</code></td>
                                                                                    </tr>
                                                                                }
                                                                            </tbody>
                                                                        </table>
                                                                        <div class="text-muted" style="font-size:0.7rem;">
                                                                            <i class="bi bi-info-circle me-1"></i>K8s Secret: <code>@($"{mc.Name}-{cdb.Name}-credentials")</code> in namespace <code>@mc.Namespace</code>
                                                                        </div>
                                                                    </div>
                                                                </td>
                                                            </tr>
                                                        }
                                                    }
                                                </tbody>
                                            </table>
                                        </div>
                                    }
                                    else
                                    {
                                        <p class="small text-muted mb-3">No databases created yet. Use the <i class="bi bi-plus-circle"></i> button to add one.</p>
                                    }

                                    @* ── Backups ── *@
                                    <h6 class="small text-muted mb-2 d-flex align-items-center">
                                        <i class="bi bi-cloud-arrow-up me-1"></i>Backups
                                        <span class="badge bg-info rounded-pill ms-2">@clusterDetail.Backups.Count</span>
                                    </h6>
                                    @if (clusterDetail.Backups.Count > 0)
                                    {
                                        <div class="table-responsive">
                                            <table class="table table-sm small mb-0">
                                                <thead class="table-light">
                                                    <tr>
                                                        <th>Name</th>
                                                        <th>Type</th>
                                                        <th>Status</th>
                                                        <th>Started</th>
                                                        <th>Completed</th>
                                                        <th>Size</th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    @foreach (CnpgBackup bk in clusterDetail.Backups)
                                                    {
                                                        <tr class="@(selectedCnpgBackup?.Name == bk.Name && selectedCnpgBackupCluster?.Id == mc.Id ? "table-warning" : "")"
                                                            style="cursor:pointer" title="Click to restore from this backup"
                                                            @onclick="() => SelectCnpgBackup(mc, bk)">
                                                            <td class="font-monospace text-truncate" style="max-width: 200px;">@bk.Name</td>
                                                            <td>
                                                                @if (bk.Type == CnpgBackupType.Scheduled)
                                                                {
                                                                    <span class="badge bg-light text-dark border"><i class="bi bi-clock me-1"></i>Scheduled</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="badge bg-light text-dark border"><i class="bi bi-hand-index me-1"></i>On-Demand</span>
                                                                }
                                                            </td>
                                                            <td>
                                                                @if (bk.Status == CnpgBackupStatus.Completed)
                                                                {
                                                                    <span class="badge bg-success-subtle text-success"><i class="bi bi-check-circle me-1"></i>Completed</span>
                                                                }
                                                                else if (bk.Status == CnpgBackupStatus.Running)
                                                                {
                                                                    <span class="badge bg-warning-subtle text-warning"><i class="bi bi-hourglass-split me-1"></i>Running</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="badge bg-danger-subtle text-danger"><i class="bi bi-x-circle me-1"></i>Failed</span>
                                                                }
                                                            </td>
                                                            <td class="text-muted">@bk.StartedAt.ToString("yyyy-MM-dd HH:mm")</td>
                                                            <td class="text-muted">@(bk.CompletedAt?.ToString("HH:mm") ?? "—")</td>
                                                            <td class="text-muted">@(bk.SizeBytes.HasValue ? FormatBytes(bk.SizeBytes.Value) : "—")</td>
                                                        </tr>
                                                    }
                                                </tbody>
                                            </table>
                                        </div>
                                    }
                                    else if (mc.StorageLinkId.HasValue)
                                    {
                                        <p class="small text-muted mb-2">No backups yet. Click <i class="bi bi-cloud-arrow-up"></i> to create one.</p>
                                    }
                                    else
                                    {
                                        <p class="small text-muted">Backups are not configured. Assign an S3 bucket to enable backups.</p>
                                    }

                                    @* ── Backup Restore Panel (CNPG) ── *@
                                    @if (selectedCnpgBackup != null && selectedCnpgBackupCluster?.Id == mc.Id)
                                    {
                                        <div class="card border-warning mt-2">
                                            <div class="card-header bg-warning bg-opacity-10 d-flex align-items-center justify-content-between py-2">
                                                <h6 class="mb-0 small">
                                                    <i class="bi bi-clock-history me-2"></i>Restore from <strong>@selectedCnpgBackup.Name</strong>
                                                    <span class="text-muted ms-2">(@(selectedCnpgBackup.CompletedAt?.ToString("yyyy-MM-dd HH:mm") ?? selectedCnpgBackup.StartedAt.ToString("yyyy-MM-dd HH:mm")))</span>
                                                </h6>
                                                <button class="btn btn-sm btn-outline-secondary border-0"
                                                        @onclick="() => { selectedCnpgBackup = null; selectedCnpgBackupCluster = null; backupRestoreError = null; }">
                                                    <i class="bi bi-x-lg"></i>
                                                </button>
                                            </div>
                                            <div class="card-body py-2">
                                                <div class="d-flex gap-4 mb-3">
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="radio" name="cnpg-restore-target-@mc.Id"
                                                               id="cnpg-rt-current-@mc.Id" checked="@(backupRestoreTarget == "current")"
                                                               @onchange="@(_ => backupRestoreTarget = "current")" />
                                                        <label class="form-check-label small" for="cnpg-rt-current-@mc.Id">
                                                            <i class="bi bi-arrow-counterclockwise me-1"></i>Current cluster
                                                        </label>
                                                    </div>
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="radio" name="cnpg-restore-target-@mc.Id"
                                                               id="cnpg-rt-new-@mc.Id" checked="@(backupRestoreTarget == "new")"
                                                               @onchange="@(_ => backupRestoreTarget = "new")" />
                                                        <label class="form-check-label small" for="cnpg-rt-new-@mc.Id">
                                                            <i class="bi bi-plus-circle me-1"></i>New cluster
                                                        </label>
                                                    </div>
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="radio" name="cnpg-restore-target-@mc.Id"
                                                               id="cnpg-rt-external-@mc.Id" checked="@(backupRestoreTarget == "external")"
                                                               @onchange="@(_ => backupRestoreTarget = "external")" />
                                                        <label class="form-check-label small" for="cnpg-rt-external-@mc.Id">
                                                            <i class="bi bi-cloud me-1"></i>External connection
                                                        </label>
                                                    </div>
                                                </div>

                                                @if (backupRestoreTarget == "current")
                                                {
                                                    <div class="alert alert-warning small py-2 mb-2">
                                                        <i class="bi bi-exclamation-triangle me-1"></i>
                                                        <strong>Destructive:</strong> Deletes the running cluster and recreates it from this backup. All data after the backup point is lost.
                                                    </div>
                                                }
                                                else if (backupRestoreTarget == "new")
                                                {
                                                    <div class="row g-2 mb-2">
                                                        <div class="col-md-6">
                                                            <label class="form-label small">New Cluster Name</label>
                                                            <input class="form-control form-control-sm" @bind="backupRestoreNewName" placeholder="@(mc.Name + "-restored")" />
                                                        </div>
                                                    </div>
                                                }
                                                else if (backupRestoreTarget == "external")
                                                {
                                                    <div class="alert alert-info small py-2 mb-2">
                                                        <i class="bi bi-info-circle me-1"></i>
                                                        CNPG uses physical (Barman) backups that cannot be directly restored to an external PostgreSQL server.
                                                        Use <strong>New cluster</strong> to restore within Kubernetes, then use <code>pg_dump</code> to export specific databases.
                                                    </div>
                                                }

                                                <div class="d-flex gap-2">
                                                    <button class="btn btn-sm btn-warning" @onclick="ExecuteBackupRestore"
                                                            disabled="@(backupRestoring || backupRestoreTarget == "external")">
                                                        @if (backupRestoring) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                                        Restore
                                                    </button>
                                                    <button class="btn btn-sm btn-outline-secondary"
                                                            @onclick="() => { selectedCnpgBackup = null; selectedCnpgBackupCluster = null; backupRestoreError = null; }">
                                                        Cancel
                                                    </button>
                                                </div>

                                                @if (!string.IsNullOrEmpty(backupRestoreError))
                                                {
                                                    <div class="alert alert-danger small py-1 mt-2 mb-0">@backupRestoreError</div>
                                                }
                                            </div>
                                        </div>
                                    }

                                    @if (configuringScheduleId == mc.Id)
                                    {
                                        <div class="d-flex align-items-center gap-2 mt-2">
                                            <input class="form-control form-control-sm" style="max-width:180px;"
                                                   @bind="scheduleInput" placeholder="0 0 2 * * *" />
                                            <button class="btn btn-sm btn-primary"
                                                    @onclick="() => ApplyScheduledBackup(mc.Id, scheduleInput)"
                                                    disabled="@(applyingScheduledBackupId == mc.Id || string.IsNullOrWhiteSpace(scheduleInput))">
                                                Apply
                                            </button>
                                            <button class="btn btn-sm btn-outline-secondary" @onclick="CancelScheduleForm">Cancel</button>
                                        </div>
                                    }
                                }

                                @if (!string.IsNullOrEmpty(mc.LastError))
                                {
                                    <div class="alert alert-danger small py-1 mt-2 mb-0">
                                        <i class="bi bi-exclamation-triangle me-1"></i>@mc.LastError
                                    </div>
                                }
                            </div>
                        }
                        else
                        {
                            @* ── Collapsed Summary Row ── *@
                            <div class="card-body py-2">
                                <div class="row small text-muted">
                                    <div class="col-auto">
                                        <i class="bi bi-server me-1"></i>@mc.KubernetesCluster.Name
                                    </div>
                                    <div class="col-auto">
                                        <i class="bi bi-box me-1"></i>@mc.Namespace
                                    </div>
                                    <div class="col-auto">
                                        <i class="bi bi-hdd-stack me-1"></i>@mc.Instances instance(s)
                                    </div>
                                    <div class="col-auto">
                                        <i class="bi bi-device-hdd me-1"></i>@mc.StorageSize
                                    </div>
                                    @if (mc.StorageLink is not null)
                                    {
                                        <div class="col-auto">
                                            <i class="bi bi-cloud me-1"></i>@mc.StorageLink.BucketName
                                        </div>
                                    }
                                    @if (mc.Databases.Count > 0)
                                    {
                                        <div class="col-auto">
                                            <i class="bi bi-table me-1"></i>@string.Join(", ", mc.Databases.Select(d => d.Name))
                                        </div>
                                    }
                                </div>
                            </div>
                        }
                    </div>
                }
            }

            @* ── Add Database Form ── *@
            @if (addDbCluster is not null)
            {
                <div class="card shadow-sm mb-3 border-success">
                    <div class="card-header bg-success bg-opacity-10">
                        <h6 class="mb-0"><i class="bi bi-plus-circle me-2"></i>Add Database to <strong>@addDbCluster.Name</strong></h6>
                    </div>
                    <div class="card-body">
                        <div class="row g-3 align-items-end">
                            <div class="col-md-6">
                                <label class="form-label small">Database Name</label>
                                <input class="form-control form-control-sm" @bind="newDbName" placeholder="myapp" />
                            </div>
                            <div class="col-md-6 d-flex gap-2">
                                <button class="btn btn-sm btn-success" @onclick="AddDatabase" disabled="@addingDb">
                                    @if (addingDb) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                    Create
                                </button>
                                <button class="btn btn-sm btn-outline-secondary" @onclick="() => addDbCluster = null">Cancel</button>
                            </div>
                        </div>
                        @if (!string.IsNullOrEmpty(dbError))
                        {
                            <div class="alert alert-danger small py-1 mt-2 mb-0">@dbError</div>
                        }
                    </div>
                </div>
            }

            @* ── Restore Form ── *@
            @if (restoreSource is not null)
            {
                <div class="card shadow-sm mb-3 border-warning">
                    <div class="card-header bg-warning bg-opacity-10">
                        <h6 class="mb-0"><i class="bi bi-clock-history me-2"></i>Point-in-Time Restore from <strong>@restoreSource.Name</strong></h6>
                    </div>
                    <div class="card-body">
                        <div class="row g-3 align-items-end">
                            <div class="col-md-4">
                                <label class="form-label small">New Cluster Name</label>
                                <input class="form-control form-control-sm" @bind="restoreName" placeholder="restored-cluster" />
                            </div>
                            <div class="col-md-4">
                                <label class="form-label small">Target Time (UTC)</label>
                                <input type="datetime-local" class="form-control form-control-sm" @bind="restoreTargetTime" />
                            </div>
                            <div class="col-md-4 d-flex gap-2">
                                <button class="btn btn-sm btn-warning" @onclick="ExecuteRestore" disabled="@restoring">
                                    @if (restoring) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                    Restore
                                </button>
                                <button class="btn btn-sm btn-outline-secondary" @onclick="() => restoreSource = null">Cancel</button>
                            </div>
                        </div>
                        @if (!string.IsNullOrEmpty(restoreError))
                        {
                            <div class="alert alert-danger small py-1 mt-2 mb-0">@restoreError</div>
                        }
                    </div>
                </div>
            }

            @* ── Upgrade Form ── *@
            @if (upgradeCluster is not null)
            {
                <div class="card shadow-sm mb-3 border-secondary">
                    <div class="card-header bg-secondary bg-opacity-10">
                        <h6 class="mb-0"><i class="bi bi-arrow-up-circle me-2"></i>Upgrade <strong>@upgradeCluster.Name</strong> (currently PG @upgradeCluster.PostgresVersion)</h6>
                    </div>
                    <div class="card-body">
                        <div class="row g-3 align-items-end">
                            <div class="col-md-4">
                                <label class="form-label small">Target Version</label>
                                <select class="form-select form-select-sm" @bind="upgradeVersion">
                                    <option value="18">PostgreSQL 18</option>
                                    <option value="17">PostgreSQL 17</option>
                                    <option value="16">PostgreSQL 16</option>
                                </select>
                            </div>
                            <div class="col-md-4 d-flex gap-2">
                                <button class="btn btn-sm btn-secondary" @onclick="ExecuteUpgrade" disabled="@upgrading">
                                    @if (upgrading) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                    Upgrade
                                </button>
                                <button class="btn btn-sm btn-outline-secondary" @onclick="() => upgradeCluster = null">Cancel</button>
                            </div>
                        </div>
                        @if (!string.IsNullOrEmpty(upgradeError))
                        {
                            <div class="alert alert-danger small py-1 mt-2 mb-0">@upgradeError</div>
                        }
                    </div>
                </div>
            }
        </div>
    }

    @* ── MongoDB Clusters ── *@
    @if (operatorStatus.MongoDbAvailable)
    {
        <div class="mb-4">
            <h5 class="d-flex align-items-center gap-2 mb-3">
                <i class="bi bi-database-gear text-success"></i>MongoDB Clusters
                @if (FilteredMongoClusters is not null)
                {
                    <span class="badge bg-success rounded-pill">@FilteredMongoClusters.Count</span>
                }
            </h5>

            @if (FilteredMongoClusters is null)
            {
                <div class="text-center py-3">
                    <div class="spinner-border spinner-border-sm text-success" role="status"></div>
                </div>
            }
            else if (FilteredMongoClusters.Count == 0)
            {
                <div class="alert alert-light border">
                    <i class="bi bi-inbox me-2"></i>
                    No MongoDB clusters discovered on Kubernetes.
                </div>
            }
            else
            {
                <div class="row g-3">
                    @foreach (DatabaseClusterInfo dbCluster in FilteredMongoClusters)
                    {
                        <div class="col-md-6 col-lg-4">
                            <div class="card h-100 shadow-sm">
                                <div class="card-header bg-white d-flex align-items-center justify-content-between py-2">
                                    <div class="d-flex align-items-center gap-2">
                                        <i class="bi bi-database-gear text-success"></i>
                                        <strong class="small">@dbCluster.Name</strong>
                                    </div>
                                    @(GetStatusBadge(dbCluster.Status))
                                </div>
                                <div class="card-body py-2">
                                    <div class="row small text-muted">
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-layers me-1"></i>@dbCluster.EnvironmentName
                                        </div>
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-server me-1"></i>@dbCluster.ClusterName
                                        </div>
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-box me-1"></i>@dbCluster.Namespace
                                        </div>
                                        <div class="col-6 mb-1">
                                            <i class="bi bi-hdd-stack me-1"></i>@dbCluster.Instances member(s)
                                        </div>
                                        @if (dbCluster.Version is not null)
                                        {
                                            <div class="col-6 mb-1">
                                                <i class="bi bi-tag me-1"></i>v@dbCluster.Version
                                            </div>
                                        }
                                    </div>

                                    @if (dbCluster.Databases.Count > 0)
                                    {
                                        <hr class="my-2" />
                                        <div class="small">
                                            <strong class="text-muted">Databases:</strong>
                                            @foreach (string dbName in dbCluster.Databases)
                                            {
                                                <span class="badge bg-light text-dark border me-1">@dbName</span>
                                            }
                                        </div>
                                    }
                                </div>
                                @if (dbCluster.CreatedAt.HasValue)
                                {
                                    <div class="card-footer bg-white py-1">
                                        <small class="text-muted">Created @dbCluster.CreatedAt.Value.ToString("yyyy-MM-dd HH:mm")</small>
                                    </div>
                                }
                            </div>
                        </div>
                    }
                </div>
            }
        </div>
    }

    @* ── Managed MongoDB Clusters ── *@
    @if (operatorStatus!.MongoDbAvailable)
    {
        <div class="mb-4">
            <h5 class="d-flex align-items-center gap-2 mb-3">
                <i class="bi bi-database-add text-success"></i>Managed MongoDB Clusters
                @if (FilteredManagedMongoClusters is not null)
                {
                    <span class="badge bg-success rounded-pill">@FilteredManagedMongoClusters.Count</span>
                }
                <button class="btn btn-sm btn-success ms-auto" @onclick="ShowMongoCreateForm" disabled="@showMongoCreate">
                    <i class="bi bi-plus-lg me-1"></i>Create Cluster
                </button>
            </h5>

            @* ── Create MongoDB Cluster Form ── *@
            @if (showMongoCreate)
            {
                <div class="card shadow-sm mb-3 border-success">
                    <div class="card-header bg-success bg-opacity-10 d-flex align-items-center justify-content-between">
                        <h6 class="mb-0"><i class="bi bi-database-add me-2"></i>New MongoDB Cluster</h6>
                        <button class="btn btn-sm btn-outline-secondary border-0" @onclick="CancelMongoCreate"><i class="bi bi-x-lg"></i></button>
                    </div>
                    <div class="card-body">
                        <div class="row g-3">
                            <div class="col-md-6">
                                <label class="form-label small">Cluster Name</label>
                                <input class="form-control form-control-sm" @bind="mongoCreateName" placeholder="my-mongo" />
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Namespace</label>
                                <input class="form-control form-control-sm" @bind="mongoCreateNamespace" placeholder="databases" />
                            </div>
                            <div class="col-md-4">
                                <label class="form-label small">Target Cluster</label>
                                <select class="form-select form-select-sm" @bind="mongoCreateClusterId">
                                    <option value="@Guid.Empty">Select cluster...</option>
                                    @if (mongoAvailableClusters is not null)
                                    {
                                        @foreach (KubernetesCluster k in mongoAvailableClusters)
                                        {
                                            <option value="@k.Id">@k.Name</option>
                                        }
                                    }
                                </select>
                            </div>
                            <div class="col-md-4">
                                <label class="form-label small">Members (Replica Set)</label>
                                <select class="form-select form-select-sm" @bind="mongoCreateMembers">
                                    <option value="1">1 (Standalone)</option>
                                    <option value="3">3 (HA)</option>
                                    <option value="5">5 (Large HA)</option>
                                </select>
                            </div>
                            <div class="col-md-4">
                                <label class="form-label small">Storage Size</label>
                                <input class="form-control form-control-sm" @bind="mongoCreateStorageSize" placeholder="10Gi" />
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Backup S3 Bucket (optional)</label>
                                <select class="form-select form-select-sm" @bind="mongoCreateStorageLinkId">
                                    <option value="@Guid.Empty">No backup</option>
                                    @if (storageLinks is not null)
                                    {
                                        @foreach (StorageLink sl in storageLinks)
                                        {
                                            <option value="@sl.Id">@sl.Name (@sl.BucketName)</option>
                                        }
                                    }
                                </select>
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Backup Schedule (cron, optional)</label>
                                <input class="form-control form-control-sm" @bind="mongoCreateSchedule" placeholder="0 2 * * *" />
                            </div>
                            <div class="col-md-6">
                                <label class="form-label small">Backup Retention (days)</label>
                                <input type="number" class="form-control form-control-sm" @bind="mongoCreateRetentionDays" min="1" max="365" />
                            </div>
                        </div>
                        <div class="mt-3 d-flex align-items-center gap-2">
                            <button class="btn btn-sm btn-success" @onclick="CreateMongoCluster" disabled="@mongoCreating">
                                @if (mongoCreating)
                                {
                                    <span class="spinner-border spinner-border-sm me-1"></span>
                                    <text>Creating...</text>
                                }
                                else
                                {
                                    <i class="bi bi-plus-lg me-1"></i>
                                    <text>Create MongoDB Cluster</text>
                                }
                            </button>
                            <button class="btn btn-sm btn-outline-secondary" @onclick="CancelMongoCreate">Cancel</button>
                        </div>
                        @if (!string.IsNullOrEmpty(mongoCreateError))
                        {
                            <div class="alert alert-danger small mt-2 mb-0 py-2">
                                <i class="bi bi-exclamation-triangle me-1"></i>@mongoCreateError
                            </div>
                        }
                    </div>
                </div>
            }

            @* ── Managed MongoDB Cluster Cards ── *@
            @if (FilteredManagedMongoClusters is null)
            {
                <div class="text-center py-3">
                    <div class="spinner-border spinner-border-sm text-success" role="status"></div>
                </div>
            }
            else if (FilteredManagedMongoClusters.Count == 0 && !showMongoCreate)
            {
                <div class="alert alert-light border">
                    <i class="bi bi-inbox me-2"></i>
                    No managed MongoDB clusters yet. Click "Create Cluster" to provision a new MongoDB replica set.
                </div>
            }
            else
            {
                @foreach (MongoCluster mc in FilteredManagedMongoClusters)
                {
                    <div class="card shadow-sm mb-3">
                        <div class="card-header bg-white d-flex align-items-center justify-content-between py-2">
                            <div class="d-flex align-items-center gap-2 cursor-pointer" @onclick="() => ToggleMongoClusterDetail(mc)">
                                <i class="bi @(expandedMongoClusterId == mc.Id ? "bi-chevron-down" : "bi-chevron-right") text-muted"></i>
                                <i class="bi bi-database-gear text-success"></i>
                                <strong>@mc.Name</strong>
                                <span class="badge bg-light text-dark border small">Mongo @mc.MongoVersion</span>
                                @(GetMongoManagedStatusBadge(mc.Status))
                                <span class="badge bg-success-subtle text-success border border-success-subtle small">
                                    <i class="bi bi-layers me-1"></i>@mc.KubernetesCluster.Environment.Name
                                </span>
                                @if (mc.Databases.Count > 0)
                                {
                                    <span class="badge bg-secondary-subtle text-secondary">@mc.Databases.Count db(s)</span>
                                }
                            </div>
                            <div class="d-flex gap-1">
                                <button class="btn btn-sm btn-outline-success border-0" title="Add Database"
                                        @onclick="() => ShowMongoAddDatabase(mc)">
                                    <i class="bi bi-plus-circle"></i>
                                </button>
                                @if (mc.StorageLinkId.HasValue)
                                {
                                    <button class="btn btn-sm btn-outline-info border-0" title="Backup Now"
                                            @onclick="() => TriggerMongoBackup(mc.Id)" disabled="@(mongoBackingUpId == mc.Id)">
                                        @if (mongoBackingUpId == mc.Id)
                                        {
                                            <span class="spinner-border spinner-border-sm"></span>
                                        }
                                        else
                                        {
                                            <i class="bi bi-cloud-arrow-up"></i>
                                        }
                                    </button>
                                    <button class="btn btn-sm btn-outline-warning border-0" title="Restore"
                                            @onclick="() => ShowMongoRestore(mc)">
                                        <i class="bi bi-clock-history"></i>
                                    </button>
                                }
                                <button class="btn btn-sm btn-outline-secondary border-0" title="Upgrade"
                                        @onclick="() => ShowMongoUpgrade(mc)">
                                    <i class="bi bi-arrow-up-circle"></i>
                                </button>
                                <button class="btn btn-sm btn-outline-danger border-0" title="Delete Cluster"
                                        @onclick="() => DeleteMongoCluster(mc.Id)" disabled="@(mongoDeletingId == mc.Id)">
                                    @if (mongoDeletingId == mc.Id)
                                    {
                                        <span class="spinner-border spinner-border-sm"></span>
                                    }
                                    else
                                    {
                                        <i class="bi bi-trash"></i>
                                    }
                                </button>
                            </div>
                        </div>

                        @* ── Expanded Mongo Detail Panel ── *@
                        @if (expandedMongoClusterId == mc.Id)
                        {
                            <div class="card-body pt-2 pb-3">
                                @if (mongoLoadingDetail)
                                {
                                    <div class="text-center py-3">
                                        <div class="spinner-border spinner-border-sm text-success"></div>
                                        <small class="text-muted ms-2">Querying cluster status...</small>
                                    </div>
                                }
                                else if (mongoClusterDetail is not null)
                                {
                                    @* ── Cluster Overview ── *@
                                    <div class="row g-2 mb-3">
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">State</div>
                                                <div class="fw-semibold">
                                                    @if (mongoClusterDetail.Phase.Contains("ready", StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        <span class="text-success"><i class="bi bi-check-circle me-1"></i>@mongoClusterDetail.Phase</span>
                                                    }
                                                    else if (mongoClusterDetail.Phase.Contains("initializing", StringComparison.OrdinalIgnoreCase))
                                                    {
                                                        <span class="text-warning"><i class="bi bi-hourglass me-1"></i>@mongoClusterDetail.Phase</span>
                                                    }
                                                    else
                                                    {
                                                        <span>@mongoClusterDetail.Phase</span>
                                                    }
                                                </div>
                                            </div>
                                        </div>
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">Ready</div>
                                                <div class="fw-semibold">@mongoClusterDetail.ReadyMembers / @mc.Members</div>
                                            </div>
                                        </div>
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">Endpoint</div>
                                                <div class="fw-semibold text-truncate font-monospace small">@(mongoClusterDetail.Endpoint ?? "—")</div>
                                            </div>
                                        </div>
                                        <div class="col-md-3">
                                            <div class="border rounded p-2 text-center small">
                                                <div class="text-muted">Info</div>
                                                <div class="fw-semibold">
                                                    <span class="me-2"><i class="bi bi-server me-1"></i>@mc.KubernetesCluster.Name</span>
                                                    <span><i class="bi bi-box me-1"></i>@mc.Namespace</span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                    @if (!string.IsNullOrEmpty(mongoClusterDetail.Message))
                                    {
                                        <div class="alert alert-warning py-1 px-2 small mb-3">
                                            <i class="bi bi-info-circle me-1"></i>@mongoClusterDetail.Message
                                        </div>
                                    }

                                    @* ── Pod Table ── *@
                                    <h6 class="small text-muted mb-2"><i class="bi bi-hdd-stack me-1"></i>Pods</h6>
                                    @if (mongoClusterDetail.Pods.Count > 0)
                                    {
                                        <div class="table-responsive mb-3">
                                            <table class="table table-sm table-hover small mb-0">
                                                <thead class="table-light">
                                                    <tr>
                                                        <th>Pod</th>
                                                        <th>Status</th>
                                                        <th>Ready</th>
                                                        <th>Node</th>
                                                        <th>Age</th>
                                                        <th>Restarts</th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    @foreach (MongoPodInfo pod in mongoClusterDetail.Pods)
                                                    {
                                                        <tr>
                                                            <td class="font-monospace">@pod.Name</td>
                                                            <td>
                                                                @if (pod.Status == "Running")
                                                                {
                                                                    <span class="text-success"><i class="bi bi-circle-fill me-1" style="font-size:0.5rem;"></i>Running</span>
                                                                }
                                                                else if (pod.Status == "Pending")
                                                                {
                                                                    <span class="text-warning"><i class="bi bi-circle-fill me-1" style="font-size:0.5rem;"></i>Pending</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="text-danger"><i class="bi bi-circle-fill me-1" style="font-size:0.5rem;"></i>@pod.Status</span>
                                                                }
                                                            </td>
                                                            <td>
                                                                @if (pod.Ready)
                                                                {
                                                                    <i class="bi bi-check-circle text-success"></i>
                                                                }
                                                                else
                                                                {
                                                                    <i class="bi bi-x-circle text-danger"></i>
                                                                }
                                                            </td>
                                                            <td class="text-truncate" style="max-width: 150px;">@(pod.Node ?? "—")</td>
                                                            <td>@FormatAge(pod.StartTime)</td>
                                                            <td>
                                                                @if (pod.Restarts > 0)
                                                                {
                                                                    <span class="text-warning">@pod.Restarts</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="text-muted">0</span>
                                                                }
                                                            </td>
                                                        </tr>
                                                    }
                                                </tbody>
                                            </table>
                                        </div>
                                    }
                                    else
                                    {
                                        <div class="alert alert-warning small py-2 mb-3">
                                            <i class="bi bi-exclamation-triangle me-1"></i>No pods found. Cluster may still be initializing.
                                        </div>
                                    }

                                    @* ── Databases ── *@
                                    <h6 class="small text-muted mb-2 d-flex align-items-center">
                                        <i class="bi bi-table me-1"></i>Databases
                                        <span class="badge bg-success rounded-pill ms-2">@mc.Databases.Count</span>
                                    </h6>
                                    @if (mc.Databases.Count > 0)
                                    {
                                        <div class="table-responsive mb-3">
                                            <table class="table table-sm small mb-0">
                                                <thead class="table-light">
                                                    <tr>
                                                        <th>Database</th>
                                                        <th>Status</th>
                                                        <th>Created</th>
                                                        <th></th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    @foreach (MongoDatabase mdb in mc.Databases)
                                                    {
                                                        <tr>
                                                            <td class="font-monospace">@mdb.Name</td>
                                                            <td>
                                                                @if (mdb.Status == MongoDatabaseStatus.Ready)
                                                                {
                                                                    <span class="badge bg-success-subtle text-success">Ready</span>
                                                                }
                                                                else if (mdb.Status == MongoDatabaseStatus.Creating)
                                                                {
                                                                    <span class="badge bg-warning-subtle text-warning">Creating</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="badge bg-danger-subtle text-danger">@mdb.Status</span>
                                                                }
                                                            </td>
                                                            <td class="text-muted">@mdb.CreatedAt.ToString("yyyy-MM-dd HH:mm")</td>
                                                            <td>
                                                                <button class="btn btn-link btn-sm text-danger p-0" title="Drop database"
                                                                        @onclick="() => DeleteMongoDatabase(mc.Id, mdb.Id)">
                                                                    <i class="bi bi-trash" style="font-size:0.8rem;"></i>
                                                                </button>
                                                            </td>
                                                        </tr>
                                                    }
                                                </tbody>
                                            </table>
                                        </div>
                                    }
                                    else
                                    {
                                        <p class="small text-muted mb-3">No databases created yet. Use the <i class="bi bi-plus-circle"></i> button to add one.</p>
                                    }

                                    @* ── Backups ── *@
                                    <h6 class="small text-muted mb-2 d-flex align-items-center">
                                        <i class="bi bi-cloud-arrow-up me-1"></i>Backups
                                        <span class="badge bg-info rounded-pill ms-2">@mongoClusterDetail.Backups.Count</span>
                                    </h6>
                                    @if (mongoClusterDetail.Backups.Count > 0)
                                    {
                                        <div class="table-responsive">
                                            <table class="table table-sm small mb-0">
                                                <thead class="table-light">
                                                    <tr>
                                                        <th>Name</th>
                                                        <th>Type</th>
                                                        <th>Status</th>
                                                        <th>Started</th>
                                                        <th>Completed</th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    @foreach (MongoBackup bk in mongoClusterDetail.Backups)
                                                    {
                                                        <tr class="@(selectedMongoBackup?.Name == bk.Name && selectedMongoBackupCluster?.Id == mc.Id ? "table-warning" : "")"
                                                            style="cursor:pointer" title="Click to restore from this backup"
                                                            @onclick="() => SelectMongoBackup(mc, bk)">
                                                            <td class="font-monospace text-truncate" style="max-width: 200px;">@bk.Name</td>
                                                            <td>
                                                                @if (bk.Type == MongoBackupType.Scheduled)
                                                                {
                                                                    <span class="badge bg-light text-dark border"><i class="bi bi-clock me-1"></i>Scheduled</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="badge bg-light text-dark border"><i class="bi bi-hand-index me-1"></i>On-Demand</span>
                                                                }
                                                            </td>
                                                            <td>
                                                                @if (bk.Status == MongoBackupStatus.Completed)
                                                                {
                                                                    <span class="badge bg-success-subtle text-success"><i class="bi bi-check-circle me-1"></i>Completed</span>
                                                                }
                                                                else if (bk.Status == MongoBackupStatus.Running)
                                                                {
                                                                    <span class="badge bg-warning-subtle text-warning"><i class="bi bi-hourglass-split me-1"></i>Running</span>
                                                                }
                                                                else
                                                                {
                                                                    <span class="badge bg-danger-subtle text-danger"><i class="bi bi-x-circle me-1"></i>Failed</span>
                                                                }
                                                            </td>
                                                            <td class="text-muted">@bk.StartedAt.ToString("yyyy-MM-dd HH:mm")</td>
                                                            <td class="text-muted">@(bk.CompletedAt?.ToString("HH:mm") ?? "—")</td>
                                                        </tr>
                                                    }
                                                </tbody>
                                            </table>
                                        </div>
                                    }
                                    else if (mc.StorageLinkId.HasValue)
                                    {
                                        <p class="small text-muted">No backups yet. Click <i class="bi bi-cloud-arrow-up"></i> to create one.</p>
                                    }
                                    else
                                    {
                                        <p class="small text-muted">Backups are not configured. Assign an S3 bucket to enable backups.</p>
                                    }

                                    @* ── Backup Restore Panel (MongoDB) ── *@
                                    @if (selectedMongoBackup != null && selectedMongoBackupCluster?.Id == mc.Id)
                                    {
                                        <div class="card border-warning mt-2">
                                            <div class="card-header bg-warning bg-opacity-10 d-flex align-items-center justify-content-between py-2">
                                                <h6 class="mb-0 small">
                                                    <i class="bi bi-clock-history me-2"></i>Restore from <strong>@selectedMongoBackup.Name</strong>
                                                    <span class="text-muted ms-2">(@(selectedMongoBackup.CompletedAt?.ToString("yyyy-MM-dd HH:mm") ?? selectedMongoBackup.StartedAt.ToString("yyyy-MM-dd HH:mm")))</span>
                                                </h6>
                                                <button class="btn btn-sm btn-outline-secondary border-0"
                                                        @onclick="() => { selectedMongoBackup = null; selectedMongoBackupCluster = null; backupRestoreError = null; }">
                                                    <i class="bi bi-x-lg"></i>
                                                </button>
                                            </div>
                                            <div class="card-body py-2">
                                                <div class="d-flex gap-4 mb-3">
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="radio" name="mongo-restore-target-@mc.Id"
                                                               id="mongo-rt-current-@mc.Id" checked="@(backupRestoreTarget == "current")"
                                                               @onchange="@(_ => backupRestoreTarget = "current")" />
                                                        <label class="form-check-label small" for="mongo-rt-current-@mc.Id">
                                                            <i class="bi bi-arrow-counterclockwise me-1"></i>Current cluster
                                                        </label>
                                                    </div>
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="radio" name="mongo-restore-target-@mc.Id"
                                                               id="mongo-rt-new-@mc.Id" checked="@(backupRestoreTarget == "new")"
                                                               @onchange="@(_ => backupRestoreTarget = "new")" />
                                                        <label class="form-check-label small" for="mongo-rt-new-@mc.Id">
                                                            <i class="bi bi-plus-circle me-1"></i>New cluster
                                                        </label>
                                                    </div>
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="radio" name="mongo-restore-target-@mc.Id"
                                                               id="mongo-rt-external-@mc.Id" checked="@(backupRestoreTarget == "external")"
                                                               @onchange="@(_ => backupRestoreTarget = "external")" />
                                                        <label class="form-check-label small" for="mongo-rt-external-@mc.Id">
                                                            <i class="bi bi-cloud me-1"></i>External connection
                                                        </label>
                                                    </div>
                                                </div>

                                                @if (backupRestoreTarget == "current")
                                                {
                                                    <div class="alert alert-warning small py-2 mb-2">
                                                        <i class="bi bi-exclamation-triangle me-1"></i>
                                                        <strong>Destructive:</strong> Runs mongorestore --drop against the running cluster. All collections are replaced with backup data.
                                                    </div>
                                                }
                                                else if (backupRestoreTarget == "new")
                                                {
                                                    <div class="row g-2 mb-2">
                                                        <div class="col-md-6">
                                                            <label class="form-label small">New Cluster Name</label>
                                                            <input class="form-control form-control-sm" @bind="backupRestoreNewName" placeholder="@(mc.Name + "-restored")" />
                                                        </div>
                                                    </div>
                                                }
                                                else if (backupRestoreTarget == "external")
                                                {
                                                    <div class="row g-2 mb-2">
                                                        <div class="col-12">
                                                            <label class="form-label small">MongoDB Connection URI</label>
                                                            <input class="form-control form-control-sm font-monospace" @bind="backupRestoreExternalUri"
                                                                   placeholder="mongodb://user:pass@host:27017/admin?authSource=admin" />
                                                            <div class="form-text small text-muted">The backup will be restored (mongorestore --drop) to this external MongoDB instance.</div>
                                                        </div>
                                                    </div>
                                                }

                                                <div class="d-flex gap-2">
                                                    <button class="btn btn-sm btn-warning" @onclick="ExecuteBackupRestore" disabled="@backupRestoring">
                                                        @if (backupRestoring) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                                        Restore
                                                    </button>
                                                    <button class="btn btn-sm btn-outline-secondary"
                                                            @onclick="() => { selectedMongoBackup = null; selectedMongoBackupCluster = null; backupRestoreError = null; }">
                                                        Cancel
                                                    </button>
                                                </div>

                                                @if (!string.IsNullOrEmpty(backupRestoreError))
                                                {
                                                    <div class="alert alert-danger small py-1 mt-2 mb-0">@backupRestoreError</div>
                                                }
                                            </div>
                                        </div>
                                    }
                                }

                                @if (!string.IsNullOrEmpty(mc.LastError))
                                {
                                    <div class="alert alert-danger small py-1 mt-2 mb-0">
                                        <i class="bi bi-exclamation-triangle me-1"></i>@mc.LastError
                                    </div>
                                }
                            </div>
                        }
                        else
                        {
                            @* ── Collapsed Summary Row ── *@
                            <div class="card-body py-2">
                                <div class="row small text-muted">
                                    <div class="col-auto">
                                        <i class="bi bi-server me-1"></i>@mc.KubernetesCluster.Name
                                    </div>
                                    <div class="col-auto">
                                        <i class="bi bi-box me-1"></i>@mc.Namespace
                                    </div>
                                    <div class="col-auto">
                                        <i class="bi bi-hdd-stack me-1"></i>@mc.Members member(s)
                                    </div>
                                    <div class="col-auto">
                                        <i class="bi bi-device-hdd me-1"></i>@mc.StorageSize
                                    </div>
                                    @if (mc.StorageLink is not null)
                                    {
                                        <div class="col-auto">
                                            <i class="bi bi-cloud me-1"></i>@mc.StorageLink.BucketName
                                        </div>
                                    }
                                    @if (mc.Databases.Count > 0)
                                    {
                                        <div class="col-auto">
                                            <i class="bi bi-table me-1"></i>@string.Join(", ", mc.Databases.Select(d => d.Name))
                                        </div>
                                    }
                                </div>
                            </div>
                        }
                    </div>
                }
            }

            @* ── Add MongoDB Database Form ── *@
            @if (mongoAddDbCluster is not null)
            {
                <div class="card shadow-sm mb-3 border-success">
                    <div class="card-header bg-success bg-opacity-10">
                        <h6 class="mb-0"><i class="bi bi-plus-circle me-2"></i>Add Database to <strong>@mongoAddDbCluster.Name</strong></h6>
                    </div>
                    <div class="card-body">
                        <div class="row g-3 align-items-end">
                            <div class="col-md-6">
                                <label class="form-label small">Database Name</label>
                                <input class="form-control form-control-sm" @bind="mongoNewDbName" placeholder="myapp" />
                            </div>
                            <div class="col-md-6 d-flex gap-2">
                                <button class="btn btn-sm btn-success" @onclick="AddMongoDatabase" disabled="@mongoAddingDb">
                                    @if (mongoAddingDb) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                    Create
                                </button>
                                <button class="btn btn-sm btn-outline-secondary" @onclick="() => mongoAddDbCluster = null">Cancel</button>
                            </div>
                        </div>
                        @if (!string.IsNullOrEmpty(mongoDbError))
                        {
                            <div class="alert alert-danger small py-1 mt-2 mb-0">@mongoDbError</div>
                        }
                    </div>
                </div>
            }

            @* ── MongoDB Restore Form ── *@
            @if (mongoRestoreSource is not null)
            {
                <div class="card shadow-sm mb-3 border-warning">
                    <div class="card-header bg-warning bg-opacity-10">
                        <h6 class="mb-0"><i class="bi bi-clock-history me-2"></i>Restore from <strong>@mongoRestoreSource.Name</strong></h6>
                    </div>
                    <div class="card-body">
                        <div class="row g-3 align-items-end">
                            <div class="col-md-5">
                                <label class="form-label small">Source Backup</label>
                                @{
                                    var completedBackups = mongoRestoreSource.Backups
                                        .Where(b => b.Status == MongoBackupStatus.Completed)
                                        .OrderByDescending(b => b.StartedAt)
                                        .ToList();
                                }
                                <select class="form-select form-select-sm" @bind="mongoRestoreBackupId">
                                    <option value="">— select backup —</option>
                                    @foreach (var b in completedBackups)
                                    {
                                        <option value="@b.Id">@b.Name (@b.StartedAt.ToString("yyyy-MM-dd HH:mm") UTC)</option>
                                    }
                                </select>
                                @if (!completedBackups.Any())
                                {
                                    <div class="form-text text-warning">No completed backups available.</div>
                                }
                            </div>
                            <div class="col-md-4 d-flex gap-2 align-items-end">
                                <button class="btn btn-sm btn-warning" @onclick="ExecuteMongoRestore" disabled="@(mongoRestoring || mongoRestoreBackupId == Guid.Empty)">
                                    @if (mongoRestoring) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                    Restore
                                </button>
                                <button class="btn btn-sm btn-outline-secondary" @onclick="() => mongoRestoreSource = null">Cancel</button>
                            </div>
                        </div>
                        @if (!string.IsNullOrEmpty(mongoRestoreError))
                        {
                            <div class="alert alert-danger small py-1 mt-2 mb-0">@mongoRestoreError</div>
                        }
                    </div>
                </div>
            }

            @* ── MongoDB Upgrade Form ── *@
            @if (mongoUpgradeCluster is not null)
            {
                <div class="card shadow-sm mb-3 border-secondary">
                    <div class="card-header bg-secondary bg-opacity-10">
                        <h6 class="mb-0"><i class="bi bi-arrow-up-circle me-2"></i>Upgrade <strong>@mongoUpgradeCluster.Name</strong> (currently @mongoUpgradeCluster.MongoVersion)</h6>
                    </div>
                    <div class="card-body">
                        <div class="row g-3 align-items-end">
                            <div class="col-md-4">
                                <label class="form-label small">Target Version</label>
                                <select class="form-select form-select-sm" @bind="mongoUpgradeVersion">
                                    <option value="8.0">MongoDB 8.0</option>
                                    <option value="7.0">MongoDB 7.0</option>
                                    <option value="6.0">MongoDB 6.0</option>
                                </select>
                            </div>
                            <div class="col-md-4 d-flex gap-2">
                                <button class="btn btn-sm btn-secondary" @onclick="ExecuteMongoUpgrade" disabled="@mongoUpgrading">
                                    @if (mongoUpgrading) { <span class="spinner-border spinner-border-sm me-1"></span> }
                                    Upgrade
                                </button>
                                <button class="btn btn-sm btn-outline-secondary" @onclick="() => mongoUpgradeCluster = null">Cancel</button>
                            </div>
                        </div>
                        @if (!string.IsNullOrEmpty(mongoUpgradeError))
                        {
                            <div class="alert alert-danger small py-1 mt-2 mb-0">@mongoUpgradeError</div>
                        }
                    </div>
                </div>
            }
        </div>
    }

    @* ── Refresh button ── *@
    <div class="mt-3">
        <button class="btn btn-sm btn-outline-secondary" @onclick="RefreshAll" disabled="@refreshing">
            @if (refreshing)
            {
                <span class="spinner-border spinner-border-sm me-1" role="status"></span>
            }
            else
            {
                <i class="bi bi-arrow-clockwise me-1"></i>
            }
            Refresh
        </button>
    </div>
}

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

    private bool loading = true;
    private bool refreshing;
    private DatabaseOperatorStatus? operatorStatus;
    private List<DatabaseClusterInfo>? cnpgClusters;
    private List<DatabaseClusterInfo>? mongoClusters;

    // Environment tab filter (null = All)
    private string? selectedEnvironment;

    private IReadOnlyList<string> AllEnvironments
    {
        get
        {
            var names = new HashSet<string>(StringComparer.Ordinal);
            if (cnpgClusters is not null)
                foreach (var c in cnpgClusters) names.Add(c.EnvironmentName);
            if (mongoClusters is not null)
                foreach (var c in mongoClusters) names.Add(c.EnvironmentName);
            if (managedClusters is not null)
                foreach (var c in managedClusters) names.Add(c.KubernetesCluster.Environment.Name);
            if (managedMongoClusters is not null)
                foreach (var c in managedMongoClusters) names.Add(c.KubernetesCluster.Environment.Name);
            return names.OrderBy(n => n).ToList();
        }
    }

    private List<DatabaseClusterInfo>? FilteredCnpgClusters =>
        cnpgClusters?.Where(c => selectedEnvironment is null || c.EnvironmentName == selectedEnvironment).ToList();

    private List<CnpgCluster>? FilteredManagedClusters =>
        managedClusters?.Where(c => selectedEnvironment is null || c.KubernetesCluster.Environment.Name == selectedEnvironment).ToList();

    private List<DatabaseClusterInfo>? FilteredMongoClusters =>
        mongoClusters?.Where(c => selectedEnvironment is null || c.EnvironmentName == selectedEnvironment).ToList();

    private List<MongoCluster>? FilteredManagedMongoClusters =>
        managedMongoClusters?.Where(c => selectedEnvironment is null || c.KubernetesCluster.Environment.Name == selectedEnvironment).ToList();

    // Managed CNPG cluster state
    private List<CnpgCluster>? managedClusters;
    private List<KubernetesCluster>? availableClusters;
    private List<StorageLink>? storageLinks;

    // Managed MongoDB cluster state
    private List<MongoCluster>? managedMongoClusters;
    private List<KubernetesCluster>? mongoAvailableClusters;

    // Create cluster form
    private bool showCreate;
    private bool creating;
    private string? createError;
    private string createName = "";
    private string createNamespace = "databases";
    private Guid createClusterId;
    private int createInstances = 3;
    private string createStorageSize = "10Gi";
    private Guid createStorageLinkId;
    private string createSchedule = "";
    private int createRetentionDays = 30;

    // Cluster detail panel
    private Guid? expandedClusterId;
    private CnpgClusterDetail? clusterDetail;
    private bool loadingDetail;

    // Delete cluster
    private Guid? deletingId;

    // Backup
    private Guid? backingUpId;
    private Guid? applyingScheduledBackupId;
    private Guid? configuringScheduleId;
    private string scheduleInput = "";

    // Restore form
    private CnpgCluster? restoreSource;
    private string restoreName = "";
    private DateTime restoreTargetTime = DateTime.UtcNow.AddHours(-1);
    private bool restoring;
    private string? restoreError;

    // Upgrade form
    private CnpgCluster? upgradeCluster;
    private string upgradeVersion = "18";
    private bool upgrading;
    private string? upgradeError;

    // Add database form
    private CnpgCluster? addDbCluster;
    private string newDbName = "";
    private bool addingDb;
    private string? dbError;

    // Database credentials
    private Guid? credentialsDatabaseId;
    private Dictionary<string, string>? databaseCredentials;
    private Guid? rotatingDatabaseId;

    // ── MongoDB State ──
    // Create MongoDB cluster form
    private bool showMongoCreate;
    private bool mongoCreating;
    private string? mongoCreateError;
    private string mongoCreateName = "";
    private string mongoCreateNamespace = "databases";
    private Guid mongoCreateClusterId;
    private int mongoCreateMembers = 3;
    private string mongoCreateStorageSize = "10Gi";
    private Guid mongoCreateStorageLinkId;
    private string mongoCreateSchedule = "";
    private int mongoCreateRetentionDays = 30;

    // Mongo cluster detail panel
    private Guid? expandedMongoClusterId;
    private MongoClusterDetail? mongoClusterDetail;
    private bool mongoLoadingDetail;

    // Mongo delete
    private Guid? mongoDeletingId;

    // Mongo backup
    private Guid? mongoBackingUpId;

    // Mongo restore form
    private MongoCluster? mongoRestoreSource;
    private Guid mongoRestoreBackupId;
    private bool mongoRestoring;
    private string? mongoRestoreError;

    // Mongo upgrade form
    private MongoCluster? mongoUpgradeCluster;
    private string mongoUpgradeVersion = "8.0";
    private bool mongoUpgrading;
    private string? mongoUpgradeError;

    // Mongo add database form
    private MongoCluster? mongoAddDbCluster;
    private string mongoNewDbName = "";
    private bool mongoAddingDb;
    private string? mongoDbError;

    // Backup-driven restore (CNPG and MongoDB)
    private CnpgBackup? selectedCnpgBackup;
    private CnpgCluster? selectedCnpgBackupCluster;
    private MongoBackup? selectedMongoBackup;
    private MongoCluster? selectedMongoBackupCluster;
    private string backupRestoreTarget = "new";
    private string backupRestoreNewName = "";
    private string backupRestoreExternalUri = "";
    private bool backupRestoring;
    private string? backupRestoreError;

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

    private async Task LoadData()
    {
        loading = true;
        StateHasChanged();

        operatorStatus = await DatabaseService.GetOperatorStatusAsync(TenantId);

        if (operatorStatus.CnpgAvailable || operatorStatus.MongoDbAvailable)
        {
            // Load discovery and managed clusters in parallel.

            Task<List<DatabaseClusterInfo>> cnpgTask = operatorStatus.CnpgAvailable
                ? DatabaseService.GetCnpgClustersAsync(TenantId)
                : Task.FromResult(new List<DatabaseClusterInfo>());

            Task<List<DatabaseClusterInfo>> mongoTask = operatorStatus.MongoDbAvailable
                ? DatabaseService.GetMongoDbClustersAsync(TenantId)
                : Task.FromResult(new List<DatabaseClusterInfo>());

            Task<List<CnpgCluster>> managedTask = operatorStatus.CnpgAvailable
                ? CnpgService.GetClustersAsync(TenantId)
                : Task.FromResult(new List<CnpgCluster>());

            Task<List<MongoCluster>> managedMongoTask = operatorStatus.MongoDbAvailable
                ? MongoService.GetClustersAsync(TenantId)
                : Task.FromResult(new List<MongoCluster>());

            await Task.WhenAll(cnpgTask, mongoTask, managedTask, managedMongoTask);
            cnpgClusters = cnpgTask.Result;
            mongoClusters = mongoTask.Result;
            managedClusters = managedTask.Result;
            managedMongoClusters = managedMongoTask.Result;
        }

        loading = false;
    }

    private async Task RefreshAll()
    {
        refreshing = true;
        StateHasChanged();

        try
        {
            await LoadData();
            await RefreshOpenDetailPanels();
        }
        finally
        {
            refreshing = false;
        }
    }

    private async Task RefreshOpenDetailPanels()
    {
        if (expandedClusterId.HasValue)
        {
            try
            {
                clusterDetail = await CnpgService.GetClusterDetailAsync(TenantId, expandedClusterId.Value);
            }
            catch { }
        }

        if (expandedMongoClusterId.HasValue)
        {
            try
            {
                mongoClusterDetail = await MongoService.GetClusterDetailAsync(TenantId, expandedMongoClusterId.Value);
            }
            catch { }
        }
    }

    // ──────── Cluster Detail Panel ────────

    private async Task ToggleClusterDetail(CnpgCluster cluster)
    {
        // If already expanded, collapse it.

        if (expandedClusterId == cluster.Id)
        {
            expandedClusterId = null;
            clusterDetail = null;
            return;
        }

        // Expand and fetch live pod/status info from K8s.

        expandedClusterId = cluster.Id;
        clusterDetail = null;
        loadingDetail = true;
        StateHasChanged();

        try
        {
            clusterDetail = await CnpgService.GetClusterDetailAsync(TenantId, cluster.Id);
        }
        catch (Exception)
        {
            clusterDetail = new CnpgClusterDetail
            {
                Cluster = cluster,
                Phase = "Error fetching status"
            };
        }
        finally
        {
            loadingDetail = false;
        }
    }

    private static string FormatAge(DateTime? startTime)
    {
        if (startTime is null)
        {
            return "—";
        }

        TimeSpan age = DateTime.UtcNow - startTime.Value.ToUniversalTime();

        if (age.TotalDays >= 1)
        {
            return $"{(int)age.TotalDays}d {age.Hours}h";
        }

        if (age.TotalHours >= 1)
        {
            return $"{(int)age.TotalHours}h {age.Minutes}m";
        }

        return $"{(int)age.TotalMinutes}m";
    }

    private static string FormatBytes(long bytes)
    {
        if (bytes >= 1_073_741_824)
        {
            return $"{bytes / 1_073_741_824.0:F1} GB";
        }

        if (bytes >= 1_048_576)
        {
            return $"{bytes / 1_048_576.0:F1} MB";
        }

        if (bytes >= 1024)
        {
            return $"{bytes / 1024.0:F0} KB";
        }

        return $"{bytes} B";
    }

    // ──────── Create Cluster ────────

    private async Task ShowCreateForm()
    {
        showCreate = true;
        createError = null;

        // Load available K8s clusters (those with CNPG installed) and S3 storage links.

        availableClusters = await DatabaseService.GetCnpgEnabledClustersAsync(TenantId);
        storageLinks = await StorageService.GetStorageLinksAsync(TenantId);
    }

    private void CancelCreate()
    {
        showCreate = false;
        createError = null;
        createName = "";
        createNamespace = "databases";
        createClusterId = Guid.Empty;
        createInstances = 3;
        createStorageSize = "10Gi";
        createStorageLinkId = Guid.Empty;
        createSchedule = "";
        createRetentionDays = 30;
    }

    private async Task CreateCluster()
    {
        if (string.IsNullOrWhiteSpace(createName) || createClusterId == Guid.Empty)
        {
            createError = "Name and target cluster are required.";
            return;
        }

        creating = true;
        createError = null;
        StateHasChanged();

        try
        {
            Guid? storageLinkId = createStorageLinkId != Guid.Empty ? createStorageLinkId : null;
            string? schedule = !string.IsNullOrWhiteSpace(createSchedule) ? createSchedule : null;

            await CnpgService.CreateClusterAsync(
                TenantId, createClusterId, createName.Trim(), createNamespace.Trim(),
                createInstances, createStorageSize.Trim(), storageLinkId, schedule,
                createRetentionDays);

            CancelCreate();
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            createError = ex.Message;
        }
        finally
        {
            creating = false;
        }
    }

    // ──────── Delete Cluster ────────

    private async Task DeleteCluster(Guid cnpgClusterId)
    {
        deletingId = cnpgClusterId;
        StateHasChanged();

        try
        {
            await CnpgService.DeleteClusterAsync(TenantId, cnpgClusterId);
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            createError = $"Delete failed: {ex.Message}";
        }
        finally
        {
            deletingId = null;
        }
    }

    // ──────── Backup ────────

    private async Task TriggerBackup(Guid cnpgClusterId)
    {
        backingUpId = cnpgClusterId;
        StateHasChanged();

        try
        {
            await CnpgService.BackupAsync(TenantId, cnpgClusterId);
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            createError = $"Backup failed: {ex.Message}";
        }
        finally
        {
            backingUpId = null;
        }
    }

    private void ToggleScheduleForm(CnpgCluster cluster)
    {
        if (!string.IsNullOrWhiteSpace(cluster.BackupSchedule))
        {
            // Schedule already set — apply directly without showing the form.
            _ = ApplyScheduledBackup(cluster.Id, null);
            return;
        }

        // No schedule yet — expand the card and show the input form.
        expandedClusterId = cluster.Id;
        configuringScheduleId = cluster.Id;
        scheduleInput = "";
    }

    private void CancelScheduleForm()
    {
        configuringScheduleId = null;
        scheduleInput = "";
    }

    private async Task ApplyScheduledBackup(Guid cnpgClusterId, string? schedule)
    {
        applyingScheduledBackupId = cnpgClusterId;
        configuringScheduleId = null;
        StateHasChanged();

        try
        {
            await CnpgService.ApplyScheduledBackupAsync(TenantId, cnpgClusterId, schedule);
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            createError = $"Apply scheduled backup failed: {ex.Message}";
        }
        finally
        {
            applyingScheduledBackupId = null;
        }
    }

    // ──────── Restore ────────

    private void ShowRestore(CnpgCluster source)
    {
        restoreSource = source;
        restoreName = $"{source.Name}-restored";
        restoreTargetTime = DateTime.UtcNow.AddHours(-1);
        restoreError = null;
    }

    private async Task ExecuteRestore()
    {
        if (string.IsNullOrWhiteSpace(restoreName))
        {
            restoreError = "New cluster name is required.";
            return;
        }

        restoring = true;
        restoreError = null;
        StateHasChanged();

        try
        {
            await CnpgService.RestoreAsync(
                TenantId, restoreSource!.Id, restoreName.Trim(), restoreTargetTime);

            restoreSource = null;
        }
        catch (Exception ex)
        {
            restoreError = ex.Message;
        }
        finally
        {
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
            restoring = false;
        }
    }

    // ──────── Upgrade ────────

    private void ShowUpgrade(CnpgCluster cluster)
    {
        upgradeCluster = cluster;
        upgradeVersion = "18";
        upgradeError = null;
    }

    private async Task ExecuteUpgrade()
    {
        upgrading = true;
        upgradeError = null;
        StateHasChanged();

        try
        {
            // Determine whether this is a minor (rolling) or major (restore-based) upgrade.
            // Minor: same major version, zero-downtime rolling update.
            // Major: restore to new cluster, swap name, remove old (~10-30s downtime).

            int currentMajor = int.Parse(upgradeCluster!.PostgresVersion.Split('.')[0].Split('-')[0]);
            int targetMajor = int.Parse(upgradeVersion.Split('.')[0].Split('-')[0]);

            if (targetMajor != currentMajor)
            {
                await CnpgService.MajorUpgradeAsync(TenantId, upgradeCluster.Id, upgradeVersion);
            }
            else
            {
                await CnpgService.UpgradeClusterAsync(TenantId, upgradeCluster.Id, upgradeVersion);
            }

            upgradeCluster = null;
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            upgradeError = ex.Message;
        }
        finally
        {
            upgrading = false;
        }
    }

    // ──────── Database Management ────────

    private void ShowAddDatabase(CnpgCluster cluster)
    {
        addDbCluster = cluster;
        newDbName = "";
        dbError = null;
    }

    private async Task AddDatabase()
    {
        if (string.IsNullOrWhiteSpace(newDbName))
        {
            dbError = "Database name is required.";
            return;
        }

        addingDb = true;
        dbError = null;
        StateHasChanged();

        try
        {
            await CnpgService.CreateDatabaseAsync(TenantId, addDbCluster!.Id, newDbName.Trim());
            addDbCluster = null;
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            dbError = ex.Message;
        }
        finally
        {
            addingDb = false;
        }
    }

    private async Task DeleteDatabase(Guid cnpgClusterId, Guid databaseId)
    {
        try
        {
            await CnpgService.DeleteDatabaseAsync(TenantId, cnpgClusterId, databaseId);
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            dbError = $"Failed to delete database: {ex.Message}";
        }
    }

    private async Task ToggleDatabaseCredentials(Guid cnpgClusterId, Guid databaseId)
    {
        // Toggle off if already showing this database's credentials.

        if (credentialsDatabaseId == databaseId)
        {
            credentialsDatabaseId = null;
            databaseCredentials = null;
            return;
        }

        // Fetch credentials from the vault and display them.

        try
        {
            databaseCredentials = await CnpgService.GetDatabaseCredentialsAsync(TenantId, databaseId);
            credentialsDatabaseId = databaseId;
        }
        catch (Exception ex)
        {
            dbError = $"Failed to load credentials: {ex.Message}";
        }
    }

    private async Task SyncDatabaseCredentialsToK8s(Guid cnpgClusterId, Guid databaseId)
    {
        try
        {
            await CnpgService.SyncDatabaseCredentialsToK8sAsync(TenantId, cnpgClusterId, databaseId);
            dbError = null;
        }
        catch (Exception ex)
        {
            dbError = $"Failed to sync credentials to K8s: {ex.Message}";
        }
    }

    private async Task RotateDatabasePassword(Guid cnpgClusterId, Guid databaseId)
    {
        rotatingDatabaseId = databaseId;
        dbError = null;
        try
        {
            await CnpgService.RotateDatabasePasswordAsync(TenantId, cnpgClusterId, databaseId);
            // Refresh credentials panel if it was open for this database.
            if (credentialsDatabaseId == databaseId)
            {
                databaseCredentials = await CnpgService.GetDatabaseCredentialsAsync(TenantId, databaseId);
            }
        }
        catch (Exception ex)
        {
            dbError = $"Failed to rotate password: {ex.Message}";
        }
        finally
        {
            rotatingDatabaseId = null;
        }
    }

    // ──────── Status Helpers ────────

    // ──────── Managed MongoDB Methods ────────

    private async Task ShowMongoCreateForm()
    {
        showMongoCreate = true;
        mongoCreateError = null;
        mongoAvailableClusters = await DatabaseService.GetMongoEnabledClustersAsync(TenantId);
        storageLinks ??= await StorageService.GetStorageLinksAsync(TenantId);
    }

    private void CancelMongoCreate()
    {
        showMongoCreate = false;
        mongoCreateError = null;
        mongoCreateName = "";
        mongoCreateNamespace = "databases";
        mongoCreateClusterId = Guid.Empty;
        mongoCreateMembers = 3;
        mongoCreateStorageSize = "10Gi";
        mongoCreateStorageLinkId = Guid.Empty;
        mongoCreateSchedule = "";
        mongoCreateRetentionDays = 30;
    }

    private async Task CreateMongoCluster()
    {
        if (string.IsNullOrWhiteSpace(mongoCreateName) || mongoCreateClusterId == Guid.Empty)
        {
            mongoCreateError = "Name and target cluster are required.";
            return;
        }

        mongoCreating = true;
        mongoCreateError = null;
        StateHasChanged();

        try
        {
            Guid? storageLinkId = mongoCreateStorageLinkId != Guid.Empty ? mongoCreateStorageLinkId : null;
            string? schedule = !string.IsNullOrWhiteSpace(mongoCreateSchedule) ? mongoCreateSchedule : null;

            await MongoService.CreateClusterAsync(
                TenantId, mongoCreateClusterId, mongoCreateName.Trim(), mongoCreateNamespace.Trim(),
                mongoCreateMembers, mongoCreateStorageSize.Trim(), storageLinkId, schedule,
                mongoCreateRetentionDays);

            CancelMongoCreate();
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            mongoCreateError = ex.Message;
        }
        finally
        {
            mongoCreating = false;
        }
    }

    private async Task DeleteMongoCluster(Guid mongoClusterId)
    {
        mongoDeletingId = mongoClusterId;
        StateHasChanged();

        try
        {
            await MongoService.DeleteClusterAsync(TenantId, mongoClusterId);
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            mongoCreateError = $"Delete failed: {ex.Message}";
        }
        finally
        {
            mongoDeletingId = null;
        }
    }

    private async Task TriggerMongoBackup(Guid mongoClusterId)
    {
        mongoBackingUpId = mongoClusterId;
        StateHasChanged();

        try
        {
            await MongoService.BackupAsync(TenantId, mongoClusterId);
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
            await RefreshOpenDetailPanels();
        }
        catch (Exception ex)
        {
            mongoCreateError = $"Backup failed: {ex.Message}";
        }
        finally
        {
            mongoBackingUpId = null;
        }
    }

    private void ShowMongoRestore(MongoCluster source)
    {
        mongoRestoreSource = source;
        mongoRestoreBackupId = source.Backups
            .Where(b => b.Status == MongoBackupStatus.Completed)
            .OrderByDescending(b => b.StartedAt)
            .Select(b => b.Id)
            .FirstOrDefault();
        mongoRestoreError = null;
    }

    private async Task ExecuteMongoRestore()
    {
        if (mongoRestoreBackupId == Guid.Empty)
        {
            mongoRestoreError = "Select a backup to restore from.";
            return;
        }

        mongoRestoring = true;
        mongoRestoreError = null;
        StateHasChanged();

        try
        {
            await MongoService.RestoreAsync(
                TenantId, mongoRestoreSource!.Id, mongoRestoreBackupId);

            mongoRestoreSource = null;
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            mongoRestoreError = ex.Message;
        }
        finally
        {
            mongoRestoring = false;
        }
    }

    // ──────── Backup-Driven Restore ────────

    private void SelectCnpgBackup(CnpgCluster cluster, CnpgBackup backup)
    {
        if (selectedCnpgBackup?.Name == backup.Name && selectedCnpgBackupCluster?.Id == cluster.Id)
        {
            selectedCnpgBackup = null;
            selectedCnpgBackupCluster = null;
            backupRestoreError = null;
            return;
        }
        selectedCnpgBackup = backup;
        selectedCnpgBackupCluster = cluster;
        selectedMongoBackup = null;
        selectedMongoBackupCluster = null;
        backupRestoreTarget = "new";
        backupRestoreNewName = $"{cluster.Name}-restored";
        backupRestoreExternalUri = "";
        backupRestoreError = null;
    }

    private void SelectMongoBackup(MongoCluster cluster, MongoBackup backup)
    {
        if (selectedMongoBackup?.Name == backup.Name && selectedMongoBackupCluster?.Id == cluster.Id)
        {
            selectedMongoBackup = null;
            selectedMongoBackupCluster = null;
            backupRestoreError = null;
            return;
        }
        selectedMongoBackup = backup;
        selectedMongoBackupCluster = cluster;
        selectedCnpgBackup = null;
        selectedCnpgBackupCluster = null;
        backupRestoreTarget = "new";
        backupRestoreNewName = $"{cluster.Name}-restored";
        backupRestoreExternalUri = "";
        backupRestoreError = null;
    }

    private async Task ExecuteBackupRestore()
    {
        backupRestoring = true;
        backupRestoreError = null;
        StateHasChanged();

        try
        {
            if (selectedCnpgBackup != null)
            {
                switch (backupRestoreTarget)
                {
                    case "current":
                        await CnpgService.RestoreInPlaceAsync(
                            TenantId, selectedCnpgBackupCluster!.Id,
                            selectedCnpgBackup.CompletedAt ?? DateTime.UtcNow);
                        break;
                    case "new":
                        if (string.IsNullOrWhiteSpace(backupRestoreNewName))
                        {
                            backupRestoreError = "New cluster name is required.";
                            return;
                        }
                        await CnpgService.RestoreAsync(
                            TenantId, selectedCnpgBackupCluster!.Id,
                            backupRestoreNewName.Trim(),
                            barmanBackupId: selectedCnpgBackup.BarmanId);
                        break;
                    default:
                        return;
                }
            }
            else if (selectedMongoBackup != null)
            {
                switch (backupRestoreTarget)
                {
                    case "current":
                        await MongoService.RestoreAsync(
                            TenantId, selectedMongoBackupCluster!.Id, selectedMongoBackup.Id);
                        break;
                    case "new":
                        if (string.IsNullOrWhiteSpace(backupRestoreNewName))
                        {
                            backupRestoreError = "New cluster name is required.";
                            return;
                        }
                        await MongoService.RestoreToNewClusterAsync(
                            TenantId, selectedMongoBackupCluster!.Id, selectedMongoBackup.Id,
                            backupRestoreNewName.Trim());
                        break;
                    case "external":
                        if (string.IsNullOrWhiteSpace(backupRestoreExternalUri))
                        {
                            backupRestoreError = "External connection URI is required.";
                            return;
                        }
                        await MongoService.RestoreToExternalAsync(
                            TenantId, selectedMongoBackupCluster!.Id, selectedMongoBackup.Id,
                            backupRestoreExternalUri.Trim());
                        break;
                }
            }

            selectedCnpgBackup = null;
            selectedCnpgBackupCluster = null;
            selectedMongoBackup = null;
            selectedMongoBackupCluster = null;
        }
        catch (Exception ex)
        {
            backupRestoreError = ex.Message;
        }
        finally
        {
            managedClusters = await CnpgService.GetClustersAsync(TenantId);
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
            backupRestoring = false;
        }
    }

    private void ShowMongoUpgrade(MongoCluster cluster)
    {
        mongoUpgradeCluster = cluster;
        mongoUpgradeVersion = "8.0";
        mongoUpgradeError = null;
    }

    private async Task ExecuteMongoUpgrade()
    {
        mongoUpgrading = true;
        mongoUpgradeError = null;
        StateHasChanged();

        try
        {
            await MongoService.UpgradeClusterAsync(TenantId, mongoUpgradeCluster!.Id, mongoUpgradeVersion);
            mongoUpgradeCluster = null;
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            mongoUpgradeError = ex.Message;
        }
        finally
        {
            mongoUpgrading = false;
        }
    }

    private void ShowMongoAddDatabase(MongoCluster cluster)
    {
        mongoAddDbCluster = cluster;
        mongoNewDbName = "";
        mongoDbError = null;
    }

    private async Task AddMongoDatabase()
    {
        if (string.IsNullOrWhiteSpace(mongoNewDbName))
        {
            mongoDbError = "Database name is required.";
            return;
        }

        mongoAddingDb = true;
        mongoDbError = null;
        StateHasChanged();

        try
        {
            await MongoService.CreateDatabaseAsync(TenantId, mongoAddDbCluster!.Id, mongoNewDbName.Trim());
            mongoAddDbCluster = null;
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            mongoDbError = ex.Message;
        }
        finally
        {
            mongoAddingDb = false;
        }
    }

    private async Task DeleteMongoDatabase(Guid mongoClusterId, Guid databaseId)
    {
        try
        {
            await MongoService.DeleteDatabaseAsync(TenantId, mongoClusterId, databaseId);
            managedMongoClusters = await MongoService.GetClustersAsync(TenantId);
        }
        catch (Exception ex)
        {
            mongoDbError = $"Failed to delete database: {ex.Message}";
        }
    }

    private async Task ToggleMongoClusterDetail(MongoCluster cluster)
    {
        if (expandedMongoClusterId == cluster.Id)
        {
            expandedMongoClusterId = null;
            mongoClusterDetail = null;
            return;
        }

        expandedMongoClusterId = cluster.Id;
        mongoClusterDetail = null;
        mongoLoadingDetail = true;
        StateHasChanged();

        try
        {
            mongoClusterDetail = await MongoService.GetClusterDetailAsync(TenantId, cluster.Id);
        }
        catch (Exception)
        {
            mongoClusterDetail = new MongoClusterDetail
            {
                Cluster = cluster,
                Phase = "Error fetching status"
            };
        }
        finally
        {
            mongoLoadingDetail = false;
        }
    }

    private static RenderFragment GetMongoManagedStatusBadge(MongoClusterStatus status) => status switch
    {
        MongoClusterStatus.Running => __builder =>
        {
            <span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Running</span>
        },
        MongoClusterStatus.Creating => __builder =>
        {
            <span class="badge bg-warning text-dark"><i class="bi bi-hourglass me-1"></i>Creating</span>
        },
        MongoClusterStatus.Upgrading => __builder =>
        {
            <span class="badge bg-info"><i class="bi bi-arrow-up-circle me-1"></i>Upgrading</span>
        },
        MongoClusterStatus.Restoring => __builder =>
        {
            <span class="badge bg-info"><i class="bi bi-clock-history me-1"></i>Restoring</span>
        },
        MongoClusterStatus.Failed => __builder =>
        {
            <span class="badge bg-danger"><i class="bi bi-x-circle me-1"></i>Failed</span>
        },
        MongoClusterStatus.Deleting => __builder =>
        {
            <span class="badge bg-secondary"><i class="bi bi-trash me-1"></i>Deleting</span>
        },
        _ => __builder =>
        {
            <span class="badge bg-secondary">@status</span>
        }
    };

    // ──────── Status Helpers (CNPG) ────────

    private static RenderFragment GetStatusBadge(string status) => status.ToLowerInvariant() switch
    {
        "cluster in healthy state" or "healthy" or "running" => __builder =>
        {
            <span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Healthy</span>
        },
        "setting up primary" or "creating primary" or "pending" => __builder =>
        {
            <span class="badge bg-warning text-dark"><i class="bi bi-hourglass me-1"></i>Provisioning</span>
        },
        "failed" or "error" => __builder =>
        {
            <span class="badge bg-danger"><i class="bi bi-x-circle me-1"></i>Failed</span>
        },
        _ => __builder =>
        {
            <span class="badge bg-secondary">@status</span>
        }
    };

    private static RenderFragment GetManagedStatusBadge(CnpgClusterStatus status) => status switch
    {
        CnpgClusterStatus.Running => __builder =>
        {
            <span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Running</span>
        },
        CnpgClusterStatus.Creating => __builder =>
        {
            <span class="badge bg-warning text-dark"><i class="bi bi-hourglass me-1"></i>Creating</span>
        },
        CnpgClusterStatus.Upgrading => __builder =>
        {
            <span class="badge bg-info"><i class="bi bi-arrow-up-circle me-1"></i>Upgrading</span>
        },
        CnpgClusterStatus.Restoring => __builder =>
        {
            <span class="badge bg-info"><i class="bi bi-clock-history me-1"></i>Restoring</span>
        },
        CnpgClusterStatus.Failed => __builder =>
        {
            <span class="badge bg-danger"><i class="bi bi-x-circle me-1"></i>Failed</span>
        },
        CnpgClusterStatus.Deleting => __builder =>
        {
            <span class="badge bg-secondary"><i class="bi bi-trash me-1"></i>Deleting</span>
        },
        _ => __builder =>
        {
            <span class="badge bg-secondary">@status</span>
        }
    };
}
