package config

import (
	"fmt"
	"strings"

	"github.com/spf13/viper"
)

const envPrefix = "JUNHONG"

func Load() (*Config, error) {
	v := viper.New()

	embeddedReader, err := getEmbeddedConfig()
	if err != nil {
		return nil, fmt.Errorf("读取嵌入配置失败: %w", err)
	}

	v.SetConfigType("yaml")
	if err := v.ReadConfig(embeddedReader); err != nil {
		return nil, fmt.Errorf("解析嵌入配置失败: %w", err)
	}

	v.SetEnvPrefix(envPrefix)
	v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	v.AutomaticEnv()

	bindEnvVariables(v)

	cfg := &Config{}
	if err := v.Unmarshal(cfg); err != nil {
		return nil, fmt.Errorf("反序列化配置失败: %w", err)
	}

	if err := cfg.ValidateRequired(); err != nil {
		return nil, err
	}

	if err := cfg.Validate(); err != nil {
		return nil, err
	}

	globalConfig.Store(cfg)

	return cfg, nil
}

func bindEnvVariables(v *viper.Viper) {
	bindings := []string{
		"server.address",
		"server.read_timeout",
		"server.write_timeout",
		"server.shutdown_timeout",
		"server.prefork",
		"database.host",
		"database.port",
		"database.user",
		"database.password",
		"database.dbname",
		"database.sslmode",
		"database.max_open_conns",
		"database.max_idle_conns",
		"database.conn_max_lifetime",
		"redis.address",
		"redis.port",
		"redis.password",
		"redis.db",
		"redis.pool_size",
		"redis.min_idle_conns",
		"redis.dial_timeout",
		"redis.read_timeout",
		"redis.write_timeout",
		"storage.provider",
		"storage.temp_dir",
		"storage.s3.endpoint",
		"storage.s3.region",
		"storage.s3.bucket",
		"storage.s3.access_key_id",
		"storage.s3.secret_access_key",
		"storage.s3.use_ssl",
		"storage.s3.path_style",
		"storage.presign.upload_expires",
		"storage.presign.download_expires",
		"logging.level",
		"logging.development",
		"logging.app_log.filename",
		"logging.app_log.max_size",
		"logging.app_log.max_backups",
		"logging.app_log.max_age",
		"logging.app_log.compress",
		"logging.access_log.filename",
		"logging.access_log.max_size",
		"logging.access_log.max_backups",
		"logging.access_log.max_age",
		"logging.access_log.compress",
		"queue.concurrency",
		"queue.retry_max",
		"queue.timeout",
		"jwt.secret_key",
		"jwt.token_duration",
		"jwt.access_token_ttl",
		"jwt.refresh_token_ttl",
		"client.require_phone_binding",
		"middleware.enable_rate_limiter",
		"middleware.rate_limiter.max",
		"middleware.rate_limiter.expiration",
		"middleware.rate_limiter.storage",
		"middleware.cors.enabled",
		"middleware.cors.allow_origins",
		"middleware.cors.allow_methods",
		"middleware.cors.allow_headers",
		"middleware.cors.expose_headers",
		"middleware.cors.allow_credentials",
		"middleware.cors.max_age",
		"sms.gateway_url",
		"sms.username",
		"sms.password",
		"sms.signature",
		"sms.timeout",
		"default_admin.username",
		"default_admin.password",
		"default_admin.phone",
		"gateway.base_url",
		"gateway.app_id",
		"gateway.app_secret",
		"gateway.timeout",
		"polling.verbose_log",
		"polling_auto_trigger.enable_auto_trigger",
		"polling_auto_trigger.auto_trigger_system_user_id",
		"worker.role",
		"worker.instance_name",
		"approval.legacy_refund_manual_enabled",
		"approval.legacy_offline_recharge_pay_enabled",
		"wecom.base_url",
		"wecom.timeout",
		"wecom.credential_encryption_key",
		"wechat.official_account.app_id",
		"wechat.official_account.app_secret",
		"wechat.official_account.token",
		"wechat.official_account.aes_key",
		"wechat.official_account.oauth_redirect_url",
		"wechat.payment.app_id",
		"wechat.payment.mch_id",
		"wechat.payment.api_v3_key",
		"wechat.payment.api_v2_key",
		"wechat.payment.cert_path",
		"wechat.payment.key_path",
		"wechat.payment.serial_no",
		"wechat.payment.notify_url",
		"wechat.payment.http_debug",
		"wechat.payment.timeout",
	}

	for _, key := range bindings {
		_ = v.BindEnv(key)
	}
}
