package healthcheck

import (
	"fmt"
	"net/http"
	"time"

	"git.pyer.club/kingecg/gologger"
)

// HealthChecker 健康检查器
type HealthChecker struct {
	client   *http.Client
	interval time.Duration
	timeout  time.Duration
	retries  int
}

func NewHealthChecker(interval time.Duration, timeout time.Duration, retries int) *HealthChecker {
	return &HealthChecker{
		client: &http.Client{
			Timeout: timeout,
		},
		interval: interval,
		timeout:  timeout,
		retries:  retries,
	}
}

// CheckHealth 检查上游服务器健康状态
func (hc *HealthChecker) CheckHealth(url string) bool {
	logger := gologger.GetLogger("healthcheck")
	for i := 0; i < hc.retries; i++ {
		resp, err := hc.client.Get(url + "/health")
		if err == nil && resp.StatusCode == http.StatusOK {
			return true
		}
		logger.Warn(fmt.Sprintf("Health check failed for %s: %v", url, err))
		time.Sleep(hc.timeout)
	}
	logger.Error(fmt.Sprintf("All health checks failed for %s", url))
	return false
}

// StartHealthCheck 启动健康检查协程
func (hc *HealthChecker) StartHealthCheck(upstreams []string, onStatusChange func(string, bool)) {
	logger := gologger.GetLogger("healthcheck")
	go func() {
		statusMap := make(map[string]bool)
		for {
			for _, upstream := range upstreams {
				healthy := hc.CheckHealth(upstream)
				if status, exists := statusMap[upstream]; exists {
					if status != healthy {
						logger.Info(fmt.Sprintf("Upstream %s status changed to %v", upstream, healthy))
						if onStatusChange != nil {
							onStatusChange(upstream, healthy)
						}
					}
				}
				statusMap[upstream] = healthy
			}
			time.Sleep(hc.interval)
		}
	}()
}
