package executionpool

import (
	"strings"
	"time"
)

type RoutePreference struct {
	RouteProfileKey  string
	CurrentPoolID    string
	CurrentSince     time.Time
	ChallengerPoolID string
	ChallengerWins   int
	UpdatedAt        time.Time
}

func AdvanceRoutePreference(
	previous RoutePreference,
	proposedPoolID string,
	scores map[string]float64,
	now time.Time,
) RoutePreference {
	if now.IsZero() {
		now = time.Now()
	}
	proposedPoolID = strings.TrimSpace(proposedPoolID)
	next := previous
	next.UpdatedAt = now
	if proposedPoolID == "" {
		return next
	}
	if _, eligible := scores[next.CurrentPoolID]; next.CurrentPoolID == "" || !eligible {
		next.CurrentPoolID = proposedPoolID
		next.CurrentSince = now
		next.ChallengerPoolID = ""
		next.ChallengerWins = 0
		return next
	}
	if proposedPoolID == next.CurrentPoolID {
		next.ChallengerPoolID = ""
		next.ChallengerWins = 0
		return next
	}
	if relativeImprovement(scores[proposedPoolID], scores[next.CurrentPoolID]) < defaultSwitchImprovement {
		next.ChallengerPoolID = ""
		next.ChallengerWins = 0
		return next
	}
	if next.ChallengerPoolID == proposedPoolID {
		next.ChallengerWins++
	} else {
		next.ChallengerPoolID = proposedPoolID
		next.ChallengerWins = 1
	}
	if next.ChallengerWins >= defaultBetterWindowCount &&
		!next.CurrentSince.IsZero() && now.Sub(next.CurrentSince) >= defaultMinimumDwell {
		next.CurrentPoolID = proposedPoolID
		next.CurrentSince = now
		next.ChallengerPoolID = ""
		next.ChallengerWins = 0
	}
	return next
}
