package controller

import (
	"net/http"
	"os"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/songquanpeng/one-api/common"
	"github.com/songquanpeng/one-api/common/config"
)

type ServerConfigItem struct {
	Key             string `json:"key"`
	Value           string `json:"value"`
	DefaultValue    string `json:"default_value"`
	RestartRequired bool   `json:"restart_required"`
	Description     string `json:"description"`
	Category        string `json:"category"`
}

func GetServerConfigs(c *gin.Context) {
	configs := collectServerConfigs()
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
		"data":    configs,
	})
}

func collectServerConfigs() []ServerConfigItem {
	// Determine database type
	dbType := "SQLite"
	if common.UsingMySQL {
		dbType = "MySQL"
	} else if common.UsingPostgreSQL {
		dbType = "PostgreSQL"
	}

	items := []ServerConfigItem{
		// ===== Database =====
		{Key: "db_type", Value: dbType, DefaultValue: "SQLite", RestartRequired: true, Description: "当前数据库类型（自动检测）", Category: "database"},
		{Key: "SQL_DSN", Value: maskSecret(os.Getenv("SQL_DSN")), DefaultValue: "", RestartRequired: true, Description: "数据库连接字符串（留空=SQLite）", Category: "database"},
		{Key: "LOG_SQL_DSN", Value: maskSecret(os.Getenv("LOG_SQL_DSN")), DefaultValue: "", RestartRequired: true, Description: "日志数据库连接字符串（留空=使用主库）", Category: "database"},
		{Key: "SQLITE_PATH", Value: os.Getenv("SQLITE_PATH"), DefaultValue: "one-api.db", RestartRequired: true, Description: "SQLite 数据库文件路径", Category: "database"},
		{Key: "SQLITE_BUSY_TIMEOUT", Value: strconv.Itoa(common.SQLiteBusyTimeout), DefaultValue: "3000", RestartRequired: true, Description: "SQLite 忙等待超时（毫秒）", Category: "database"},
		{Key: "SQL_MAX_IDLE_CONNS", Value: "", DefaultValue: "100", RestartRequired: true, Description: "数据库最大空闲连接数", Category: "database"},
		{Key: "SQL_MAX_OPEN_CONNS", Value: "", DefaultValue: "1000", RestartRequired: true, Description: "数据库最大打开连接数", Category: "database"},
		{Key: "SQL_MAX_LIFETIME", Value: "", DefaultValue: "60", RestartRequired: true, Description: "数据库连接最长存活时间（秒）", Category: "database"},

		// ===== Redis =====
		{Key: "REDIS_CONN_STRING", Value: maskSecret(os.Getenv("REDIS_CONN_STRING")), DefaultValue: "", RestartRequired: true, Description: "Redis 连接字符串（留空=不启用）", Category: "redis"},
		{Key: "REDIS_PASSWORD", Value: maskSecret(os.Getenv("REDIS_PASSWORD")), DefaultValue: "", RestartRequired: true, Description: "Redis 密码", Category: "redis"},
		{Key: "REDIS_MASTER_NAME", Value: os.Getenv("REDIS_MASTER_NAME"), DefaultValue: "", RestartRequired: true, Description: "Redis 主节点名称（集群模式）", Category: "redis"},
		{Key: "SYNC_FREQUENCY", Value: strconv.Itoa(config.SyncFrequency), DefaultValue: "600", RestartRequired: true, Description: "缓存同步频率（秒）", Category: "redis"},

		// ===== Performance =====
		{Key: "DEBUG", Value: strconv.FormatBool(config.DebugEnabled), DefaultValue: "false", RestartRequired: false, Description: "启用调试模式", Category: "performance"},
		{Key: "DEBUG_SQL", Value: strconv.FormatBool(config.DebugSQLEnabled), DefaultValue: "false", RestartRequired: false, Description: "启用 SQL 调试日志", Category: "performance"},
		{Key: "MEMORY_CACHE_ENABLED", Value: strconv.FormatBool(config.MemoryCacheEnabled), DefaultValue: "false", RestartRequired: false, Description: "启用内存缓存", Category: "performance"},
		{Key: "BATCH_UPDATE_ENABLED", Value: strconv.FormatBool(config.BatchUpdateEnabled), DefaultValue: "false", RestartRequired: false, Description: "启用批量更新", Category: "performance"},
		{Key: "BATCH_UPDATE_INTERVAL", Value: strconv.Itoa(config.BatchUpdateInterval), DefaultValue: "5", RestartRequired: false, Description: "批量更新间隔（秒）", Category: "performance"},
		{Key: "GIN_MODE", Value: os.Getenv("GIN_MODE"), DefaultValue: "release", RestartRequired: true, Description: "Gin 运行模式（debug/release/test）", Category: "performance"},

		// ===== Network =====
		{Key: "RELAY_TIMEOUT", Value: strconv.Itoa(config.RelayTimeout), DefaultValue: "0", RestartRequired: false, Description: "中转超时时间（秒，0=不超时）", Category: "network"},
		{Key: "RELAY_PROXY", Value: config.RelayProxy, DefaultValue: "", RestartRequired: false, Description: "中转代理地址", Category: "network"},
		{Key: "USER_CONTENT_REQUEST_PROXY", Value: config.UserContentRequestProxy, DefaultValue: "", RestartRequired: false, Description: "用户内容请求代理地址", Category: "network"},
		{Key: "USER_CONTENT_REQUEST_TIMEOUT", Value: strconv.Itoa(config.UserContentRequestTimeout), DefaultValue: "30", RestartRequired: false, Description: "用户内容请求超时（秒）", Category: "network"},
		{Key: "HTTPS_PROXY", Value: maskSecret(os.Getenv("HTTPS_PROXY")), DefaultValue: "", RestartRequired: false, Description: "HTTPS 代理地址", Category: "network"},

		// ===== Rate Limit =====
		{Key: "GLOBAL_API_RATE_LIMIT", Value: strconv.Itoa(config.GlobalApiRateLimitNum), DefaultValue: "480", RestartRequired: false, Description: "全局 API 速率限制（次/3分钟）", Category: "ratelimit"},
		{Key: "GLOBAL_WEB_RATE_LIMIT", Value: strconv.Itoa(config.GlobalWebRateLimitNum), DefaultValue: "240", RestartRequired: false, Description: "全局 Web 速率限制（次/3分钟）", Category: "ratelimit"},

		// ===== Metrics =====
		{Key: "ENABLE_METRIC", Value: strconv.FormatBool(config.EnableMetric), DefaultValue: "false", RestartRequired: false, Description: "启用指标监控", Category: "metrics"},
		{Key: "METRIC_QUEUE_SIZE", Value: strconv.Itoa(config.MetricQueueSize), DefaultValue: "10", RestartRequired: false, Description: "指标队列大小", Category: "metrics"},
		{Key: "METRIC_SUCCESS_RATE_THRESHOLD", Value: strconv.FormatFloat(config.MetricSuccessRateThreshold, 'f', 2, 64), DefaultValue: "0.8", RestartRequired: false, Description: "成功率阈值", Category: "metrics"},
		{Key: "CHANNEL_TEST_FREQUENCY", Value: os.Getenv("CHANNEL_TEST_FREQUENCY"), DefaultValue: "", RestartRequired: true, Description: "渠道自动测试频率（秒，留空=不自动测试）", Category: "metrics"},

		// ===== Other =====
		{Key: "PORT", Value: strconv.Itoa(*common.Port), DefaultValue: "3000", RestartRequired: true, Description: "服务监听端口", Category: "other"},
		{Key: "SESSION_SECRET", Value: maskSecret(config.SessionSecret), DefaultValue: "自动生成 UUID", RestartRequired: true, Description: "Session 密钥", Category: "other"},
		{Key: "NODE_TYPE", Value: os.Getenv("NODE_TYPE"), DefaultValue: "master", RestartRequired: true, Description: "节点类型（master/slave）", Category: "other"},
		{Key: "POLLING_INTERVAL", Value: os.Getenv("POLLING_INTERVAL"), DefaultValue: "", RestartRequired: true, Description: "从节点轮询间隔（秒）", Category: "other"},
		{Key: "GEMINI_SAFETY_SETTING", Value: config.GeminiSafetySetting, DefaultValue: "BLOCK_NONE", RestartRequired: false, Description: "Gemini 安全设置", Category: "other"},
		{Key: "GEMINI_VERSION", Value: config.GeminiVersion, DefaultValue: "v1", RestartRequired: false, Description: "Gemini API 版本", Category: "other"},
		{Key: "THEME", Value: config.Theme, DefaultValue: "default", RestartRequired: false, Description: "前端主题名称", Category: "other"},
		{Key: "FRONTEND_BASE_URL", Value: os.Getenv("FRONTEND_BASE_URL"), DefaultValue: "", RestartRequired: true, Description: "前端基础 URL（从节点使用）", Category: "other"},
		{Key: "ONLY_ONE_LOG_FILE", Value: strconv.FormatBool(config.OnlyOneLogFile), DefaultValue: "false", RestartRequired: false, Description: "仅使用一个日志文件", Category: "other"},
		{Key: "ENFORCE_INCLUDE_USAGE", Value: strconv.FormatBool(config.EnforceIncludeUsage), DefaultValue: "false", RestartRequired: false, Description: "强制返回 usage 信息", Category: "other"},
		{Key: "TEST_PROMPT", Value: config.TestPrompt, DefaultValue: "Output only your specific model name with no additional text.", RestartRequired: false, Description: "渠道测试提示词", Category: "other"},
	}

	// Fill in SQL_MAX_* values from env
	if v := os.Getenv("SQL_MAX_IDLE_CONNS"); v != "" {
		items[7].Value = v
	}
	if v := os.Getenv("SQL_MAX_OPEN_CONNS"); v != "" {
		items[8].Value = v
	}
	if v := os.Getenv("SQL_MAX_LIFETIME"); v != "" {
		items[9].Value = v
	}

	return items
}

