package config

import (
	"encoding/json"
	"os"
	"strconv"
)

type Config struct {
	Server struct {
		Port int `json:"port"`
	} `json:"server"`
	InfluxDB struct {
		URL      string `json:"url"`
		Token    string `json:"token"`
		Org      string `json:"org"`
		Bucket   string `json:"bucket"`
		Username string `json:"username"`
		Password string `json:"password"`
	} `json:"influxdb"`
	DB struct {
		Type     string `json:"type"`
		Host     string `json:"host"`
		Port     int    `json:"port"`
		Username string `json:"username"`
		Password string `json:"password"`
		Database string `json:"database"`
		SSLMode  string `json:"ssl_mode"`
		Charset  string `json:"charset"`
	} `json:"db"`
}

func LoadConfig() (*Config, error) {
	// 创建默认配置
	cfg := &Config{}

	// 设置默认值
	cfg.Server.Port = 8080
	cfg.InfluxDB.URL = "http://localhost:8086"
	cfg.InfluxDB.Token = ""
	cfg.InfluxDB.Org = "monitor"
	cfg.InfluxDB.Bucket = "monitor"
	cfg.InfluxDB.Username = ""
	cfg.InfluxDB.Password = ""

	// 数据库默认配置（只支持MySQL）
	cfg.DB.Type = "mysql"
	cfg.DB.Host = "localhost"
	cfg.DB.Port = 3306
	cfg.DB.Username = "root"
	cfg.DB.Password = ""
	cfg.DB.Database = "monitor"
	cfg.DB.SSLMode = "disable"
	cfg.DB.Charset = "utf8mb4"

	// 从配置文件读取配置
	readConfigFile(cfg)

	// 从环境变量读取配置（优先级高于配置文件）
	loadFromEnv(cfg)

	return cfg, nil
}

// 从配置文件读取配置
func readConfigFile(cfg *Config) {
	// 获取配置文件路径，默认./config.json，可通过环境变量指定
	configFile := os.Getenv("SERVER_CONFIG_FILE")
	if configFile == "" {
		configFile = "./config.json"
	}

	// 检查配置文件是否存在
	if _, err := os.Stat(configFile); os.IsNotExist(err) {
		return
	}

	// 读取配置文件
	content, err := os.ReadFile(configFile)
	if err != nil {
		return
	}

	// 解析配置文件
	var fileConfig Config
	if err := json.Unmarshal(content, &fileConfig); err != nil {
		return
	}

	// 合并配置：只覆盖非零值
	if fileConfig.Server.Port != 0 {
		cfg.Server.Port = fileConfig.Server.Port
	}

	if fileConfig.InfluxDB.URL != "" {
		cfg.InfluxDB.URL = fileConfig.InfluxDB.URL
	}

	if fileConfig.InfluxDB.Token != "" {
		cfg.InfluxDB.Token = fileConfig.InfluxDB.Token
	}

	if fileConfig.InfluxDB.Org != "" {
		cfg.InfluxDB.Org = fileConfig.InfluxDB.Org
	}

	if fileConfig.InfluxDB.Bucket != "" {
		cfg.InfluxDB.Bucket = fileConfig.InfluxDB.Bucket
	}

	if fileConfig.InfluxDB.Username != "" {
		cfg.InfluxDB.Username = fileConfig.InfluxDB.Username
	}

	if fileConfig.InfluxDB.Password != "" {
		cfg.InfluxDB.Password = fileConfig.InfluxDB.Password
	}

	// 合并数据库配置
	if fileConfig.DB.Type != "" {
		cfg.DB.Type = fileConfig.DB.Type
	}

	if fileConfig.DB.Host != "" {
		cfg.DB.Host = fileConfig.DB.Host
	}

	if fileConfig.DB.Port != 0 {
		cfg.DB.Port = fileConfig.DB.Port
	}

	if fileConfig.DB.Username != "" {
		cfg.DB.Username = fileConfig.DB.Username
	}

	if fileConfig.DB.Password != "" {
		cfg.DB.Password = fileConfig.DB.Password
	}

	if fileConfig.DB.Database != "" {
		cfg.DB.Database = fileConfig.DB.Database
	}

	if fileConfig.DB.SSLMode != "" {
		cfg.DB.SSLMode = fileConfig.DB.SSLMode
	}

	if fileConfig.DB.Charset != "" {
		cfg.DB.Charset = fileConfig.DB.Charset
	}
}

// SaveConfig 保存配置到文件
func SaveConfig(cfg *Config) error {
	// 获取配置文件路径，默认./config.json，可通过环境变量指定
	configFile := os.Getenv("SERVER_CONFIG_FILE")
	if configFile == "" {
		configFile = "./config.json"
	}

	// 将配置转换为JSON
	jsonData, err := json.MarshalIndent(cfg, "", "  ")
	if err != nil {
		return err
	}

	// 写入配置文件
	return os.WriteFile(configFile, jsonData, 0644)
}

// 从环境变量读取配置
func loadFromEnv(cfg *Config) {
	// Server config
	if portStr := os.Getenv("SERVER_PORT"); portStr != "" {
		if port, err := strconv.Atoi(portStr); err == nil {
			cfg.Server.Port = port
		}
	}

	// InfluxDB config
	if url := os.Getenv("INFLUXDB_URL"); url != "" {
		cfg.InfluxDB.URL = url
	}

	if token := os.Getenv("INFLUXDB_TOKEN"); token != "" {
		cfg.InfluxDB.Token = token
	}

	if org := os.Getenv("INFLUXDB_ORG"); org != "" {
		cfg.InfluxDB.Org = org
	}

	if bucket := os.Getenv("INFLUXDB_BUCKET"); bucket != "" {
		cfg.InfluxDB.Bucket = bucket
	}

	if username := os.Getenv("INFLUXDB_USERNAME"); username != "" {
		cfg.InfluxDB.Username = username
	}

	if password := os.Getenv("INFLUXDB_PASSWORD"); password != "" {
		cfg.InfluxDB.Password = password
	}

	// Database config
	if dbType := os.Getenv("DB_TYPE"); dbType != "" {
		cfg.DB.Type = dbType
	}

	if dbHost := os.Getenv("DB_HOST"); dbHost != "" {
		cfg.DB.Host = dbHost
	}

	if dbPortStr := os.Getenv("DB_PORT"); dbPortStr != "" {
		if dbPort, err := strconv.Atoi(dbPortStr); err == nil {
			cfg.DB.Port = dbPort
		}
	}

	if dbUsername := os.Getenv("DB_USERNAME"); dbUsername != "" {
		cfg.DB.Username = dbUsername
	}

	if dbPassword := os.Getenv("DB_PASSWORD"); dbPassword != "" {
		cfg.DB.Password = dbPassword
	}

	if dbDatabase := os.Getenv("DB_DATABASE"); dbDatabase != "" {
		cfg.DB.Database = dbDatabase
	}

	if dbSSLMode := os.Getenv("DB_SSL_MODE"); dbSSLMode != "" {
		cfg.DB.SSLMode = dbSSLMode
	}

	if dbCharset := os.Getenv("DB_CHARSET"); dbCharset != "" {
		cfg.DB.Charset = dbCharset
	}
}
