package config

import (
	"fmt"
	"path/filepath"

	"github.com/joho/godotenv"
	"github.com/spf13/viper"
)

// Config 应用配置。
type Config struct {
	App       AppConfig       `mapstructure:"app"`
	Server    ServerConfig    `mapstructure:"server"`
	Session   SessionConfig   `mapstructure:"session"`
	Redis     RedisConfig     `mapstructure:"redis"`
	AI        AIConfig        `mapstructure:"ai"`
	Storage   StorageConfig   `mapstructure:"storage"`
	Log       LogConfig       `mapstructure:"log"`
	Auth      AuthConfig      `mapstructure:"auth"`
	RateLimit RateLimitConfig `mapstructure:"ratelimit"`
}

// SessionConfig 会话管理配置。
type SessionConfig struct {
	TTL        int `mapstructure:"ttl"`         // 会话过期时间（分钟）
	MaxHistory int `mapstructure:"max_history"`  // 对话历史上限（条）
}

type AppConfig struct {
	Env     string `mapstructure:"env"`
	Version string `mapstructure:"version"`
}

type ServerConfig struct {
	Host              string   `mapstructure:"host"`
	Port              int      `mapstructure:"port"`
	ReadTimeout       int      `mapstructure:"read_timeout"`
	WriteTimeout      int      `mapstructure:"write_timeout"`
	HeartbeatInterval int      `mapstructure:"heartbeat_interval"` // 心跳检查间隔（秒）
	HeartbeatTimeout  int      `mapstructure:"heartbeat_timeout"`  // 心跳超时（秒）
	ShutdownTimeout   int      `mapstructure:"shutdown_timeout"`   // 优雅关闭超时（秒）
	AllowedOrigins    []string `mapstructure:"allowed_origins"`    // CORS 允许的来源，空表示允许所有
}

// Addr 返回 host:port 地址。
func (s ServerConfig) Addr() string {
	return fmt.Sprintf("%s:%d", s.Host, s.Port)
}

type RedisConfig struct {
	Addr     string `mapstructure:"addr"`
	Password string `mapstructure:"password"`
	DB       int    `mapstructure:"db"`
}

type AIConfig struct {
	STT STTConfig `mapstructure:"stt"`
	LLM LLMConfig `mapstructure:"llm"`
	TTS TTSConfig `mapstructure:"tts"`
}

type STTConfig struct {
	Provider          string `mapstructure:"provider"`
	APIKey            string `mapstructure:"api_key"`
	Model             string `mapstructure:"model"`
	Endpoint          string `mapstructure:"endpoint"`
	Timeout           int    `mapstructure:"timeout"`             // STT 超时（秒）
	HTTPClientTimeout int    `mapstructure:"http_client_timeout"` // HTTP 客户端超时（秒）
}

type LLMConfig struct {
	Provider          string `mapstructure:"provider"`
	APIKey            string `mapstructure:"api_key"`
	Model             string `mapstructure:"model"`
	Endpoint          string `mapstructure:"endpoint"`
	Timeout           int    `mapstructure:"timeout"`
	HTTPClientTimeout int    `mapstructure:"http_client_timeout"` // HTTP 客户端超时（秒）
}

type TTSConfig struct {
	Provider          string  `mapstructure:"provider"`
	APIKey            string  `mapstructure:"api_key"`
	Model             string  `mapstructure:"model"`
	Voice             string  `mapstructure:"voice"`
	Speed             float64 `mapstructure:"speed"`
	Endpoint          string  `mapstructure:"endpoint"`
	Timeout           int     `mapstructure:"timeout"`
	HTTPClientTimeout int     `mapstructure:"http_client_timeout"` // HTTP 客户端超时（秒）
	OutputFormat      string  `mapstructure:"output_format"`       // 输出格式：mp3/wav
	SampleRate        int     `mapstructure:"sample_rate"`         // 输出采样率
}

type StorageConfig struct {
	Redis       RedisStorageConfig `mapstructure:"redis"`
	Persistence PersistenceConfig  `mapstructure:"persistence"`
	// Deprecated: 使用 Redis 和 Persistence 替代
	Driver string `mapstructure:"driver"`
	DSN    string `mapstructure:"dsn"`
}

