package config

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

	"github.com/spf13/viper"
)

const (
	BaseDir       string = "/etc/sunhpc"
	LogDir        string = "/var/log/sunhpc"
	TmplDir       string = BaseDir + "/tmpl.d"
	appName       string = "sunhpc"
	defaultDBPath string = "/var/lib/sunhpc"
	defaultDBName string = "sunhpc.db"
)

type Config struct {
	DB      DBConfig      `yaml:"db"`
	Log     LogConfig     `yaml:"log"`
	Cluster ClusterConfig `yaml:"cluster"`
}

type DBConfig struct {
	Type     string `yaml:"type"`
	Path     string `yaml:"path"` // SQLite: 目录路径
	Name     string `yaml:"name"` // SQLite: 文件名
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	Socket   string `yaml:"socket"`
	Verbose  bool   `yaml:"verbose"`
}

type LogConfig struct {
	Level    string `yaml:"level"`
	Format   string `yaml:"format"`
	Output   string `yaml:"output"`
	FilePath string `yaml:"file_path"`
}

type ClusterConfig struct {
	Name       string `yaml:"name"`
	AdminEmail string `yaml:"admin_email"`
	TimeZone   string `yaml:"time_zone"`
	NodePrefix string `yaml:"node_prefix"`
}

// LoadConfig loads configuration with the following precedence:
// 优先级排序:
// 1. 环境变量 (prefix: SUNHPC_)
// 2. ~/.sunhpc.yaml
// 3. ./sunhpc.yaml
// 4. /etc/sunhpc/sunhpc.yaml
// 5. Default values
/*
	示例配置文件:
	```yaml
	db:
	  type: sqlite
	  name: sunhpc.db
	  path: /var/lib/sunhpc
	  socket: /var/lib/sunhpc/mysql/mysqld.sock
	  user: root
	  password: ""
	  host: localhost
	```

	环境变量配置示例:
	```bash
	export SUNHPC_DATABASE_TYPE=mysql
	export SUNHPC_DATABASE_NAME=sunhpc
	export SUNHPC_DATABASE_USER=root
	export SUNHPC_DATABASE_PASSWORD=123456
	export SUNHPC_DATABASE_HOST=localhost
	```
*/
func LoadConfig() (*Config, error) {
	v := viper.New()

	// Step 1: 设置默认值(最低优先级)
	v.SetDefault("db.type", "sqlite")
	v.SetDefault("db.name", "sunhpc.db")
	v.SetDefault("db.path", "/var/lib/sunhpc")
	v.SetDefault("db.socket", "/var/lib/sunhpc/mysql/mysqld.sock")
	v.SetDefault("db.user", "")
	v.SetDefault("db.password", "")
	v.SetDefault("db.host", "localhost")
	v.SetDefault("db.port", 3306)
	v.SetDefault("db.verbose", false)

	// Step 2: 启用环境变量（高优先级）
	v.SetEnvPrefix("SUNHPC")                           // e.g., SUNHPC_DATABASE_NAME
	v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) // db.type -> SUNHPC_DB_TYPE
	v.AutomaticEnv()                                   // Auto bind env vars matching config keys

	// Step 3: 按优先级从高到低加载配置文件
	// 优先级: env > ./sunhpc.yaml > ~/.sunhpc.yaml > /etc/sunhpc/sunhpc.yaml > defaults
	configFiles := []string{
		"./sunhpc.yaml",
		filepath.Join(os.Getenv("HOME"), ".sunhpc.yaml"),
		filepath.Join(BaseDir, "sunhpc.yaml"),
	}

	var configFile string
	for _, cfgFile := range configFiles {
		if _, err := os.Stat(cfgFile); err == nil {
			configFile = cfgFile
			break // 找到第一个就停止.
		}
	}

	// 如果找到配置文件，就加载它.
	if configFile != "" {
		v.SetConfigFile(configFile)
		if err := v.ReadInConfig(); err != nil {
			return nil, fmt.Errorf("加载配置文件 %s 失败: %w", configFile, err)
		}
	}

	// 解码到结构体
	var cfg Config
	if err := v.Unmarshal(&cfg); err != nil {
		return nil, fmt.Errorf("解码配置到结构体失败: %w", err)
	}

	return &cfg, nil
}

// InitDirs 创建所有必需目录
func InitDirs() error {
	dirs := []string{
		BaseDir,
		TmplDir,
		LogDir,
	}
	for _, d := range dirs {
		if err := os.MkdirAll(d, 0755); err != nil {
			return fmt.Errorf("创建目录 %s 失败: %w", d, err)
		}
	}
	return nil
}
