// Package config 环境变量配置（密钥经部署注入，本地开发用 .env.local / docker compose）。
package config

import (
	"encoding/json"
	"log/slog"
	"os"
	"strconv"

	"dudu/server/pkg/protocol"
)

type Config struct {
	Addr        string // HTTP 监听地址
	PostgresDSN string
	RedisAddr   string
	RedisDB     int

	JWTSecret   string
	JWTTTLHours int

	// 微信开放平台 / 商户号（申请中可留空，相关模块降级为 mock）
	WechatWebAppID     string
	WechatWebSecret    string
	WechatMobileAppID  string
	WechatMobileSecret string
	WxPayMchID         string
	WxPayCertSerial    string
	WxPayPrivateKeyPEM string
	WxPayAPIv3Key      string
	WxPayNotifyURL     string

	// ASR
	ASRProvider     string // gummy | mock
	DashScopeAPIKey string

	// OSS（反馈图片）
	OSSEndpoint  string
	OSSBucket    string
	OSSKeyID     string
	OSSKeySecret string

	// SMTP（邮箱验证码登录；未配置降级 mock mailer）
	SMTPHost string
	// EmailDevCode 非空时邮箱验证码固定为该值（仅开发脚本设置，生产禁用）
	EmailDevCode string

	// AppLatest 启动时解析 APP_LATEST_JSON 一次（17G）：平台→版本信息。
	// 解析失败或未配置则为 nil/空，handler 据此返回 204，不 fail-fast。
	AppLatest map[string]protocol.AppLatestResponse
}

func Load() Config {
	return Config{
		Addr:        getenv("ADDR", ":8080"),
		PostgresDSN: getenv("POSTGRES_DSN", "host=localhost user=dudu password=dudu dbname=dudu port=5432 sslmode=disable TimeZone=Asia/Shanghai"),
		RedisAddr:   getenv("REDIS_ADDR", "localhost:6379"),
		RedisDB:     getint("REDIS_DB", 0),

		JWTSecret:   getenv("JWT_SECRET", "dev-secret-change-me"),
		JWTTTLHours: getint("JWT_TTL_HOURS", 24*7),

		WechatWebAppID:     os.Getenv("WECHAT_WEB_APPID"),
		WechatWebSecret:    os.Getenv("WECHAT_WEB_SECRET"),
		WechatMobileAppID:  os.Getenv("WECHAT_MOBILE_APPID"),
		WechatMobileSecret: os.Getenv("WECHAT_MOBILE_SECRET"),
		WxPayMchID:         os.Getenv("WXPAY_MCHID"),
		WxPayCertSerial:    os.Getenv("WXPAY_CERT_SERIAL"),
		WxPayPrivateKeyPEM: os.Getenv("WXPAY_PRIVATE_KEY_PEM"),
		WxPayAPIv3Key:      os.Getenv("WXPAY_APIV3_KEY"),
		WxPayNotifyURL:     os.Getenv("WXPAY_NOTIFY_URL"),

		ASRProvider:     getenv("ASR_PROVIDER", "mock"),
		DashScopeAPIKey: os.Getenv("DASHSCOPE_API_KEY"),

		OSSEndpoint:  os.Getenv("OSS_ENDPOINT"),
		OSSBucket:    os.Getenv("OSS_BUCKET"),
		SMTPHost:     os.Getenv("SMTP_HOST"),
		EmailDevCode: os.Getenv("AUTH_EMAIL_DEV_CODE"),
		OSSKeyID:     os.Getenv("OSS_KEY_ID"),
		OSSKeySecret: os.Getenv("OSS_KEY_SECRET"),

		AppLatest: loadAppLatest(),
	}
}

// loadAppLatest 启动时解析一次 APP_LATEST_JSON（17G）。失败仅告警并返回 nil，
// 不 fail-fast——未配置此项时服务仍需正常启动。
func loadAppLatest() map[string]protocol.AppLatestResponse {
	raw := os.Getenv("APP_LATEST_JSON")
	if raw == "" {
		return nil
	}
	var all map[string]protocol.AppLatestResponse
	if err := json.Unmarshal([]byte(raw), &all); err != nil {
		slog.Warn("invalid APP_LATEST_JSON, app update disabled", "err", err)
		return nil
	}
	return all
}

func getenv(k, def string) string {
	if v := os.Getenv(k); v != "" {
		return v
	}
	return def
}

func getint(k string, def int) int {
	if v := os.Getenv(k); v != "" {
		if n, err := strconv.Atoi(v); err == nil {
			return n
		}
	}
	return def
}
