// ABOUTME: Resource management for EdgeConnect delete command with deletion execution
// ABOUTME: Handles actual deletion operations with proper ordering (instances first, then app)
package v1

import (
	"context"
	"fmt"
	"time"

	"edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect"
)

// ResourceManagerInterface defines the interface for resource management
type ResourceManagerInterface interface {
	// ExecuteDeletion executes a deletion plan
	ExecuteDeletion(ctx context.Context, plan *DeletionPlan) (*DeletionResult, error)
}

// EdgeConnectResourceManager implements resource management for EdgeConnect
type EdgeConnectResourceManager struct {
	client EdgeConnectClientInterface
	logger Logger
}

// Logger interface for deletion logging
type Logger interface {
	Printf(format string, v ...interface{})
}

// ResourceManagerOptions configures the resource manager behavior
type ResourceManagerOptions struct {
	// Logger for deletion operations
	Logger Logger
}

// DefaultResourceManagerOptions returns sensible defaults
func DefaultResourceManagerOptions() ResourceManagerOptions {
	return ResourceManagerOptions{
		Logger: nil,
	}
}

// NewResourceManager creates a new EdgeConnect resource manager
func NewResourceManager(client EdgeConnectClientInterface, opts ...func(*ResourceManagerOptions)) ResourceManagerInterface {
	options := DefaultResourceManagerOptions()
	for _, opt := range opts {
		opt(&options)
	}

	return &EdgeConnectResourceManager{
		client: client,
		logger: options.Logger,
	}
}

// WithLogger sets a logger for deletion operations
func WithLogger(logger Logger) func(*ResourceManagerOptions) {
	return func(opts *ResourceManagerOptions) {
		opts.Logger = logger
	}
}

// ExecuteDeletion executes a deletion plan
// Important: Instances must be deleted before the app
func (rm *EdgeConnectResourceManager) ExecuteDeletion(ctx context.Context, plan *DeletionPlan) (*DeletionResult, error) {
	startTime := time.Now()
	rm.logf("Starting deletion: %s", plan.ConfigName)

	result := &DeletionResult{
		Plan:             plan,
		Success:          true,
		CompletedActions: []DeletionActionResult{},
		FailedActions:    []DeletionActionResult{},
	}

	// If plan is empty, return success immediately
	if plan.IsEmpty() {
		rm.logf("No resources to delete")
		result.Duration = time.Since(startTime)
		return result, nil
	}

	// Step 1: Delete all instances first
	for _, instance := range plan.InstancesToDelete {
		actionStart := time.Now()
		rm.logf("Deleting instance: %s", instance.Name)

		instanceKey := edgeconnect.AppInstanceKey{
			Organization: instance.Organization,
			Name:         instance.Name,
			CloudletKey: edgeconnect.CloudletKey{
				Organization: instance.CloudletOrg,
				Name:         instance.CloudletName,
			},
		}

		err := rm.client.DeleteAppInstance(ctx, instanceKey, instance.Region)
		actionResult := DeletionActionResult{
			Type:     "instance",
			Target:   instance.Name,
			Duration: time.Since(actionStart),
		}

		if err != nil {
			rm.logf("Failed to delete instance %s: %v", instance.Name, err)
			actionResult.Success = false
			actionResult.Error = err
			result.FailedActions = append(result.FailedActions, actionResult)
			result.Success = false
			result.Error = fmt.Errorf("failed to delete instance %s: %w", instance.Name, err)
			result.Duration = time.Since(startTime)
			return result, result.Error
		}

		rm.logf("Successfully deleted instance: %s", instance.Name)
		actionResult.Success = true
		result.CompletedActions = append(result.CompletedActions, actionResult)
	}

	// Step 2: Delete the app (only after all instances are deleted)
	if plan.AppToDelete != nil {
		actionStart := time.Now()
		app := plan.AppToDelete
		rm.logf("Deleting app: %s version %s", app.Name, app.Version)

		appKey := edgeconnect.AppKey{
			Organization: app.Organization,
			Name:         app.Name,
			Version:      app.Version,
		}

		err := rm.client.DeleteApp(ctx, appKey, app.Region)
		actionResult := DeletionActionResult{
			Type:     "app",
			Target:   fmt.Sprintf("%s:%s", app.Name, app.Version),
			Duration: time.Since(actionStart),
		}

		if err != nil {
			rm.logf("Failed to delete app %s: %v", app.Name, err)
			actionResult.Success = false
			actionResult.Error = err
			result.FailedActions = append(result.FailedActions, actionResult)
			result.Success = false
			result.Error = fmt.Errorf("failed to delete app %s: %w", app.Name, err)
			result.Duration = time.Since(startTime)
			return result, result.Error
		}

		rm.logf("Successfully deleted app: %s", app.Name)
		actionResult.Success = true
		result.CompletedActions = append(result.CompletedActions, actionResult)
	}

	result.Duration = time.Since(startTime)
	rm.logf("Deletion completed successfully in %v", result.Duration)

	return result, nil
}

// logf logs a message if a logger is configured
func (rm *EdgeConnectResourceManager) logf(format string, v ...interface{}) {
	if rm.logger != nil {
		rm.logger.Printf(format, v...)
	}
}
