package config

import (
	"os"
	"strconv"
	"time"
)

// Config 全局配置
type Config struct {
	// 服务配置
	Server ServerConfig

	// 数据库配置
	Database DatabaseConfig

	// Redis配置
	Redis RedisConfig

	// JWT配置
	JWT JWTConfig

	// 安全配置
	Security SecurityConfig

	// OAuth配置
	OAuth OAuthConfig

	// OAuth提供商配置
	Providers OAuthProvidersConfig

	// 应用信息
	App AppConfig
}

type ServerConfig struct {
	Host string
	Port int
	Mode string // debug/release
}

type DatabaseConfig struct {
	Type            string // mysql/postgres/sqlite
	DSN             string
	MaxOpenConns    int
	MaxIdleConns    int
	ConnMaxLifetime time.Duration
}

type RedisConfig struct {
	Addr     string
	Password string
	DB       int
	Enabled  bool
}

type JWTConfig struct {
	Secret          string
	AccessExpiry    time.Duration
	RefreshExpiry   time.Duration
	Issuer          string
}

type SecurityConfig struct {
	BcryptCost      int
	MaxLoginAttempts int
	CaptchaEnabled  bool
}

type OAuthConfig struct {
	AuthorizationExpiry time.Duration
	AccessExpiry        time.Duration
	RefreshExpiry       time.Duration
}

// OAuthProviderConfig 第三方OAuth提供商配置
type OAuthProviderConfig struct {
	Enabled      bool
	ClientID     string
	ClientSecret string
	AuthURL      string
	TokenURL     string
	UserInfoURL  string
	Scopes       []string
}

// OAuthProvidersConfig 所有OAuth提供商配置
type OAuthProvidersConfig struct {
	Google  OAuthProviderConfig
	GitHub  OAuthProviderConfig
	WeChat  OAuthProviderConfig
	Weibo   OAuthProviderConfig
	Feishu  OAuthProviderConfig
	Lark    OAuthProviderConfig
}

type AppConfig struct {
	ID          string
	Name        string
	InitAdmin   InitAdminConfig
}

type InitAdminConfig struct {
	Username string
	Password string
	Email    string
}

var C *Config

func init() {
	C = &Config{
		Server: ServerConfig{
			Host: getEnv("SERVER_HOST", "0.0.0.0"),
			Port: getEnvInt("SERVER_PORT", 8080),
			Mode: getEnv("SERVER_MODE", "debug"),
		},
		Database: DatabaseConfig{
			Type:            getEnv("DB_TYPE", "mysql"),
			DSN:             getEnv("DB_DSN", "root:123456@tcp(127.0.0.1:3306)/vbase?charset=utf8mb4&parseTime=True&loc=Local"),
			MaxOpenConns:    getEnvInt("DB_MAX_OPEN", 100),
			MaxIdleConns:    getEnvInt("DB_MAX_IDLE", 10),
			ConnMaxLifetime: time.Hour,
		},
		Redis: RedisConfig{
			Enabled:  getEnvBool("REDIS_ENABLED", true),
			Addr:     getEnv("REDIS_ADDR", "localhost:6379"),
			Password: getEnv("REDIS_PASSWORD", ""),
			DB:       getEnvInt("REDIS_DB", 0),
		},
		JWT: JWTConfig{
			Secret:        getEnv("JWT_SECRET", "your-secret-key-change-in-production-min-32-characters"),
			AccessExpiry:  getEnvDuration("JWT_ACCESS_EXPIRY", time.Hour),
			RefreshExpiry: getEnvDuration("JWT_REFRESH_EXPIRY", 30*24*time.Hour),
			Issuer:        getEnv("JWT_ISSUER", "vbase"),
		},
		Security: SecurityConfig{
			BcryptCost:       getEnvInt("BCRYPT_COST", 12),
			MaxLoginAttempts: getEnvInt("MAX_LOGIN_ATTEMPTS", 5),
			CaptchaEnabled:   getEnvBool("CAPTCHA_ENABLED", true),
		},
		OAuth: OAuthConfig{
			AuthorizationExpiry: getEnvDuration("OAUTH_AUTH_EXPIRY", 10*time.Minute),
			AccessExpiry:        getEnvDuration("OAUTH_ACCESS_EXPIRY", time.Hour),
			RefreshExpiry:       getEnvDuration("OAUTH_REFRESH_EXPIRY", 30*24*time.Hour),
		},
		Providers: OAuthProvidersConfig{
			Google: OAuthProviderConfig{
				Enabled:      getEnvBool("OAUTH_GOOGLE_ENABLED", false),
				ClientID:     getEnv("OAUTH_GOOGLE_CLIENT_ID", ""),
				ClientSecret: getEnv("OAUTH_GOOGLE_CLIENT_SECRET", ""),
				AuthURL:      "https://accounts.google.com/o/oauth2/v2/auth",
				TokenURL:     "https://oauth2.googleapis.com/token",
				UserInfoURL:  "https://openidconnect.googleapis.com/v1/userinfo",
				Scopes:       []string{"openid", "email", "profile"},
			},
			GitHub: OAuthProviderConfig{
				Enabled:      getEnvBool("OAUTH_GITHUB_ENABLED", false),
				ClientID:     getEnv("OAUTH_GITHUB_CLIENT_ID", ""),
				ClientSecret: getEnv("OAUTH_GITHUB_CLIENT_SECRET", ""),
				AuthURL:      "https://github.com/login/oauth/authorize",
				TokenURL:     "https://github.com/login/oauth/access_token",
				UserInfoURL:  "https://api.github.com/user",
				Scopes:       []string{"user:email", "read:user"},
			},
			WeChat: OAuthProviderConfig{
				Enabled:      getEnvBool("OAUTH_WECHAT_ENABLED", false),
				ClientID:     getEnv("OAUTH_WECHAT_APP_ID", ""),
				ClientSecret: getEnv("OAUTH_WECHAT_APP_SECRET", ""),
				AuthURL:      "https://open.weixin.qq.com/connect/qrconnect",
				TokenURL:     "https://api.weixin.qq.com/sns/oauth2/access_token",
				UserInfoURL:  "https://api.weixin.qq.com/sns/userinfo",
				Scopes:       []string{"snsapi_login"},
			},
		},
		App: AppConfig{
			ID:   getEnv("APP_ID", "vbase"),
			Name: getEnv("APP_NAME", "VBase IAM"),
			InitAdmin: InitAdminConfig{
				Username: getEnv("INIT_ADMIN_USERNAME", "admin"),
				Password: getEnv("INIT_ADMIN_PASSWORD", ""), // 为空时随机生成
				Email:    getEnv("INIT_ADMIN_EMAIL", "admin@example.com"),
			},
		},
	}
}

func getEnv(key, defaultVal string) string {
	if v := os.Getenv(key); v != "" {
		return v
	}
	return defaultVal
}

func getEnvInt(key string, defaultVal int) int {
	if v := os.Getenv(key); v != "" {
		if i, err := strconv.Atoi(v); err == nil {
			return i
		}
	}
	return defaultVal
}

func getEnvBool(key string, defaultVal bool) bool {
	if v := os.Getenv(key); v != "" {
		if b, err := strconv.ParseBool(v); err == nil {
			return b
		}
	}
	return defaultVal
}

func getEnvDuration(key string, defaultVal time.Duration) time.Duration {
	if v := os.Getenv(key); v != "" {
		if d, err := time.ParseDuration(v); err == nil {
			return d
		}
	}
	return defaultVal
}
