@using EntKube.Web.Data
@using EntKube.Web.Services

@* ═══════════════════════════════════════════════════════════════════
   Deployment operations view — the heart of the customer portal.
   Shows deployment info, live pods, pod logs, and allows restart/
   delete/scale operations. Access is role-gated: Viewers can only
   browse and read logs; Operators can restart and delete pods;
   Admins have full control.
   ═══════════════════════════════════════════════════════════════════ *@

@* --- Deployment header --- *@
<div class="card shadow-sm mb-3">
    <div class="card-body">
        <div class="d-flex align-items-start justify-content-between">
            <div>
                <h5 class="mb-1">
                    <i class="bi bi-rocket-takeoff me-2 text-primary"></i>@Deployment.Name
                </h5>
                <div class="d-flex flex-wrap gap-2 text-muted small">
                    @TypeBadge(Deployment.Type)
                    <span><i class="bi bi-layers me-1"></i>@Deployment.Environment?.Name</span>
                    <span><i class="bi bi-hdd-network me-1"></i>@Deployment.Cluster?.Name</span>
                    <span><i class="bi bi-box me-1"></i>@Deployment.Namespace</span>
                </div>
            </div>
            <div class="d-flex gap-1">
                @SyncBadge(Deployment.SyncStatus)
                @HealthBadge(Deployment.HealthStatus)
            </div>
        </div>

        @if (Deployment.Type == DeploymentType.HelmChart)
        {
            <div class="mt-2 p-2 bg-light rounded small">
                <i class="bi bi-box-seam me-1"></i>
                @Deployment.HelmChartName <span class="text-muted">@Deployment.HelmChartVersion</span>
                <span class="text-muted ms-1">from @Deployment.HelmRepoUrl</span>
            </div>
        }

        @if (!string.IsNullOrEmpty(Deployment.StatusMessage))
        {
            <div class="mt-2 text-muted small">@Deployment.StatusMessage</div>
        }

        @if (Deployment.LastSyncedAt.HasValue)
        {
            <div class="mt-1 text-muted small">
                <i class="bi bi-clock me-1"></i>Last synced @Deployment.LastSyncedAt.Value.ToString("g")
            </div>
        }
    </div>
</div>

@* --- Tabs: Pods / Manifests / Resources --- *@
<ul class="nav nav-tabs mb-3">
    <li class="nav-item">
        <button class="nav-link @(activeTab == "pods" ? "active" : "")" @onclick="LoadPods">
            <i class="bi bi-cpu me-1"></i>Pods
            @if (pods is not null)
            {
                <span class="badge bg-primary ms-1">@pods.Count</span>
            }
        </button>
    </li>
    <li class="nav-item">
        <button class="nav-link @(activeTab == "manifests" ? "active" : "")" @onclick="LoadManifests">
            <i class="bi bi-file-earmark-code me-1"></i>Manifests
        </button>
    </li>
    <li class="nav-item">
        <button class="nav-link @(activeTab == "resources" ? "active" : "")" @onclick="LoadResources">
            <i class="bi bi-diagram-3 me-1"></i>Resources
        </button>
    </li>
</ul>

@* ══════════════════════════════════════════════════════════════
   Pods Tab — live pod list from the cluster
   ══════════════════════════════════════════════════════════════ *@
