package auth

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"gopkg.in/yaml.v3"
)

// OAuthConfigYAML OAuth配置结构 (从YAML文件加载)
type OAuthConfigYAML struct {
	Common   CommonConfig        `yaml:"common"`
	WeChat   WeChatOAuthConfig   `yaml:"wechat"`
	Google   GoogleOAuthConfig   `yaml:"google"`
	Facebook FacebookOAuthConfig `yaml:"facebook"`
	QQ       QQOAuthConfig       `yaml:"qq"`
	Weibo    WeiboOAuthConfig    `yaml:"weibo"`
	Twitter  TwitterOAuthConfig  `yaml:"twitter"`
}

// CommonConfig 通用配置
type CommonConfig struct {
	RedirectBaseURL string `yaml:"redirect_base_url"`
	CallbackPath    string `yaml:"callback_path"`
}

// WeChatOAuthConfig 微信OAuth配置
type WeChatOAuthConfig struct {
	Enabled     bool              `yaml:"enabled"`
	AppID       string            `yaml:"app_id"`
	AppSecret   string            `yaml:"app_secret"`
	Scopes      []string          `yaml:"scopes"`
	AuthURL     string            `yaml:"auth_url"`
	TokenURL    string            `yaml:"token_url"`
	UserInfoURL string            `yaml:"user_info_url"`
	MiniProgram MiniProgramConfig `yaml:"mini_program"`
}

// MiniProgramConfig 小程序配置
type MiniProgramConfig struct {
	Enabled   bool   `yaml:"enabled"`
	AppID     string `yaml:"app_id"`
	AppSecret string `yaml:"app_secret"`
}

// GoogleOAuthConfig Google OAuth配置
type GoogleOAuthConfig struct {
	Enabled      bool     `yaml:"enabled"`
	ClientID     string   `yaml:"client_id"`
	ClientSecret string   `yaml:"client_secret"`
	Scopes       []string `yaml:"scopes"`
	AuthURL      string   `yaml:"auth_url"`
	TokenURL     string   `yaml:"token_url"`
	UserInfoURL  string   `yaml:"user_info_url"`
	JWTAuthURL   string   `yaml:"jwt_auth_url"`
}

// FacebookOAuthConfig Facebook OAuth配置
type FacebookOAuthConfig struct {
	Enabled     bool     `yaml:"enabled"`
	AppID       string   `yaml:"app_id"`
	AppSecret   string   `yaml:"app_secret"`
	Scopes      []string `yaml:"scopes"`
	AuthURL     string   `yaml:"auth_url"`
	TokenURL    string   `yaml:"token_url"`
	UserInfoURL string   `yaml:"user_info_url"`
}

// QQOAuthConfig QQ OAuth配置
type QQOAuthConfig struct {
	Enabled     bool     `yaml:"enabled"`
	AppID       string   `yaml:"app_id"`
	AppKey      string   `yaml:"app_key"`
	AppSecret   string   `yaml:"app_secret"`
	RedirectURI string   `yaml:"redirect_uri"`
	Scopes      []string `yaml:"scopes"`
	AuthURL     string   `yaml:"auth_url"`
	TokenURL    string   `yaml:"token_url"`
	OpenIDURL   string   `yaml:"openid_url"`
	UserInfoURL string   `yaml:"user_info_url"`
}

// WeiboOAuthConfig 微博OAuth配置
type WeiboOAuthConfig struct {
	Enabled     bool     `yaml:"enabled"`
	AppKey      string   `yaml:"app_key"`
	AppSecret   string   `yaml:"app_secret"`
	RedirectURI string   `yaml:"redirect_uri"`
	Scopes      []string `yaml:"scopes"`
	AuthURL     string   `yaml:"auth_url"`
	TokenURL    string   `yaml:"token_url"`
	UserInfoURL string   `yaml:"user_info_url"`
}

// TwitterOAuthConfig Twitter OAuth配置
type TwitterOAuthConfig struct {
	Enabled      bool     `yaml:"enabled"`
	ClientID     string   `yaml:"client_id"`
	ClientSecret string   `yaml:"client_secret"`
	Scopes       []string `yaml:"scopes"`
	AuthURL      string   `yaml:"auth_url"`
	TokenURL     string   `yaml:"token_url"`
	UserInfoURL  string   `yaml:"user_info_url"`
}

var (
	oauthConfig     *OAuthConfigYAML
	oauthConfigOnce sync.Once
)

