package configs

import (
	"bytes"
	_ "embed"
	"io"
	"os"

	"bindbox-game/internal/pkg/env"

	"github.com/spf13/viper"
)

var config = new(Config)

type Config struct {
	MySQL struct {
		Read struct {
			Addr string `mapstructure:"addr" toml:"addr"`
			User string `mapstructure:"user" toml:"user"`
			Pass string `mapstructure:"pass" toml:"pass"`
			Name string `mapstructure:"name" toml:"name"`
		} `mapstructure:"read" toml:"read"`
		Write struct {
			Addr string `mapstructure:"addr" toml:"addr"`
			User string `mapstructure:"user" toml:"user"`
			Pass string `mapstructure:"pass" toml:"pass"`
			Name string `mapstructure:"name" toml:"name"`
		} `mapstructure:"write" toml:"write"`
	} `mapstructure:"mysql" toml:"mysql"`

	Redis struct {
		Addr string `mapstructure:"addr" toml:"addr"`
		Pass string `mapstructure:"pass" toml:"pass"`
		DB   int    `mapstructure:"db" toml:"db"`
	} `mapstructure:"redis" toml:"redis"`

	JWT struct {
		AdminSecret   string `mapstructure:"admin_secret" toml:"admin_secret"`
		PatientSecret string `mapstructure:"patient_secret" toml:"patient_secret"`
		DoctorSecret  string `mapstructure:"doctor_secret" toml:"doctor_secret"`
	} `mapstructure:"jwt" toml:"jwt"`

	Language struct {
		Local string `mapstructure:"local" toml:"local"`
	} `mapstructure:"language" toml:"language"`

	Wechat struct {
		AppID                   string `mapstructure:"app_id" toml:"app_id"`
		AppSecret               string `mapstructure:"app_secret" toml:"app_secret"`
		LotteryResultTemplateID string `mapstructure:"lottery_result_template_id" toml:"lottery_result_template_id"`
	} `mapstructure:"wechat" toml:"wechat"`

	WechatPay struct {
		MchID          string `mapstructure:"mchid" toml:"mchid"`
		SerialNo       string `mapstructure:"serial_no" toml:"serial_no"`
		PrivateKeyPath string `mapstructure:"private_key_path" toml:"private_key_path"`
		ApiV3Key       string `mapstructure:"api_v3_key" toml:"api_v3_key"`
		NotifyURL      string `mapstructure:"notify_url" toml:"notify_url"`
		PublicKeyID    string `mapstructure:"public_key_id" toml:"public_key_id"`
		PublicKeyPath  string `mapstructure:"public_key_path" toml:"public_key_path"`
	} `mapstructure:"wechatpay" toml:"wechatpay"`

	COS struct {
		Bucket    string `mapstructure:"bucket" toml:"bucket"`
		Region    string `mapstructure:"region" toml:"region"`
		SecretID  string `mapstructure:"secret_id" toml:"secret_id"`
		SecretKey string `mapstructure:"secret_key" toml:"secret_key"`
		BaseURL   string `mapstructure:"base_url" toml:"base_url"`
	} `mapstructure:"cos" toml:"cos"`

	Random struct {
		CommitMasterKey string `mapstructure:"commit_master_key" toml:"commit_master_key"`
	} `mapstructure:"random" toml:"random"`

	AliyunSMS struct {
		AccessKeyID     string `mapstructure:"access_key_id" toml:"access_key_id"`
		AccessKeySecret string `mapstructure:"access_key_secret" toml:"access_key_secret"`
		SignName        string `mapstructure:"sign_name" toml:"sign_name"`
		TemplateCode    string `mapstructure:"template_code" toml:"template_code"`
	} `mapstructure:"aliyun_sms" toml:"aliyun_sms"`

	Internal struct {
		ApiKey string `mapstructure:"api_key" toml:"api_key"`
	} `mapstructure:"internal" toml:"internal"`

	Douyin struct {
		AppID     string `mapstructure:"app_id" toml:"app_id"`
		AppSecret string `mapstructure:"app_secret" toml:"app_secret"`
		NotifyURL string `mapstructure:"notify_url" toml:"notify_url"`
	} `mapstructure:"douyin" toml:"douyin"`

	Otel struct {
		Enabled  bool   `mapstructure:"enabled" toml:"enabled"`
		Endpoint string `mapstructure:"endpoint" toml:"endpoint"`
	} `mapstructure:"otel" toml:"otel"`
}