@if (activeTab == "pods")
{
    @if (!string.IsNullOrEmpty(operationMessage))
    {
        <div class="alert @(operationSuccess ? "alert-success" : "alert-danger") alert-dismissible py-2 small mb-3">
            @operationMessage
            <button type="button" class="btn-close btn-close-sm" @onclick="() => operationMessage = null"></button>
        </div>
    }

    @* --- Operation buttons (role-gated) --- *@
    @if (AccessRole >= CustomerAccessRole.Operator)
    {
        <div class="d-flex gap-2 mb-3">
            <button class="btn btn-sm btn-outline-warning" @onclick="RestartAllDeployments" disabled="@operationInProgress">
                <i class="bi bi-arrow-repeat me-1"></i>Restart Deployment
            </button>
        </div>
    }

    @if (podsLoading)
    {
        <div class="text-center py-4">
            <div class="spinner-border spinner-border-sm text-primary" role="status"></div>
            <p class="text-muted small mt-2">Loading pods from cluster...</p>
        </div>
    }
    else if (!string.IsNullOrEmpty(podsError))
    {
        <div class="alert alert-warning py-2 small">
            <i class="bi bi-exclamation-triangle me-1"></i>@podsError
        </div>
    }
    else if (pods is null || pods.Count == 0)
    {
        <div class="text-center py-4">
            <i class="bi bi-cpu text-muted" style="font-size: 2rem;"></i>
            <p class="text-muted small mt-2">No pods found in namespace <code>@Deployment.Namespace</code>.</p>
        </div>
    }
    else
    {
        @* --- Pod log viewer (shown above pods when active) --- *@
        @if (showLogViewer)
        {
            <div class="card border-dark mb-3">
                <div class="card-header bg-dark text-white py-2 d-flex align-items-center justify-content-between">
                    <div>
                        <i class="bi bi-terminal me-1"></i>
                        Logs: <strong>@logPodName</strong>
                        @if (!string.IsNullOrEmpty(logContainerName))
                        {
                            <span class="text-muted ms-1">(@logContainerName)</span>
                        }
                    </div>
                    <button class="btn btn-sm btn-outline-light" @onclick="CloseLogViewer">
                        <i class="bi bi-x"></i>
                    </button>
                </div>
                <div class="card-body p-0">
                    @if (logLoading)
                    {
                        <div class="text-center py-3">
                            <div class="spinner-border spinner-border-sm text-primary" role="status"></div>
                        </div>
                    }
                    else if (!string.IsNullOrEmpty(logError))
                    {
                        <div class="alert alert-warning m-2 py-1 small">@logError</div>
                    }
                    else
                    {
                        <pre class="mb-0 p-2 small bg-dark text-light" style="max-height: 400px; overflow-y: auto; white-space: pre-wrap; word-break: break-all;">@logContent</pre>
                    }
                </div>
            </div>
        }

        @* --- Pod cards --- *@
        @foreach (PodInfo pod in pods)
        {
            <div class="card mb-2">
                <div class="card-body py-2">
                    <div class="d-flex align-items-center justify-content-between">
                        <div>
                            <span class="fw-medium small">
                                <i class="bi bi-cpu me-1 @GetPodStatusColor(pod.Status)"></i>@pod.Name
                            </span>
                            <span class="badge @GetPodStatusBadgeClass(pod.Status) ms-2">@pod.Status</span>
                            <span class="text-muted small ms-2">@pod.ReadyContainers/@pod.TotalContainers ready</span>
                            @if (pod.Restarts > 0)
                            {
                                <span class="badge bg-warning text-dark ms-1">@pod.Restarts restarts</span>
                            }
                        </div>
                        <div class="d-flex gap-1">
                            @* --- Logs button (always available) --- *@
                            @if (pod.Containers.Count <= 1)
                            {
                                <button class="btn btn-sm btn-outline-dark" title="View logs"
                                        @onclick="() => ViewLogs(pod.Name, null)">
                                    <i class="bi bi-terminal"></i>
                                </button>
                            }
                            else
                            {
                                @* Multi-container: dropdown to pick container *@
                                <div class="btn-group">
                                    <button class="btn btn-sm btn-outline-dark dropdown-toggle" data-bs-toggle="dropdown"
                                            title="View logs">
                                        <i class="bi bi-terminal"></i>
                                    </button>
                                    <ul class="dropdown-menu dropdown-menu-end">
                                        @foreach (ContainerInfo container in pod.Containers)
                                        {
                                            <li>
                                                <button class="dropdown-item small"
                                                        @onclick="() => ViewLogs(pod.Name, container.Name)">
                                                    @container.Name
                                                </button>
                                            </li>
                                        }
                                    </ul>
                                </div>
                            }

                            @* --- Delete pod (Operator+ only) --- *@
                            @if (AccessRole >= CustomerAccessRole.Operator)
                            {
                                @if (confirmDeletePod == pod.Name)
                                {
                                    <button class="btn btn-sm btn-danger" @onclick="() => DeletePod(pod.Name)"
                                            disabled="@operationInProgress">
                                        Confirm
                                    </button>
                                    <button class="btn btn-sm btn-outline-secondary"
                                            @onclick="() => confirmDeletePod = null">
                                        Cancel
                                    </button>
                                }
                                else
                                {
                                    <button class="btn btn-sm btn-outline-danger" title="Delete pod"
                                            @onclick="() => confirmDeletePod = pod.Name">
                                        <i class="bi bi-trash"></i>
                                    </button>
                                }
                            }
                        </div>
                    </div>

                    @* --- Container details (expanded) --- *@
                    @if (pod.Containers.Count > 1)
                    {
                        <div class="mt-2 ms-4">
                            @foreach (ContainerInfo container in pod.Containers)
                            {
                                <div class="d-flex align-items-center text-muted small mb-1">
                                    <i class="bi bi-box me-1 @(container.Ready ? "text-success" : "text-warning")"></i>
                                    <span class="fw-medium me-2">@container.Name</span>
                                    <span class="me-2">@container.Image</span>
                                    <span class="badge @(container.Ready ? "bg-success" : "bg-warning text-dark")">
                                        @container.State
                                    </span>
                                    @if (container.RestartCount > 0)
                                    {
                                        <span class="badge bg-warning text-dark ms-1">@container.RestartCount restarts</span>
                                    }
                                </div>
                            }
                        </div>
                    }

                    @if (pod.StartTime.HasValue)
                    {
                        <div class="text-muted small mt-1 ms-4">
                            <i class="bi bi-clock me-1"></i>Started @pod.StartTime.Value.ToString("g")
                        </div>
                    }
                </div>
            </div>
        }
    }
}