// LoadOAuthConfig 加载OAuth配置
func LoadOAuthConfig(configPath string) (*OAuthConfigYAML, error) {
	var err error
	oauthConfigOnce.Do(func() {
		// 如果未指定配置文件，尝试默认路径
		if configPath == "" {
			configPath = filepath.Join("configs", "oauth_config.yaml")
		}

		// 如果配置文件不存在，尝试从环境变量加载
		if _, statErr := os.Stat(configPath); os.IsNotExist(statErr) {
			oauthConfig = loadFromEnv()
			return
		}

		// 从文件加载配置
		data, readErr := os.ReadFile(configPath)
		if readErr != nil {
			oauthConfig = loadFromEnv()
			err = fmt.Errorf("failed to read oauth config file: %w", readErr)
			return
		}

		oauthConfig = &OAuthConfigYAML{}
		if unmarshalErr := yaml.Unmarshal(data, oauthConfig); unmarshalErr != nil {
			oauthConfig = loadFromEnv()
			err = fmt.Errorf("failed to parse oauth config file: %w", unmarshalErr)
			return
		}
	})

	return oauthConfig, err
}

// loadFromEnv 从环境变量加载配置
func loadFromEnv() *OAuthConfigYAML {
	return &OAuthConfigYAML{
		Common: CommonConfig{
			RedirectBaseURL: getEnv("OAUTH_REDIRECT_BASE_URL", "http://localhost:8080"),
			CallbackPath:    getEnv("OAUTH_CALLBACK_PATH", "/api/v1/auth/oauth/callback"),
		},
		WeChat: WeChatOAuthConfig{
			Enabled:     getEnvBool("WECHAT_OAUTH_ENABLED", false),
			AppID:       getEnv("WECHAT_APP_ID", ""),
			AppSecret:   getEnv("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",
		},
		Google: GoogleOAuthConfig{
			Enabled:      getEnvBool("GOOGLE_OAUTH_ENABLED", false),
			ClientID:     getEnv("GOOGLE_CLIENT_ID", ""),
			ClientSecret: getEnv("GOOGLE_CLIENT_SECRET", ""),
			AuthURL:      "https://accounts.google.com/o/oauth2/v2/auth",
			TokenURL:     "https://oauth2.googleapis.com/token",
			UserInfoURL:  "https://www.googleapis.com/oauth2/v2/userinfo",
			JWTAuthURL:   "https://oauth2.googleapis.com/tokeninfo",
		},
		Facebook: FacebookOAuthConfig{
			Enabled:     getEnvBool("FACEBOOK_OAUTH_ENABLED", false),
			AppID:       getEnv("FACEBOOK_APP_ID", ""),
			AppSecret:   getEnv("FACEBOOK_APP_SECRET", ""),
			AuthURL:     "https://www.facebook.com/v18.0/dialog/oauth",
			TokenURL:    "https://graph.facebook.com/v18.0/oauth/access_token",
			UserInfoURL: "https://graph.facebook.com/v18.0/me?fields=id,name,email,picture",
		},
		QQ: QQOAuthConfig{
			Enabled:     getEnvBool("QQ_OAUTH_ENABLED", false),
			AppID:       getEnv("QQ_APP_ID", ""),
			AppKey:      getEnv("QQ_APP_KEY", ""),
			AppSecret:   getEnv("QQ_APP_SECRET", ""),
			RedirectURI: getEnv("QQ_REDIRECT_URI", ""),
			AuthURL:     "https://graph.qq.com/oauth2.0/authorize",
			TokenURL:    "https://graph.qq.com/oauth2.0/token",
			OpenIDURL:   "https://graph.qq.com/oauth2.0/me",
			UserInfoURL: "https://graph.qq.com/user/get_user_info",
		},
		Weibo: WeiboOAuthConfig{
			Enabled:     getEnvBool("WEIBO_OAUTH_ENABLED", false),
			AppKey:      getEnv("WEIBO_APP_KEY", ""),
			AppSecret:   getEnv("WEIBO_APP_SECRET", ""),
			RedirectURI: getEnv("WEIBO_REDIRECT_URI", ""),
			AuthURL:     "https://api.weibo.com/oauth2/authorize",
			TokenURL:    "https://api.weibo.com/oauth2/access_token",
			UserInfoURL: "https://api.weibo.com/2/users/show.json",
		},
		Twitter: TwitterOAuthConfig{
			Enabled:      getEnvBool("TWITTER_OAUTH_ENABLED", false),
			ClientID:     getEnv("TWITTER_CLIENT_ID", ""),
			ClientSecret: getEnv("TWITTER_CLIENT_SECRET", ""),
			AuthURL:      "https://twitter.com/i/oauth2/authorize",
			TokenURL:     "https://api.twitter.com/2/oauth2/token",
			UserInfoURL:  "https://api.twitter.com/2/users/me",
		},
	}
}

// GetOAuthConfig 获取OAuth配置
func GetOAuthConfig() *OAuthConfigYAML {
	if oauthConfig == nil {
		_, _ = LoadOAuthConfig("")
	}
	return oauthConfig
}

// getEnv 获取环境变量
func getEnv(key, defaultValue string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return defaultValue
}

// getEnvBool 获取布尔型环境变量
func getEnvBool(key string, defaultValue bool) bool {
	if value := os.Getenv(key); value != "" {
		return strings.ToLower(value) == "true" || value == "1"
	}
	return defaultValue
}
