package compaction

import (
	"chat-switchboard/treepath"
)

// ── Token Estimation ────────────────────────
//
// Rough heuristic matching the frontend Tokens.estimate() (~4 chars/token).
// Good enough for threshold checks. Swap in a real tokenizer later if
// over/under-triggering becomes a problem.

// EstimateTokens returns a rough token count for a string.
// Uses the ~4 chars/token heuristic for English (GPT/Claude average).
func EstimateTokens(text string) int {
	return (len(text) + 3) / 4
}

// EstimatePath returns total estimated tokens for a message path.
// Adds +4 per message for role/delimiter overhead, matching the frontend.
func EstimatePath(path []treepath.PathMessage) int {
	total := 0
	for i := range path {
		total += EstimateTokens(path[i].Content) + 4
	}
	return total
}

// EstimatePathFromSummary returns estimated tokens for messages after
// the most recent summary boundary. Returns 0 and false if a summary
// exists but fewer than minMessages follow it.
func EstimatePathFromSummary(path []treepath.PathMessage, minMessages int) (tokens int, msgCount int, ok bool) {
	startIdx := 0
	for i := range path {
		if treepath.IsSummaryMessage(&path[i]) {
			startIdx = i + 1
		}
	}

	post := path[startIdx:]

	// Count non-system, non-summary messages
	count := 0
	est := 0
	for i := range post {
		if post[i].Role == "system" || treepath.IsSummaryMessage(&post[i]) {
			continue
		}
		count++
		est += EstimateTokens(post[i].Content) + 4
	}

	if count < minMessages {
		return 0, count, false
	}
	return est, count, true
}