@* ══════════════════════════════════════════════════════════════
   Manifests Tab
   ══════════════════════════════════════════════════════════════ *@
@if (activeTab == "manifests")
{
    @if (manifests is null)
    {
        <div class="text-center py-3">
            <div class="spinner-border spinner-border-sm text-primary" role="status"></div>
        </div>
    }
    else if (manifests.Count == 0)
    {
        <div class="text-center py-4">
            <i class="bi bi-file-earmark-code text-muted" style="font-size: 2rem;"></i>
            <p class="text-muted small mt-2">No manifests defined for this deployment.</p>
        </div>
    }
    else
    {
        @foreach (DeploymentManifest manifest in manifests)
        {
            <div class="card mb-2">
                <div class="card-header bg-white py-2">
                    <span class="badge bg-secondary me-1">@manifest.Kind</span>
                    <span class="fw-medium">@manifest.Name</span>
                </div>
                <div class="card-body p-2">
                    <pre class="mb-0 small" style="max-height: 200px; overflow-y: auto;">@manifest.YamlContent</pre>
                </div>
            </div>
        }
    }
}

@* ══════════════════════════════════════════════════════════════
   Resources Tab (ArgoCD-style tree)
   ══════════════════════════════════════════════════════════════ *@
@if (activeTab == "resources")
{
    @if (resourceTree is null)
    {
        <div class="text-center py-3">
            <div class="spinner-border spinner-border-sm text-primary" role="status"></div>
        </div>
    }
    else if (resourceTree.Count == 0)
    {
        <div class="text-center py-4">
            <i class="bi bi-diagram-3 text-muted" style="font-size: 2rem;"></i>
            <p class="text-muted small mt-2">No tracked resources.</p>
        </div>
    }
    else
    {
        @foreach (DeploymentResource root in resourceTree)
        {
            @RenderResource(root, 0)
        }
    }
}

