package cluster

import (
	"context"
	"fmt"
)

// K3dClusterStep is the real cluster_create step that:
// 1. Ensures k3d is installed (auto-installs if missing)
// 2. Checks if the cluster already exists and is healthy
// 3. Creates the cluster if it doesn't exist or is unhealthy
type K3dClusterStep struct {
	ClusterName string
	Agents      int
	Memory      string
	K3dVersion  string
	K3sImage    string
}

func (s *K3dClusterStep) Name() StepName { return StepClusterCreate }

func (s *K3dClusterStep) Run(ctx context.Context) error {
	// Step 1: Ensure k3d is installed
	if err := EnsureK3d(ctx, s.K3dVersion); err != nil {
		return fmt.Errorf("ensure k3d: %w", err)
	}

	k3d := &ExecK3dClient{}

	// Step 2: Check if cluster already exists and is healthy
	healthy, err := k3d.ClusterHealthy(ctx, s.ClusterName)
	if err != nil {
		return fmt.Errorf("check cluster health: %w", err)
	}
	if healthy {
		return nil // Cluster is already running, nothing to do
	}

	// Step 3: If cluster exists but is unhealthy, delete and recreate
	exists, err := k3d.ClusterExists(ctx, s.ClusterName)
	if err != nil {
		return fmt.Errorf("check cluster: %w", err)
	}
	if exists {
		if err := k3d.DeleteCluster(ctx, s.ClusterName); err != nil {
			return fmt.Errorf("delete unhealthy cluster: %w", err)
		}
	}

	// Step 4: Create cluster
	if s.K3sImage != "" {
		return k3d.CreateClusterWithImage(ctx, s.ClusterName, s.Agents, s.Memory, s.K3sImage, nil, nil)
	}
	return k3d.CreateCluster(ctx, s.ClusterName, s.Agents, s.Memory, nil, nil)
}

// NewK3dClusterStep creates a K3dClusterStep from config values.
func NewK3dClusterStep(clusterName string, agents int, memory, k3dVersion, k3sImage string) *K3dClusterStep {
	return &K3dClusterStep{
		ClusterName: clusterName,
		Agents:      agents,
		Memory:      memory,
		K3dVersion:  k3dVersion,
		K3sImage:    k3sImage,
	}
}