func UpdateServerConfig(c *gin.Context) {
	var req struct {
		Key   string `json:"key"`
		Value string `json:"value"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "无效的参数",
		})
		return
	}

	// Check if this is a restart-required setting
	restartRequiredKeys := map[string]bool{
		"SQL_DSN": true, "LOG_SQL_DSN": true, "SQLITE_PATH": true,
		"SQLITE_BUSY_TIMEOUT": true, "SQL_MAX_IDLE_CONNS": true,
		"SQL_MAX_OPEN_CONNS": true, "SQL_MAX_LIFETIME": true,
		"REDIS_CONN_STRING": true, "REDIS_PASSWORD": true,
		"REDIS_MASTER_NAME": true, "SYNC_FREQUENCY": true,
		"PORT": true, "SESSION_SECRET": true, "NODE_TYPE": true,
		"POLLING_INTERVAL": true, "GIN_MODE": true,
		"FRONTEND_BASE_URL": true, "CHANNEL_TEST_FREQUENCY": true,
		"INITIAL_ROOT_TOKEN": true, "INITIAL_ROOT_ACCESS_TOKEN": true,
	}

	if restartRequiredKeys[req.Key] {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": "该设置需要重启服务才能生效，请使用下载 .env 文件功能修改后重启，或直接在 .env 文件中修改。",
		})
		return
	}

	// Update runtime settings
	err := updateRuntimeConfig(req.Key, req.Value)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "设置已更新",
	})
}

func updateRuntimeConfig(key, value string) error {
	switch key {
	case "DEBUG":
		config.DebugEnabled = value == "true"
	case "DEBUG_SQL":
		config.DebugSQLEnabled = value == "true"
	case "MEMORY_CACHE_ENABLED":
		config.MemoryCacheEnabled = value == "true"
	case "BATCH_UPDATE_ENABLED":
		config.BatchUpdateEnabled = value == "true"
	case "BATCH_UPDATE_INTERVAL":
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		config.BatchUpdateInterval = v
	case "RELAY_TIMEOUT":
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		config.RelayTimeout = v
	case "RELAY_PROXY":
		config.RelayProxy = value
	case "USER_CONTENT_REQUEST_PROXY":
		config.UserContentRequestProxy = value
	case "USER_CONTENT_REQUEST_TIMEOUT":
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		config.UserContentRequestTimeout = v
	case "HTTPS_PROXY":
		os.Setenv("HTTPS_PROXY", value)
	case "GEMINI_SAFETY_SETTING":
		config.GeminiSafetySetting = value
	case "GEMINI_VERSION":
		config.GeminiVersion = value
	case "THEME":
		if !config.ValidThemes[value] {
			return nil // silently ignore invalid themes
		}
		config.Theme = value
	case "GLOBAL_API_RATE_LIMIT":
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		config.GlobalApiRateLimitNum = v
	case "GLOBAL_WEB_RATE_LIMIT":
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		config.GlobalWebRateLimitNum = v
	case "ENABLE_METRIC":
		config.EnableMetric = value == "true"
	case "METRIC_QUEUE_SIZE":
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		config.MetricQueueSize = v
	case "METRIC_SUCCESS_RATE_THRESHOLD":
		v, err := strconv.ParseFloat(value, 64)
		if err != nil {
			return err
		}
		config.MetricSuccessRateThreshold = v
	case "ONLY_ONE_LOG_FILE":
		config.OnlyOneLogFile = value == "true"
	case "ENFORCE_INCLUDE_USAGE":
		config.EnforceIncludeUsage = value == "true"
	case "TEST_PROMPT":
		config.TestPrompt = value
	default:
		return nil // unknown key, ignore silently
	}
	return nil
}

func maskSecret(s string) string {
	if s == "" {
		return ""
	}
	if len(s) <= 4 {
		return "****"
	}
	return s[:2] + "****" + s[len(s)-2:]
}