package config

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"os"
	"path/filepath"

	"github.com/google/uuid"
	"github.com/spf13/viper"
)

// Config 全局配置结构
type Config struct {
	App        AppConfig        `mapstructure:"app"`
	Server     ServerConfig     `mapstructure:"server"`
	Database   DatabaseConfig   `mapstructure:"database"`
	JWT        JWTConfig        `mapstructure:"jwt"`
	Log        LogConfig        `mapstructure:"log"`
	Encryption EncryptionConfig `mapstructure:"encryption"`
	WireGuard  WireGuardConfig  `mapstructure:"wireguard"`
	STUN       STUNConfig       `mapstructure:"stun"`
	TURN       TURNConfig       `mapstructure:"turn"`
}

// AppConfig 应用配置
type AppConfig struct {
	Version   string `mapstructure:"version"`    // 版本号
	BuildDate string `mapstructure:"build_date"` // 构建日期
}

// ServerConfig 服务器配置
type ServerConfig struct {
	Port       int    `mapstructure:"port"`
	Mode       string `mapstructure:"mode"`        // debug, release, test
	StaticPath string `mapstructure:"static_path"` // 前端静态文件目录
}

// DatabaseConfig 数据库配置
type DatabaseConfig struct {
	Type string `mapstructure:"type"`
	Path string `mapstructure:"path"`
}

// JWTConfig JWT 配置
type JWTConfig struct {
	Secret          string `mapstructure:"secret"`
	AccessTokenDur  string `mapstructure:"access_token_duration"`
	RefreshTokenDur string `mapstructure:"refresh_token_duration"`
}

// LogConfig 日志配置
type LogConfig struct {
	Level      string `mapstructure:"level"`
	Format     string `mapstructure:"format"`
	Output     string `mapstructure:"output"`
	MaxSize    int    `mapstructure:"max_size"`
	MaxBackups int    `mapstructure:"max_backups"`
	MaxAge     int    `mapstructure:"max_age"`
}

// EncryptionConfig 加密配置
type EncryptionConfig struct {
	NetworkSecretKey string `mapstructure:"network_secret_key"`
}

// WireGuardConfig WireGuard 配置（固定使用用户态）
type WireGuardConfig struct {
	// 已删除 PreferredMode 字段 - 统一使用 wireguard-go 用户态
}

// STUNConfig STUN 配置
type STUNConfig struct {
	DefaultServers    []string `mapstructure:"default_servers"`    // 默认 STUN 服务器列表
	SelectionStrategy string   `mapstructure:"selection_strategy"` // 选择策略：auto, domestic, international, custom
	AutoTest          bool     `mapstructure:"auto_test"`          // 是否启用自动测试
	TestInterval      int      `mapstructure:"test_interval"`      // 测试间隔（秒）
	Timeout           int      `mapstructure:"timeout"`            // 超时时间（秒）
}

// TURNConfig TURN 配置
type TURNConfig struct {
	DefaultServers []TURNServerConfig `mapstructure:"default_servers"` // 默认 TURN 服务器列表
}

// TURNServerConfig TURN 服务器配置
type TURNServerConfig struct {
	URL        string `mapstructure:"url"`        // TURN 服务器 URL
	Username   string `mapstructure:"username"`   // 用户名
	Credential string `mapstructure:"credential"` // 凭证
	AuthType   string `mapstructure:"auth_type"`  // 鉴权方式：credential, token, secret
}

// Load 加载配置文件
func Load(configPath string) (*Config, error) {
	// 如果未指定配置文件路径，使用默认路径
	if configPath == "" {
		configPath = "config.yaml"
	}

	// 检查配置文件是否存在
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		// 尝试从示例文件复制
		examplePath := "configs/config.example.yaml"
		if _, err := os.Stat(examplePath); err == nil {
			// 创建目录
			dir := filepath.Dir(configPath)
			if dir != "." {
				os.MkdirAll(dir, 0755)
			}
			// 复制示例配置
			data, _ := os.ReadFile(examplePath)
			os.WriteFile(configPath, data, 0644)
		}
	}

	// 读取配置文件
	viper.SetConfigFile(configPath)
	viper.AutomaticEnv()

	if err := viper.ReadInConfig(); err != nil {
		return nil, fmt.Errorf("读取配置文件失败：%w", err)
	}

	var config Config
	if err := viper.Unmarshal(&config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败：%w", err)
	}

	// 自动填充默认值
	if config.Server.Port == 0 {
		config.Server.Port = 9531
	}
	if config.Server.Mode == "" {
		config.Server.Mode = "release"
	}

	// 自动生成 JWT Secret
	if config.JWT.Secret == "" {
		config.JWT.Secret = generateJWTSecret()
	}

	// 自动生成加密密钥
	if config.Encryption.NetworkSecretKey == "" {
		config.Encryption.NetworkSecretKey = generateEncryptionKey()
	}

	return &config, nil
}

// generateJWTSecret 使用 crypto/rand 生成随机 JWT Secret
func generateJWTSecret() string {
	b := make([]byte, 32)
	_, err := rand.Read(b)
	if err != nil {
		// 极端情况回退（几乎不会发生）
		return uuid.New().String()
	}
	return hex.EncodeToString(b)
}

// generateEncryptionKey 使用 crypto/rand 生成加密密钥
func generateEncryptionKey() string {
	key := make([]byte, 32)
	_, err := rand.Read(key)
	if err != nil {
		// 极端情况回退（几乎不会发生）
		return uuid.New().String() + uuid.New().String()
	}
	return hex.EncodeToString(key)
}