type RedisStorageConfig struct {
	Enabled bool `mapstructure:"enabled"`
}

type PersistenceConfig struct {
	Enabled bool   `mapstructure:"enabled"`
	Driver  string `mapstructure:"driver"`
	DSN     string `mapstructure:"dsn"`
}

type LogConfig struct {
	Level  string `mapstructure:"level"`
	Format string `mapstructure:"format"`
}

// AuthConfig 认证配置。
type AuthConfig struct {
	JWTSecret  string `mapstructure:"jwt_secret"`  // JWT 签名密钥，必须通过环境变量 CAMTALK_AUTH_JWT_SECRET 设置
	AccessTTL  int    `mapstructure:"access_ttl"`   // Access Token 过期时间（分钟），默认 15
	RefreshTTL int    `mapstructure:"refresh_ttl"`  // Refresh Token 过期时间（分钟），默认 10080（7天）
}

// RateLimitConfig 限流配置。
type RateLimitConfig struct {
	Enabled  bool         `mapstructure:"enabled"`
	Query    BucketConfig `mapstructure:"query"`
	Login    BucketConfig `mapstructure:"login"`
	Register BucketConfig `mapstructure:"register"`
}

// BucketConfig 令牌桶配置。
type BucketConfig struct {
	Capacity int     `mapstructure:"capacity"` // 桶容量（突发上限）
	Rate     float64 `mapstructure:"rate"`     // 每秒填充令牌数
}

// Load 加载配置。优先级：环境变量 > config.{env}.yaml > config.yaml > 默认值。
// workDir 为项目根目录或 backend 目录，用于定位 .env 和 config/config.yaml。
func Load(workDir string) (*Config, error) {
	// 1. 加载 .env 文件（敏感信息）
	envFile := filepath.Join(workDir, ".env")
	_ = godotenv.Load(envFile) // 文件不存在也不报错

	v := viper.New()
	v.SetConfigName("config")
	v.SetConfigType("yaml")
	v.AddConfigPath(filepath.Join(workDir, "config")) // 配置文件在 config/ 目录下
	v.AddConfigPath(workDir)                          // 兼容旧路径

	// 2. 设置默认值（与 config.yaml 保持一致，仅作为兜底）
	setDefaults(v)

	// 3. 读取 config.yaml
	if err := v.ReadInConfig(); err != nil {
		return nil, fmt.Errorf("config: read config.yaml: %w", err)
	}

	// 4. 合并环境专属配置 config.{env}.yaml（可选）
	env := v.GetString("app.env")
	if env != "" {
		v.SetConfigName("config." + env)
		_ = v.MergeInConfig() // 文件不存在也不报错
	}

	// 5. 显式绑定敏感信息环境变量（不用 AutomaticEnv，避免隐式映射）
	bindEnvVars(v)

	var cfg Config
	if err := v.Unmarshal(&cfg); err != nil {
		return nil, fmt.Errorf("config: unmarshal: %w", err)
	}

	return &cfg, nil
}

