package config

import (
	"fmt"
	"strings"
)

// RestoreProfile defines resource settings for restore operations
type RestoreProfile struct {
	Name               string
	ParallelDBs        int  // Number of databases to restore in parallel
	Jobs               int  // Parallel decompression jobs
	DisableProgress    bool // Disable progress indicators to reduce overhead
	MemoryConservative bool // Use memory-conservative settings
}

// GetRestoreProfile returns the profile settings for a given profile name
func GetRestoreProfile(profileName string) (*RestoreProfile, error) {
	profileName = strings.ToLower(strings.TrimSpace(profileName))

	switch profileName {
	case "conservative":
		return &RestoreProfile{
			Name:               "conservative",
			ParallelDBs:        1, // Single-threaded restore
			Jobs:               1, // Single-threaded decompression
			DisableProgress:    false,
			MemoryConservative: true,
		}, nil

	case "balanced", "":
		return &RestoreProfile{
			Name:               "balanced",
			ParallelDBs:        0, // Use config default or auto-detect
			Jobs:               0, // Use config default or auto-detect
			DisableProgress:    false,
			MemoryConservative: false,
		}, nil

	case "aggressive", "performance":
		return &RestoreProfile{
			Name:               "aggressive",
			ParallelDBs:        -1, // Auto-detect based on resources
			Jobs:               -1, // Auto-detect based on CPU
			DisableProgress:    false,
			MemoryConservative: false,
		}, nil

	case "potato":
		// Easter egg: same as conservative but with a fun name
		return &RestoreProfile{
			Name:               "potato",
			ParallelDBs:        1,
			Jobs:               1,
			DisableProgress:    false,
			MemoryConservative: true,
		}, nil

	case "turbo":
		// TURBO MODE: Maximum parallelism for fastest restore
		// Matches native pg_restore -j8 performance
		return &RestoreProfile{
			Name:               "turbo",
			ParallelDBs:        4, // 4 DBs in parallel (balanced I/O)
			Jobs:               8, // pg_restore --jobs=8
			DisableProgress:    false,
			MemoryConservative: false,
		}, nil

	case "max-performance", "maxperformance", "max":
		// Maximum performance for high-end servers
		// Use for dedicated restore operations where speed is critical
		return &RestoreProfile{
			Name:               "max-performance",
			ParallelDBs:        8,    // 8 DBs in parallel
			Jobs:               16,   // pg_restore --jobs=16
			DisableProgress:    true, // Reduce TUI overhead
			MemoryConservative: false,
		}, nil

	default:
		return nil, fmt.Errorf("unknown profile: %s (valid: conservative, balanced, aggressive, turbo, max-performance)", profileName)
	}
}

// ApplyProfile applies profile settings to config, respecting explicit user overrides
func ApplyProfile(cfg *Config, profileName string, explicitJobs, explicitParallelDBs int) error {
	profile, err := GetRestoreProfile(profileName)
	if err != nil {
		return err
	}

	// Show profile being used
	if cfg.Debug {
		fmt.Printf("Using restore profile: %s\n", profile.Name)
		if profile.MemoryConservative {
			fmt.Println("Memory-conservative mode enabled")
		}
	}

	// Apply profile settings only if not explicitly overridden
	if explicitJobs == 0 && profile.Jobs > 0 {
		cfg.Jobs = profile.Jobs
	}

	if explicitParallelDBs == 0 && profile.ParallelDBs != 0 {
		cfg.ClusterParallelism = profile.ParallelDBs
	}

	// Store profile name
	cfg.ResourceProfile = profile.Name

	// Conservative profile implies large DB mode settings
	if profile.MemoryConservative {
		cfg.LargeDBMode = true
	}

	return nil
}

// GetProfileDescription returns a human-readable description of the profile
func GetProfileDescription(profileName string) string {
	profile, err := GetRestoreProfile(profileName)
	if err != nil {
		return "Unknown profile"
	}

	switch profile.Name {
	case "conservative":
		return "Conservative: --jobs=1, single-threaded, minimal memory usage. Best for resource-constrained servers."
	case "potato":
		return "Potato Mode: Same as conservative, for servers running on a potato 🥔"
	case "balanced":
		return "Balanced: Auto-detect resources, moderate parallelism. Good default for most scenarios."
	case "aggressive":
		return "Aggressive: Maximum parallelism, all available resources. Best for dedicated database servers."
	case "turbo":
		return "Turbo: --jobs=8, 4 parallel DBs. Matches pg_restore -j8 speed. Great for production restores."
	case "max-performance":
		return "Max-Performance: --jobs=16, 8 parallel DBs, TUI disabled. For dedicated restore operations."
	default:
		return profile.Name
	}
}

// ListProfiles returns a list of all available profiles with descriptions
func ListProfiles() map[string]string {
	return map[string]string{
		"conservative":    GetProfileDescription("conservative"),
		"balanced":        GetProfileDescription("balanced"),
		"turbo":           GetProfileDescription("turbo"),
		"max-performance": GetProfileDescription("max-performance"),
		"aggressive":      GetProfileDescription("aggressive"),
		"potato":          GetProfileDescription("potato"),
	}
}
