package config

import (
	"fmt"
	"log"
	"os"

	"github.com/spf13/viper"
)

type Config struct {
	Server    ServerConfig    `mapstructure:"server"`
	Database  DatabaseConfig  `mapstructure:"database"`
	JWT       JWTConfig       `mapstructure:"jwt"`
	Wechat    WechatConfig    `mapstructure:"wechat"`
	XHS       XHSConfig       `mapstructure:"xhs"`
	Scheduler SchedulerConfig `mapstructure:"scheduler"`
}

type ServerConfig struct {
	Port int    `mapstructure:"port"`
	Mode string `mapstructure:"mode"`
}

type DatabaseConfig struct {
	Host            string `mapstructure:"host"`
	Port            int    `mapstructure:"port"`
	Username        string `mapstructure:"username"`
	Password        string `mapstructure:"password"`
	DBName          string `mapstructure:"dbname"`
	Charset         string `mapstructure:"charset"`
	ParseTime       bool   `mapstructure:"parse_time"`
	Loc             string `mapstructure:"loc"`
	MaxIdleConns    int    `mapstructure:"max_idle_conns"`
	MaxOpenConns    int    `mapstructure:"max_open_conns"`
	ConnMaxLifetime int    `mapstructure:"conn_max_lifetime"`
}

type JWTConfig struct {
	Secret      string `mapstructure:"secret"`
	ExpireHours int    `mapstructure:"expire_hours"`
}

type WechatConfig struct {
	AppID     string `mapstructure:"app_id"`
	AppSecret string `mapstructure:"app_secret"`
}

type XHSConfig struct {
	PythonServiceURL string `mapstructure:"python_service_url"`
}

type SchedulerConfig struct {
	Enabled                  bool   `mapstructure:"enabled"`                       // 是否启用定时任务
	PublishCron              string `mapstructure:"publish_cron"`                  // 发布任务的Cron表达式
	MaxConcurrent            int    `mapstructure:"max_concurrent"`                // 最大并发发布数
	PublishTimeout           int    `mapstructure:"publish_timeout"`               // 发布超时时间（秒）
	MaxArticlesPerUserPerRun int    `mapstructure:"max_articles_per_user_per_run"` // 每轮每个用户最大发文数
	MaxFailuresPerUserPerRun int    `mapstructure:"max_failures_per_user_per_run"` // 每轮每个用户最大失败次数
	MaxDailyArticlesPerUser  int    `mapstructure:"max_daily_articles_per_user"`   // 每个用户每日最大发文数
	MaxHourlyArticlesPerUser int    `mapstructure:"max_hourly_articles_per_user"`  // 每个用户每小时最大发文数
	Proxy                    string `mapstructure:"proxy"`                         // 全局代理地址（可选）
	UserAgent                string `mapstructure:"user_agent"`                    // 全局User-Agent（可选）
	ProxyFetchURL            string `mapstructure:"proxy_fetch_url"`               // 动态获取代理的接口地址（可选）
}

var AppConfig *Config

// LoadConfig 加载配置文件
// 优先级: 环境变量 > 配置文件
func LoadConfig(env string) error {
	// 1. 优先从环境变量 APP_ENV 获取环境配置
	if envFromEnv := os.Getenv("APP_ENV"); envFromEnv != "" {
		env = envFromEnv
		log.Printf("从环境变量 APP_ENV 读取环境: %s", env)
	}

	if env == "" {
		env = "dev"
	}

	// 2. 加载配置文件
	viper.SetConfigName(fmt.Sprintf("config.%s", env))
	viper.SetConfigType("yaml")
	viper.AddConfigPath("./config")
	viper.AddConfigPath("../config")

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

	// 3. 绑定环境变量(自动读取环境变量覆盖配置)
	viper.AutomaticEnv()

	// 绑定特定的环境变量到配置项
	bindEnvVariables()

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

	log.Printf("配置加载成功: %s 环境", env)
	log.Printf("数据库配置: %s@%s:%d/%s", AppConfig.Database.Username, AppConfig.Database.Host, AppConfig.Database.Port, AppConfig.Database.DBName)
	return nil
}

// bindEnvVariables 绑定环境变量到配置项
func bindEnvVariables() {
	// Server 配置
	viper.BindEnv("server.port", "SERVER_PORT")
	viper.BindEnv("server.mode", "SERVER_MODE")

	// Database 配置
	viper.BindEnv("database.host", "DB_HOST")
	viper.BindEnv("database.port", "DB_PORT")
	viper.BindEnv("database.username", "DB_USERNAME")
	viper.BindEnv("database.password", "DB_PASSWORD")
	viper.BindEnv("database.dbname", "DB_NAME")
	viper.BindEnv("database.charset", "DB_CHARSET")

	// JWT 配置
	viper.BindEnv("jwt.secret", "JWT_SECRET")
	viper.BindEnv("jwt.expire_hours", "JWT_EXPIRE_HOURS")

	// Wechat 配置
	viper.BindEnv("wechat.app_id", "WECHAT_APP_ID")
	viper.BindEnv("wechat.app_secret", "WECHAT_APP_SECRET")

	// XHS 配置
	viper.BindEnv("xhs.python_service_url", "XHS_PYTHON_SERVICE_URL")

	// Scheduler 配置
	viper.BindEnv("scheduler.enabled", "SCHEDULER_ENABLED")
	viper.BindEnv("scheduler.publish_cron", "SCHEDULER_PUBLISH_CRON")
	viper.BindEnv("scheduler.max_concurrent", "SCHEDULER_MAX_CONCURRENT")
	viper.BindEnv("scheduler.publish_timeout", "SCHEDULER_PUBLISH_TIMEOUT")
	viper.BindEnv("scheduler.max_articles_per_user_per_run", "SCHEDULER_MAX_ARTICLES_PER_USER_PER_RUN")
	viper.BindEnv("scheduler.max_failures_per_user_per_run", "SCHEDULER_MAX_FAILURES_PER_USER_PER_RUN")
	viper.BindEnv("scheduler.max_daily_articles_per_user", "SCHEDULER_MAX_DAILY_ARTICLES_PER_USER")
	viper.BindEnv("scheduler.max_hourly_articles_per_user", "SCHEDULER_MAX_HOURLY_ARTICLES_PER_USER")
	viper.BindEnv("scheduler.proxy", "SCHEDULER_PROXY")
	viper.BindEnv("scheduler.user_agent", "SCHEDULER_USER_AGENT")
	viper.BindEnv("scheduler.proxy_fetch_url", "SCHEDULER_PROXY_FETCH_URL")
}

// GetDSN 获取数据库连接字符串
func (c *DatabaseConfig) GetDSN() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=%t&loc=%s",
		c.Username,
		c.Password,
		c.Host,
		c.Port,
		c.DBName,
		c.Charset,
		c.ParseTime,
		c.Loc,
	)
}