// setDefaults 设置兜底默认值，与 config.yaml 保持一致。
func setDefaults(v *viper.Viper) {
	// app
	v.SetDefault("app.env", "dev")
	v.SetDefault("app.version", "dev")

	// server
	v.SetDefault("server.host", "0.0.0.0")
	v.SetDefault("server.port", 8080)
	v.SetDefault("server.read_timeout", 30)
	v.SetDefault("server.write_timeout", 30)
	v.SetDefault("server.shutdown_timeout", 10)
	v.SetDefault("server.heartbeat_interval", 30)
	v.SetDefault("server.heartbeat_timeout", 60)

	// session
	v.SetDefault("session.ttl", 30)
	v.SetDefault("session.max_history", 20)

	// ai — 默认值与 config.yaml 一致（mimo/dashscope）
	v.SetDefault("ai.stt.provider", "mimo")
	v.SetDefault("ai.stt.model", "mimo-v2.5-asr")
	v.SetDefault("ai.stt.endpoint", "https://api.xiaomimimo.com/v1")
	v.SetDefault("ai.stt.timeout", 5)
	v.SetDefault("ai.stt.http_client_timeout", 30)

	v.SetDefault("ai.llm.provider", "dashscope")
	v.SetDefault("ai.llm.model", "qwen3-vl-plus")
	v.SetDefault("ai.llm.endpoint", "https://dashscope.aliyuncs.com/compatible-mode/v1")
	v.SetDefault("ai.llm.timeout", 30)
	v.SetDefault("ai.llm.http_client_timeout", 60)

	v.SetDefault("ai.tts.provider", "mimo")
	v.SetDefault("ai.tts.model", "mimo-v2.5-tts")
	v.SetDefault("ai.tts.voice", "mimo_default")
	v.SetDefault("ai.tts.speed", 1.0)
	v.SetDefault("ai.tts.endpoint", "https://token-plan-cn.xiaomimimo.com/v1")
	v.SetDefault("ai.tts.timeout", 5)
	v.SetDefault("ai.tts.http_client_timeout", 30)
	v.SetDefault("ai.tts.output_format", "mp3")
	v.SetDefault("ai.tts.sample_rate", 24000)

	// storage
	v.SetDefault("storage.driver", "memory")
	v.SetDefault("storage.redis.enabled", false)
	v.SetDefault("storage.persistence.enabled", false)
	v.SetDefault("storage.persistence.driver", "postgres")

	// redis
	v.SetDefault("redis.addr", "localhost:6379")
	v.SetDefault("redis.password", "")
	v.SetDefault("redis.db", 0)

	// auth
	v.SetDefault("auth.access_ttl", 15)
	v.SetDefault("auth.refresh_ttl", 10080)

	// log
	v.SetDefault("log.level", "info")
	v.SetDefault("log.format", "console")

	// ratelimit
	v.SetDefault("ratelimit.enabled", false)
	v.SetDefault("ratelimit.query.capacity", 10)
	v.SetDefault("ratelimit.query.rate", 0.2)
	v.SetDefault("ratelimit.login.capacity", 5)
	v.SetDefault("ratelimit.login.rate", 0.1)
	v.SetDefault("ratelimit.register.capacity", 3)
	v.SetDefault("ratelimit.register.rate", 0.05)
}

// bindEnvVars 显式绑定敏感信息环境变量。
// 只绑定不应出现在 config.yaml 中的敏感字段，非敏感配置通过 config.yaml 管理。
func bindEnvVars(v *viper.Viper) {
	// app.env 特殊处理：环境变量 APP_ENV 覆盖 config.yaml 中的 app.env
	v.BindEnv("app.env", "APP_ENV")

	// AI API Key
	v.BindEnv("ai.stt.api_key", "CAMTALK_AI_STT_API_KEY")
	v.BindEnv("ai.llm.api_key", "CAMTALK_AI_LLM_API_KEY")
	v.BindEnv("ai.tts.api_key", "CAMTALK_AI_TTS_API_KEY")

	// JWT
	v.BindEnv("auth.jwt_secret", "CAMTALK_AUTH_JWT_SECRET")

	// 数据库
	v.BindEnv("storage.dsn", "CAMTALK_STORAGE_DSN")
	v.BindEnv("storage.persistence.dsn", "CAMTALK_STORAGE_DSN")
	v.BindEnv("storage.redis.enabled", "CAMTALK_STORAGE_REDIS_ENABLED")
	v.BindEnv("storage.persistence.enabled", "CAMTALK_STORAGE_PERSISTENCE_ENABLED")
	v.BindEnv("storage.persistence.driver", "CAMTALK_STORAGE_PERSISTENCE_DRIVER")

	// Redis（密码可能包含特殊字符，通过环境变量设置更安全）
	v.BindEnv("redis.addr", "CAMTALK_REDIS_ADDR")
	v.BindEnv("redis.password", "CAMTALK_REDIS_PASSWORD")
}
