package client

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"time"
)

type HttpClient struct {
	*http.Client
	maxRetries     int
	retryDelayFunc RetryDelayFunc
}

// NewClient 构造函数,其中 delayFunc 参数是可选的
func NewClient(timeout time.Duration, maxRetries int, delayFunc ...RetryDelayFunc) *HttpClient {
	var df RetryDelayFunc
	if len(delayFunc) > 0 {
		df = delayFunc[0]
	} else {
		df = defaultRetryDelayFunc
	}
	return &HttpClient{
		Client:         &http.Client{Timeout: timeout},
		maxRetries:     maxRetries,
		retryDelayFunc: df,
	}
}

func DefaultClient() *HttpClient {
	return NewClient(time.Second*10, 3)
}
func defaultRetryDelayFunc(attempt int) time.Duration {
	delay := time.Duration(attempt) * time.Second
	if attempt > 0 {
		delay *= 2
	}
	return delay
}

type RetryDelayFunc func(attempt int) time.Duration

// DoWithRetry 发送带有重试机制的HTTP请求,允许用户自定义重试延迟逻辑
func (hc *HttpClient) DoWithRetry(ctx context.Context, req *http.Request) (*http.Response, error) {
	attempt := 0
	for {
		resp, err := hc.Do(req.WithContext(ctx))
		if err != nil {
			if attempt >= hc.maxRetries {
				return nil, fmt.Errorf("请求失败: %w", err)
			}
			attempt++
			delay := hc.retryDelayFunc(attempt)
			time.Sleep(delay)
			continue
		}
		return resp, nil
	}
}

func (hc *HttpClient) Post(url string, contentType string, buf io.Reader) (resp *http.Response, err error) {
	return
}

func (hc *HttpClient) Get(url string) (resp *http.Response, err error) {
	req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil)
	if err != nil {
		log.Fatalf("创建请求失败: %v", err)
	}
	resp, err = hc.DoWithRetry(req.Context(), req)
	return
}