package config

import (
	"os"

	"github.com/coroot/coroot-node-agent/flags"
	klog "github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

// shouldUpdateConfig 判断是否应该更新配置
// 热更新时，如果配置项通过命令行参数或环境变量设置，则不更新
func shouldUpdateConfig(configKey, envKey1, envKey2 string, currentValue, configValue, defaultValue string, isHotReload bool) bool {
	// 检查环境变量（无论是初始加载还是热更新）
	if os.Getenv(envKey1) != "" || os.Getenv(envKey2) != "" {
		if isHotReload {
			klog.Debugf("[config] Skipping %s update (set via environment variable)", configKey)
		}
		return false
	}

	// 检查当前值是否与默认值不同
	// 如果不同，说明是通过命令行参数设置的（因为 kingpin.Parse() 已经处理了命令行参数）
	// 无论是初始加载还是热更新，都不应该被配置文件覆盖
	if currentValue != defaultValue {
		if isHotReload {
			klog.Debugf("[config] Skipping %s update (set via command line: %s)", configKey, currentValue)
		} else {
			klog.Debugf("[config] Skipping %s update from config file (set via command line: %s)", configKey, currentValue)
		}
		return false
	}

	// 当前值等于默认值，说明没有通过命令行参数设置，可以更新
	return true
}

// applyConfig 应用配置到 flags
// isHotReload: true 表示热更新，false 表示初始加载
// 热更新时不会覆盖通过命令行参数或环境变量设置的配置项
// 注意：ConfigServer 和 DataServer 的最高优先级是 common.ini（如果 RunInOmniagent 为 true），不受此函数影响
func applyConfig(v *viper.Viper, isHotReload bool) {
	klog.Infof("═══════════════════════════════════════════════════════════════")
	if isHotReload {
		klog.Infof("🔄 [CONFIG] Starting hot reload configuration...")
	} else {
		klog.Infof("📋 [CONFIG] Starting initial configuration load...")
	}
	klog.Infof("═══════════════════════════════════════════════════════════════")

	// Server 配置
	// ConfigServer 和 DataServer 从 common.ini 加载（如果 RunInOmniagent 为 true）
	// 但是，无论是否在 RunInOmniagent 模式下，只要配置文件中的 config_server 发生改变，就更新 ProxyClient
	if v.IsSet("server.config_server") {
		newConfigServer := v.GetString("server.config_server")
		oldConfigServer := *flags.ConfigServer
		klog.Infof("📝 [CONFIG] server.config_server: config_file=%s, current=%s, flags_empty=%v",
			newConfigServer, oldConfigServer, *flags.ConfigServer == "")

		// 参考备份代码：只有当 *flags.ConfigServer == "" 时才从配置文件更新
		if *flags.ConfigServer == "" && !*flags.RunInOmniagent {
			if newConfigServer != oldConfigServer {
				*flags.ConfigServer = newConfigServer
				klog.Infof("✅ [CONFIG] server.config_server UPDATED: %s -> %s", oldConfigServer, newConfigServer)
				// 更新 ProxyClient 的 endpoints
				updateProxyClientEndpoints(newConfigServer)
			} else {
				klog.Infof("⏭️  [CONFIG] server.config_server UNCHANGED: %s", newConfigServer)
			}
		} else if *flags.RunInOmniagent {
			// 在 RunInOmniagent 模式下，即使不更新 flags.ConfigServer（因为 common.ini 优先级更高），
			// 只要配置文件中的值改变了，也更新 ProxyClient
			if newConfigServer != oldConfigServer {
				klog.Infof("🔄 [CONFIG] server.config_server (RunInOmniagent mode): updating ProxyClient only: %s -> %s", oldConfigServer, newConfigServer)
				updateProxyClientEndpoints(newConfigServer)
			} else {
				klog.Infof("⏭️  [CONFIG] server.config_server (RunInOmniagent mode): no change, skipping")
			}
		}
	}
	if v.IsSet("server.data_server") {
		newDataServer := v.GetString("server.data_server")
		oldDataServer := *flags.DataServer
		klog.Infof("📝 [CONFIG] server.data_server: config_file=%s, current=%s, flags_empty=%v",
			newDataServer, oldDataServer, *flags.DataServer == "")

		// 参考备份代码：只有当 *flags.DataServer == "" 时才从配置文件更新
		if *flags.DataServer == "" && !*flags.RunInOmniagent {
			if newDataServer != oldDataServer {
				*flags.DataServer = newDataServer
				klog.Infof("✅ [CONFIG] server.data_server UPDATED: %s -> %s", oldDataServer, newDataServer)
			} else {
				klog.Infof("⏭️  [CONFIG] server.data_server UNCHANGED: %s", newDataServer)
			}
		} else {
			klog.Infof("⏭️  [CONFIG] server.data_server SKIPPED (set via command line or RunInOmniagent mode)")
		}
	}
	if v.IsSet("server.server_prefix") {
		newVal := v.GetString("server.server_prefix")
		oldVal := *flags.ServerPrefix
		if newVal != oldVal {
			*flags.ServerPrefix = newVal
			klog.Infof("✅ [CONFIG] server.server_prefix UPDATED: %s -> %s", oldVal, newVal)
		}
	}
	if v.IsSet("server.license_key") {
		*flags.LicenseKey = v.GetString("server.license_key")
	}

	// Agent 配置
	if v.IsSet("agent.disable_register_host") {
		newVal := v.GetBool("agent.disable_register_host")
		oldVal := *flags.DisableRegisterHost
		// 布尔值：检查环境变量，如果没有设置环境变量，则从配置文件更新
		envSet := os.Getenv("EUSPACE_AGENT_DISABLE_REGISTER_HOST") != "" || os.Getenv("DISABLE_REG_HOST") != ""
		if !envSet {
			if newVal != oldVal {
				*flags.DisableRegisterHost = newVal
				klog.Infof("✅ [CONFIG] agent.disable_register_host UPDATED: %v -> %v", oldVal, newVal)
			}
		} else {
			klog.Infof("⏭️  [CONFIG] agent.disable_register_host SKIPPED (set via env)")
		}
	}
	if v.IsSet("agent.enable_license_check") {
		*flags.EnableLicenseCheck = v.GetBool("agent.enable_license_check")
	}
	if v.IsSet("agent.send_net_data") {
		*flags.SendNetData = v.GetBool("agent.send_net_data")
	}

	// Logging 配置
	if v.IsSet("logging.log_level") {
		newLogLevel := v.GetString("logging.log_level")
		oldLogLevel := *flags.LogLevel
		klog.Infof("📝 [CONFIG] logging.log_level: config_file=%s, current=%s, flags_empty=%v",
			newLogLevel, oldLogLevel, *flags.LogLevel == "")

		// 参考备份代码：只有当 *flags.LogLevel == "" 时才从配置文件更新 flags
		if *flags.LogLevel == "" {
			if newLogLevel != oldLogLevel {
				*flags.LogLevel = newLogLevel
				klog.Infof("✅ [CONFIG] logging.log_level UPDATED (flags): %s -> %s", oldLogLevel, newLogLevel)
			}
		} else {
			klog.Infof("⏭️  [CONFIG] logging.log_level SKIPPED (set via command line: %s)", *flags.LogLevel)
		}

		// 使用统一的热更新机制：比较配置文件的新旧值，如果改变了就更新 logrus 级别
		// 这样即使 *flags.LogLevel 是通过命令行设置的，配置文件改变时也能更新 logrus
		checkAndUpdateConfigValue("logging.log_level", newLogLevel, isHotReload, func() {
			// 初始加载时，如果 flags.LogLevel 为空，也要设置 logrus 级别
			if !isHotReload && *flags.LogLevel == "" {
				updateLogLevel(newLogLevel)
			} else if isHotReload {
				// 热更新时，无论 flags 是否更新，都更新 logrus 级别
				updateLogLevel(newLogLevel)
			}
		})
	}
	if v.IsSet("logging.console_log") {
		*flags.ConsoleLog = v.GetBool("logging.console_log")
	}
}
