package common

import (
	"context"
	"fmt"
	"time"

	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/key/task"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/deploy"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/util"
)

// Guardian adds and removes the finalizer of the Key.
type Guardian struct {
	*task.BaseTask
}

func NewGuardian(ctx *task.Context) *Guardian {
	return &Guardian{BaseTask: &task.BaseTask{Context: ctx}}
}

func (t *Guardian) Name() string {
	return "Guardian"
}

func (t *Guardian) Create(ctx context.Context) deploy.Result {
	t.BeginAt = util.Pointer(time.Now())

	// Add finalizer
	if !controllerutil.ContainsFinalizer(t.Key, v1alpha1.Finalizer) {
		controllerutil.AddFinalizer(t.Key, v1alpha1.Finalizer)
		// Require immediate requeue without running other tasks
		return deploy.Panic(nil).WithRequeuAfter(0)
	}

	// Check key phase and set to Creating if needed
	switch phase := t.Key.Status.Phase; phase {
	case "", v1alpha1.KeyPhaseFailed:
		t.Key.Status.Phase = v1alpha1.KeyPhaseCreating
	case v1alpha1.KeyPhaseCreating, v1alpha1.KeyPhaseActive:
		// Valid phases during creation, no change needed
	default:
		return deploy.Panic(fmt.Errorf("unexpected key phase during creation: %s", phase))
	}

	return deploy.Done()
}

func (t *Guardian) Delete(ctx context.Context) deploy.Result {
	if err := t.readyToDelete(ctx); err != nil {
		return deploy.Panic(err).WithRequeuAfter(30 * time.Second)
	}
	return deploy.Done()
}

// Check if the dependent objects are deleted
func (t *Guardian) readyToDelete(ctx context.Context) error {
	// For now, we don't have specific dependent resources to check for Keys
	// This is where we would check for resources that depend on this Key
	// For example, if there were resources that reference this Key, we would check them here

	// In the future, this might include checking for:
	// - Resources that use this Key for encryption
	// - Services that depend on this Key
	// - Other infrastructure components that reference this Key

	// For now, we allow deletion to proceed
	return nil
}