var (
	//go:embed dev_configs.toml
	devConfigs []byte

	//go:embed fat_configs.toml
	fatConfigs []byte

	//go:embed uat_configs.toml
	uatConfigs []byte

	//go:embed pro_configs.toml
	proConfigs []byte
)

func Init() {
	var r io.Reader

	switch env.Active().Value() {
	case "dev":
		r = bytes.NewReader(devConfigs)
	case "fat":
		r = bytes.NewReader(fatConfigs)
	case "uat":
		r = bytes.NewReader(uatConfigs)
	case "pro":
		r = bytes.NewReader(proConfigs)
	default:
		r = bytes.NewReader(fatConfigs)
	}

	viper.SetConfigType("toml")

	if err := viper.ReadConfig(r); err != nil {
		panic(err)
	}

	if err := viper.Unmarshal(config); err != nil {
		panic(err)
	}

	if v := os.Getenv("WECHAT_MCHID"); v != "" {
		config.WechatPay.MchID = v
	}
	if v := os.Getenv("WECHAT_SERIAL_NO"); v != "" {
		config.WechatPay.SerialNo = v
	}
	if v := os.Getenv("WECHAT_PRIVATE_KEY_PATH"); v != "" {
		config.WechatPay.PrivateKeyPath = v
	}
	if v := os.Getenv("WECHAT_API_V3_KEY"); v != "" {
		config.WechatPay.ApiV3Key = v
	}
	if v := os.Getenv("WECHAT_NOTIFY_URL"); v != "" {
		config.WechatPay.NotifyURL = v
	}
	if v := os.Getenv("WECHAT_PUBLIC_KEY_ID"); v != "" {
		config.WechatPay.PublicKeyID = v
	}
	if v := os.Getenv("WECHAT_PUBLIC_KEY_PATH"); v != "" {
		config.WechatPay.PublicKeyPath = v
	}

	// 阿里云短信配置环境变量覆盖
	if v := os.Getenv("ALIYUN_SMS_ACCESS_KEY_ID"); v != "" {
		config.AliyunSMS.AccessKeyID = v
	}
	if v := os.Getenv("ALIYUN_SMS_ACCESS_KEY_SECRET"); v != "" {
		config.AliyunSMS.AccessKeySecret = v
	}
	if v := os.Getenv("ALIYUN_SMS_SIGN_NAME"); v != "" {
		config.AliyunSMS.SignName = v
	}
	if v := os.Getenv("ALIYUN_SMS_TEMPLATE_CODE"); v != "" {
		config.AliyunSMS.TemplateCode = v
	}

	// MySQL 配置环境变量覆盖
	if v := os.Getenv("MYSQL_ADDR"); v != "" {
		config.MySQL.Read.Addr = v
		config.MySQL.Write.Addr = v
	}
	if v := os.Getenv("MYSQL_READ_ADDR"); v != "" {
		config.MySQL.Read.Addr = v
	}
	if v := os.Getenv("MYSQL_WRITE_ADDR"); v != "" {
		config.MySQL.Write.Addr = v
	}
	if v := os.Getenv("MYSQL_USER"); v != "" {
		config.MySQL.Read.User = v
		config.MySQL.Write.User = v
	}
	if v := os.Getenv("MYSQL_PASS"); v != "" {
		config.MySQL.Read.Pass = v
		config.MySQL.Write.Pass = v
	}
	if v := os.Getenv("MYSQL_NAME"); v != "" {
		config.MySQL.Read.Name = v
		config.MySQL.Write.Name = v
	}

	// Redis 配置环境变量覆盖
	if v := os.Getenv("REDIS_ADDR"); v != "" {
		config.Redis.Addr = v
	}
	if v := os.Getenv("REDIS_PASS"); v != "" {
		config.Redis.Pass = v
	}
}

func Get() Config {
	return *config
}
