package delay

import (
	"errors"
	"fmt"
	"time"
)

// ProgressiveDelay 用于管理渐进式延迟策略
type ProgressiveDelay struct {
	initialDelay     time.Duration // 初始延迟时间
	growthFactor     float64       // 延迟增长因子 (例如 1.5)
	maxDelay         time.Duration // 最大延迟时间
	maxRetryDuration time.Duration // 最大重试时间
	currentDelay     time.Duration // 当前延迟时间
	startTime        time.Time     // 重试开始时间
}

// New 创建一个新的渐进式延迟对象
func New(initialDelay, maxDelay, maxRetryDuration time.Duration, growthFactor float64) (*ProgressiveDelay, error) {
	// 参数校验
	if initialDelay <= 0 {
		return nil, errors.New("initialDelay must be greater than zero")
	}
	if maxDelay <= 0 {
		return nil, errors.New("maxDelay must be greater than zero")
	}
	if maxRetryDuration <= 0 {
		return nil, errors.New("maxRetryDuration must be greater than zero")
	}
	if growthFactor <= 1.0 {
		return nil, errors.New("growthFactor must be greater than 1")
	}

	// 初始化并返回
	return &ProgressiveDelay{
		initialDelay:     initialDelay,
		maxDelay:         maxDelay,
		maxRetryDuration: maxRetryDuration,
		growthFactor:     growthFactor,
		currentDelay:     initialDelay,
		startTime:        time.Now(),
	}, nil
}

// NextDelay 计算并返回下次的延迟时间
func (pd *ProgressiveDelay) NextDelay() (time.Duration, error) {
	// 检查最大重试时间是否已过
	if time.Since(pd.startTime) > pd.maxRetryDuration {
		return 0, fmt.Errorf("最大重试时间超过限制: %v", pd.maxRetryDuration)
	}

	// 返回当前延迟时间
	delay := pd.currentDelay

	// 计算下一个延迟时间并更新 currentDelay
	pd.currentDelay = time.Duration(float64(pd.currentDelay) * pd.growthFactor)

	// 如果下次延迟超过最大延迟时间，限制在最大值
	if pd.currentDelay > pd.maxDelay {
		pd.currentDelay = pd.maxDelay
	}

	return delay, nil
}