@code {
    [Parameter] public required AppDeployment Deployment { get; set; }
    [Parameter] public CustomerAccessRole AccessRole { get; set; }
    [Parameter] public required KubernetesOperationsService K8sOps { get; set; }
    [Parameter] public required DeploymentService DeploymentService { get; set; }
    [Parameter] public EventCallback OnBack { get; set; }

    private string activeTab = "pods";

    // Pods
    private List<PodInfo>? pods;
    private bool podsLoading;
    private string? podsError;

    // Operations
    private bool operationInProgress;
    private string? operationMessage;
    private bool operationSuccess;
    private string? confirmDeletePod;

    // Logs
    private bool showLogViewer;
    private bool logLoading;
    private string logPodName = "";
    private string? logContainerName;
    private string logContent = "";
    private string? logError;

    // Manifests
    private List<DeploymentManifest>? manifests;

    // Resources
    private List<DeploymentResource>? resourceTree;

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

    // ──────── Pod operations ────────

    private async Task LoadPods()
    {
        activeTab = "pods";
        await LoadPodsInternal();
    }

    private async Task LoadPodsInternal()
    {
        podsLoading = true;
        podsError = null;
        pods = null;
        StateHasChanged();

        KubernetesOperationResult<List<PodInfo>> result = await K8sOps.GetPodsAsync(Deployment.Id);

        if (result.IsSuccess)
        {
            pods = result.Data ?? [];
        }
        else
        {
            podsError = result.Error;
        }

        podsLoading = false;
    }

    private async Task ViewLogs(string podName, string? containerName)
    {
        showLogViewer = true;
        logLoading = true;
        logPodName = podName;
        logContainerName = containerName;
        logContent = "";
        logError = null;
        StateHasChanged();

        KubernetesOperationResult<string> result = await K8sOps.GetPodLogsAsync(
            Deployment.Id, podName, containerName);

        if (result.IsSuccess)
        {
            logContent = result.Data ?? "(empty)";
        }
        else
        {
            logError = result.Error;
        }

        logLoading = false;
    }

    private void CloseLogViewer()
    {
        showLogViewer = false;
    }

    private async Task RestartAllDeployments()
    {
        operationInProgress = true;
        operationMessage = null;
        StateHasChanged();

        // Find all Deployment-kind resources tracked for this deployment
        // and restart each one. If none are tracked, try the deployment name.
        List<DeploymentResource> tree = await DeploymentService.GetResourceTreeAsync(Deployment.Id);
        List<string> deploymentNames = tree
            .Where(r => r.Kind == "Deployment")
            .Select(r => r.Name)
            .ToList();

        if (deploymentNames.Count == 0)
        {
            // Fallback: use the deployment name itself.
            deploymentNames.Add(Deployment.Name);
        }

        List<string> failures = [];

        foreach (string name in deploymentNames)
        {
            KubernetesOperationResult result = await K8sOps.RestartDeploymentAsync(Deployment.Id, name);

            if (!result.IsSuccess)
            {
                failures.Add($"{name}: {result.Error}");
            }
        }

        if (failures.Count == 0)
        {
            operationMessage = $"Rolling restart triggered for {deploymentNames.Count} deployment(s).";
            operationSuccess = true;
        }
        else
        {
            operationMessage = $"Some restarts failed: {string.Join("; ", failures)}";
            operationSuccess = false;
        }

        operationInProgress = false;

        // Refresh pods after a short delay to show new status.
        await Task.Delay(2000);
        await LoadPodsInternal();
    }

    private async Task DeletePod(string podName)
    {
        operationInProgress = true;
        confirmDeletePod = null;
        StateHasChanged();

        KubernetesOperationResult result = await K8sOps.DeletePodAsync(Deployment.Id, podName);

        if (result.IsSuccess)
        {
            operationMessage = $"Pod '{podName}' deleted. Kubernetes will create a replacement.";
            operationSuccess = true;
        }
        else
        {
            operationMessage = result.Error;
            operationSuccess = false;
        }

        operationInProgress = false;

        // Refresh pods.
        await Task.Delay(2000);
        await LoadPodsInternal();
    }

    // ──────── Manifests ────────

    private async Task LoadManifests()
    {
        activeTab = "manifests";

        if (manifests is null)
        {
            manifests = await DeploymentService.GetManifestsAsync(Deployment.Id);
        }
    }

    // ──────── Resources ────────

    private async Task LoadResources()
    {
        activeTab = "resources";

        if (resourceTree is null)
        {
            resourceTree = await DeploymentService.GetResourceTreeAsync(Deployment.Id);
        }
    }

    // ──────── Rendering helpers ────────

    private static string GetPodStatusColor(string status) => status switch
    {
        "Running" => "text-success",
        "Pending" => "text-warning",
        "Succeeded" => "text-info",
        "Failed" => "text-danger",
        _ => "text-muted"
    };

    private static string GetPodStatusBadgeClass(string status) => status switch
    {
        "Running" => "bg-success",
        "Pending" => "bg-warning text-dark",
        "Succeeded" => "bg-info",
        "Failed" => "bg-danger",
        _ => "bg-secondary"
    };

    private RenderFragment TypeBadge(DeploymentType type) => type switch
    {
        DeploymentType.Manual => @<span class="badge bg-info">Manual</span>,
        DeploymentType.Yaml => @<span class="badge bg-warning text-dark">YAML</span>,
        DeploymentType.HelmChart => @<span class="badge bg-purple text-white" style="background-color: #6f42c1 !important;">Helm</span>,
        _ => @<span class="badge bg-secondary">Unknown</span>
    };

    private RenderFragment SyncBadge(SyncStatus status) => status switch
    {
        SyncStatus.Synced => @<span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Synced</span>,
        SyncStatus.OutOfSync => @<span class="badge bg-warning text-dark"><i class="bi bi-exclamation-circle me-1"></i>OutOfSync</span>,
        SyncStatus.Syncing => @<span class="badge bg-info"><i class="bi bi-arrow-repeat me-1"></i>Syncing</span>,
        SyncStatus.Failed => @<span class="badge bg-danger"><i class="bi bi-x-circle me-1"></i>Failed</span>,
        _ => @<span class="badge bg-secondary">Unknown</span>
    };

    private RenderFragment HealthBadge(HealthStatus status) => status switch
    {
        HealthStatus.Healthy => @<span class="badge bg-success"><i class="bi bi-heart-fill me-1"></i>Healthy</span>,
        HealthStatus.Progressing => @<span class="badge bg-info"><i class="bi bi-hourglass-split me-1"></i>Progressing</span>,
        HealthStatus.Degraded => @<span class="badge bg-warning text-dark"><i class="bi bi-exclamation-triangle me-1"></i>Degraded</span>,
        HealthStatus.Missing => @<span class="badge bg-danger"><i class="bi bi-question-circle me-1"></i>Missing</span>,
        HealthStatus.Suspended => @<span class="badge bg-secondary"><i class="bi bi-pause-circle me-1"></i>Suspended</span>,
        _ => @<span class="badge bg-secondary">Unknown</span>
    };

    private RenderFragment RenderResource(DeploymentResource resource, int depth) => __builder =>
    {
        <div class="d-flex align-items-center py-1 border-bottom" style="padding-left: @(depth * 24)px;">
            <span class="badge bg-secondary me-2 small">@resource.Kind</span>
            <span class="fw-medium small flex-grow-1">@resource.Name</span>
            <div class="d-flex gap-1">
                @SyncBadge(resource.SyncStatus)
                @HealthBadge(resource.HealthStatus)
            </div>
        </div>
        @if (resource.ChildResources?.Count > 0)
        {
            @foreach (DeploymentResource child in resource.ChildResources)
            {
                @RenderResource(child, depth + 1)
            }
        }
    };
}
