package config

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/spf13/viper"
)

func Load(path string) (*Config, error) {
	v := viper.New()

	// Try to find config file - support multiple paths
	configPath := resolveConfigPath(path)
	if configPath == "" {
		return nil, fmt.Errorf("config file not found at: %s (and no alternative paths worked)", path)
	}

	v.SetConfigFile(configPath)
	v.SetConfigType("yaml")
	v.SetEnvPrefix("SECURITY_CENTER")
	v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	v.AutomaticEnv()

	setDefaults(v)

	if err := v.ReadInConfig(); err != nil {
		return nil, fmt.Errorf("read config: %w", err)
	}

	var cfg Config
	if err := v.Unmarshal(&cfg); err != nil {
		return nil, fmt.Errorf("decode config: %w", err)
	}

	return &cfg, nil
}

// resolveConfigPath tries to find the config file in multiple locations
func resolveConfigPath(defaultPath string) string {
	// Check if environment variable is set
	if envPath := os.Getenv("SECURITY_CENTER_CONFIG_PATH"); envPath != "" {
		if _, err := os.Stat(envPath); err == nil {
			return envPath
		}
	}

	// Try the provided path
	if _, err := os.Stat(defaultPath); err == nil {
		return defaultPath
	}

	// Try relative to current working directory
	cwd, err := os.Getwd()
	if err == nil {
		paths := []string{
			filepath.Join(cwd, "configs/config.yaml"),
			filepath.Join(cwd, "config.yaml"),
		}
		for _, p := range paths {
			if _, err := os.Stat(p); err == nil {
				return p
			}
		}
	}

	// Try relative to executable directory
	exePath, err := os.Executable()
	if err == nil {
		exeDir := filepath.Dir(exePath)
		paths := []string{
			filepath.Join(exeDir, "configs/config.yaml"),
			filepath.Join(exeDir, "config.yaml"),
			filepath.Join(filepath.Dir(exeDir), "configs/config.yaml"),
		}
		for _, p := range paths {
			if _, err := os.Stat(p); err == nil {
				return p
			}
		}
	}

	return ""
}

func setDefaults(v *viper.Viper) {
	v.SetDefault("app.name", "security-center")
	v.SetDefault("app.environment", "development")
	v.SetDefault("http.host", "0.0.0.0")
	v.SetDefault("http.port", 8080)
	v.SetDefault("http.read_timeout", "15s")
	v.SetDefault("http.write_timeout", "15s")
	v.SetDefault("http.shutdown_timeout", "10s")
	v.SetDefault("log.level", "info")
	v.SetDefault("log.format", "json")
	v.SetDefault("auth.bypass_sso", false)
	v.SetDefault("auth.dev_user.id", "dev-user")
	v.SetDefault("auth.dev_user.email", "dev.user@example.com")
	v.SetDefault("auth.dev_user.name", "Development User")
	v.SetDefault("auth.dev_user.roles", []string{"admin"})
	v.SetDefault("database.max_open_conns", 50)
	v.SetDefault("database.max_idle_conns", 10)
	v.SetDefault("database.conn_max_lifetime", "1h")
	v.SetDefault("redis.db", 0)
	v.SetDefault("redis.dial_timeout", "5s")
	v.SetDefault("redis.read_timeout", "2s")
	v.SetDefault("redis.write_timeout", "2s")
	v.SetDefault("jwt.access_token_ttl", "24h")
	v.SetDefault("jwt.refresh_token_ttl", "168h")
	v.SetDefault("jwt.refresh_grace_period", "15m")
	v.SetDefault("jwt.signing_algorithm", "HS256")
	v.SetDefault("oauth.enabled", true)
}
