// Filename: internal/settings/manager.go
package settings

import (
	"encoding/json"
	"fmt"
	"gemini-balancer/internal/models"
	"gemini-balancer/internal/pkg/reflectutil"
	"reflect"
	"time"
)

// ========= 便利的读取器 (Convenience Accessors) =========
func (sm *SettingsManager) IsIPBanEnabled() bool {
	return sm.GetSettings().EnableIPBanning
}

func (sm *SettingsManager) GetMaxLoginAttempts() int {
	return sm.GetSettings().MaxLoginAttempts
}

func (sm *SettingsManager) GetIPBanDuration() time.Duration {
	minutes := sm.GetSettings().IPBanDurationMinutes
	return time.Duration(minutes) * time.Minute
}

// GetSettingsCopy 返回当前系统设置的一个值副本，确保线程安全。
func (sm *SettingsManager) GetSettingsCopy() models.SystemSettings {
	// 从 syncer 获取当前的设置指针
	currentSettingsPtr := sm.GetSettings()
	if currentSettingsPtr == nil {
		// 在 syncer 初始化完成前，返回一个安全的默认值
		return *defaultSystemSettings()
	}
	// 返回指针指向的值，Go会自动创建一个副本
	return *currentSettingsPtr
}

// ========= 辅助与调试函数 (Helpers & Debugging) =========
// [ DisplaySettings 现在接收一个参数，以便在加载后立即打印
func (sm *SettingsManager) DisplaySettings(settings *models.SystemSettings) {
	if settings == nil {
		sm.logger.Warn("Cannot display settings, current settings object is nil.")
		return
	}
	sm.logger.Info("")
	sm.logger.Info("========= Runtime System Settings (from SettingsManager) =========")
	sm.logger.Infof("  - Request Timeout: %d seconds", settings.RequestTimeoutSeconds)
	sm.logger.Infof("  - Connect Timeout: %d seconds", settings.ConnectTimeoutSeconds)
	sm.logger.Infof("  - Max Retries: %d", settings.MaxRetries)
	sm.logger.Infof("  - Blacklist Threshold: %d", settings.BlacklistThreshold)
	sm.logger.Info("==================================================================")
	sm.logger.Info("")
}

// defaultSystemSettings
func defaultSystemSettings() *models.SystemSettings {
	settings := &models.SystemSettings{}
	settings.CustomHeaders = make(map[string]string)

	v := reflect.ValueOf(settings).Elem()
	t := v.Type()
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fieldValue := v.Field(i)
		// 我们只对“简单组织”动刀
		kind := fieldValue.Kind()
		if kind == reflect.Int || kind == reflect.Int64 || kind == reflect.String || kind == reflect.Bool {
			defaultValue := field.Tag.Get("default")
			if defaultValue != "" {
				if err := reflectutil.SetFieldFromString(fieldValue, defaultValue); err != nil {
					panic(fmt.Sprintf("FATAL: Invalid default tag for primitive field %s ('%s'): %v", field.Name, defaultValue, err))
				}
			}
		}
	}
	return settings
}

// parseAndSetField “扫描”数据库字符串，并将其“开箱”到正确的Go类型中
func parseAndSetField(fieldValue reflect.Value, dbValue string) error {
	if !fieldValue.CanSet() {
		return fmt.Errorf("field is not settable")
	}
	// 如果数据库值为空，我们不进行任何操作，以保留defaultSystemSettings设置的默认值
	if dbValue == "" {
		return nil
	}
	kind := fieldValue.Kind()
	switch kind {
	case reflect.Slice, reflect.Map:
		// 如果是 slice 或 map，我们就用“开箱器 (json.Unmarshal)”
		// fieldValue.Addr().Interface() 获取到的是指向该字段的指针，正是Unmarshal所需要的
		return json.Unmarshal([]byte(dbValue), fieldValue.Addr().Interface())
	default:
		// 对于所有原始类型，我们信任并复用现有的 reflectutil 工具
		return reflectutil.SetFieldFromString(fieldValue, dbValue)
	}
}

// Stop 优雅地停止SettingsManager的后台syncer。
func (sm *SettingsManager) Stop() {
	if sm.syncer != nil {
		sm.logger.Info("Stopping SettingsManager's syncer...")
		sm.syncer.Stop()
	}
}
