package httpclient

import (
	"net"
	"net/http"
	"sync"
	"time"
)

// 全局单例变量
var (
	once         sync.Once    // 保证初始化只执行一次
	globalClient *http.Client // 复用的 HTTP Client 实例
)

// InitHttpClient 初始化全局 HTTP Client（手动调用，可选）
// 配置连接池参数，优化连接复用
func InitHttpClient() {
	once.Do(func() {
		// 核心：配置 Transport（连接池核心参数）
		transport := &http.Transport{
			// 全局最大空闲连接数（避免连接数过多）
			MaxIdleConns: 100,
			// 空闲连接超时时间（超时后关闭，释放资源）
			IdleConnTimeout: 30 * time.Second,
			// 每个目标主机的最大空闲连接数（避免单主机占用过多连接）
			MaxIdleConnsPerHost: 10,
			MaxConnsPerHost:     20, // 新增：每个目标主机的最大并发连接数（防止打满服务器）
			// 禁用压缩（根据业务需求调整，比如调用微信接口可开启）
			DisableCompression: false,
			// TCP 连接建立超时（防止连接挂死）
			DialContext: (&net.Dialer{
				Timeout:   10 * time.Second, // 连接建立超时
				KeepAlive: 30 * time.Second, // TCP 保活时间（维持长连接）
			}).DialContext,
			// TLS 握手超时（HTTPS 场景必配）
			TLSHandshakeTimeout: 5 * time.Second,
			/// 等待响应头的超时
			ResponseHeaderTimeout: 15 * time.Second,
		}

		// 构建 HTTP Client
		globalClient = &http.Client{
			Timeout:   20 * time.Second, // 整个请求的超时（连接+读取+写入）
			Transport: transport,
			// 可选：禁用自动重定向（根据业务需求，比如微信接口无需重定向）
			// CheckRedirect: func(req *http.Request, via []*http.Request) error {
			// 	return http.ErrUseLastResponse
			// },
		}
	})
}

// GetClient 获取全局 HTTP Client 实例（推荐使用此方法调用）
// 懒加载：如果未初始化，自动触发初始化
func GetClient() *http.Client {
	InitHttpClient() // 兜底：确保初始化
	return globalClient
}
