package delete

import (
	"fmt"

	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/config"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/dataplane"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/di"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/helm"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/workflow"
	"gorm.io/gorm"

	"github.com/tidbcloud/metrics-integration/global/internal/domain/entity"
	helmpackage "github.com/tidbcloud/metrics-integration/global/pkg/helm/pipeline"

	"github.com/shiningrush/fastflow/pkg/entity/run"
)

type PipelineDeleteAction struct{}

func (a *PipelineDeleteAction) Name() string {
	return "PipelineDeleteAction"
}

func (a *PipelineDeleteAction) Run(ctx run.ExecuteContext, params interface{}) error {
	id, err := workflow.GetUint64FromRunVar(ctx, "id")
	if err != nil {
		return fmt.Errorf("invalid id: %v", err)
	}

	pipelineMetaData := &entity.Integration{}
	if err := di.DiCall(func(db *gorm.DB) error {
		// Use Unscoped() to include soft-deleted records (deleted_at NOT NULL)
		return db.Unscoped().First(pipelineMetaData, id).Error
	}); err != nil {
		return fmt.Errorf("failed to get pipeline from db: %w", err)
	}

	// helm deploy

	packageConfig := &helmpackage.PipelineConfig{
		PipelineID: fmt.Sprintf("%d", id),
	}

	serverAddr := config.Global().RegionalExecutorConfig.GetPipelineDataplaneServerAddr(id, string(pipelineMetaData.CloudProviderType), pipelineMetaData.Region)
	if serverAddr != "" {
		if err := helm.RemoteUninstall(ctx.Context(), packageConfig, serverAddr); err != nil {
			return fmt.Errorf("failed to remove helm chart: %w", err)
		}
	} else {
		// get dataplane rest config
		restConfig, err := dataplane.GetRestConfig(pipelineMetaData.Region)
		if err != nil {
			return fmt.Errorf("failed to get rest config: %w", err)
		}

		if err := helm.Uninstall(ctx.Context(), restConfig, packageConfig); err != nil {
			return err
		}

		if err := helm.RemoveNamespaceIfExists(ctx.Context(), restConfig, packageConfig); err != nil {
			return fmt.Errorf("failed to remove namespace: %w", err)
		}
	}

	skipDBDeletion := workflow.GetStringFromRunVar(ctx, "skip_db_deletion")
	if skipDBDeletion != "true" {
		// update metadb: delete Integration and GeneralIntegration records in a transaction
		if err := di.DiCall(func(db *gorm.DB) error {
			return db.Transaction(func(tx *gorm.DB) error {
				if result := tx.Delete(&entity.Integration{}, "id = ?", id); result.Error != nil {
					return result.Error
				}
				// also attempt to delete corresponding GeneralIntegration with same id
				// (skip if it doesn't exist)
				if err := tx.Where("id = ?", id).Delete(&entity.GeneralIntegration{}).Error; err != nil {
					// If the error is record not found, ignore; otherwise return
					return err
				}
				return nil
			})
		}); err != nil {
			return fmt.Errorf("write metadb failed: %s", err)
		}
	}

	return nil
}
