using EntKube.Clusters.Domain;
using EntKube.SharedKernel.Domain;

namespace EntKube.Clusters.Features.RegisterCluster;

/// <summary>
/// Handles the registration of a new Kubernetes cluster into the platform.
/// A tenant admin provides the cluster name, API server URL, and optionally
/// a kubeconfig secret reference. We validate the input, create the cluster
/// aggregate, and persist it. The cluster starts in Pending state until the
/// background health-check service confirms connectivity.
/// </summary>
public class RegisterClusterHandler
{
    private readonly IClusterRepository repository;

    public RegisterClusterHandler(IClusterRepository repository)
    {
        this.repository = repository;
    }

    public async Task<Result<Guid>> HandleAsync(RegisterClusterRequest request, CancellationToken ct = default)
    {
        // Validate that the caller provided the minimum required information.
        // Without a name and API URL, we cannot register a cluster.

        if (string.IsNullOrWhiteSpace(request.Name))
        {
            return Result.Failure<Guid>("Cluster name is required.");
        }

        if (string.IsNullOrWhiteSpace(request.ApiServerUrl))
        {
            return Result.Failure<Guid>("API server URL is required.");
        }

        // Create the cluster aggregate using the domain factory method.
        // This encapsulates all the business rules for what a valid new cluster looks like.

        KubernetesCluster cluster = KubernetesCluster.Register(
            request.Name,
            request.ApiServerUrl,
            request.KubeConfigSecret);

        // Persist the new cluster so it can be picked up by the health-check background service.

        await repository.AddAsync(cluster, ct);

        return Result.Success(cluster.Id);
    }
}

public record RegisterClusterRequest(string Name, string ApiServerUrl, string? KubeConfigSecret);
