package replay

import (
	"fmt"
	"regexp"
	"strings"
)

// fillerPatterns are the hedge phrases the spec rejects. Compiled once
// per package — the gate runs on every replay call.
var fillerPatterns = []*regexp.Regexp{
	regexp.MustCompile(`(?i)as an ai`),
	regexp.MustCompile(`(?i)i cannot`),
	regexp.MustCompile(`(?i)i'?m sorry, but`),
	regexp.MustCompile(`(?i)i don'?t have access`),
	regexp.MustCompile(`(?i)i am unable to`),
}

// ValidateResponse runs the deterministic gate on a model response.
// Empty / too-short / hedge-bearing / context-disconnected responses
// fail. Matches replay.ts:validateResponse one-to-one.
func ValidateResponse(response string, bundle *ContextBundle) ValidationResult {
	trimmed := strings.TrimSpace(response)
	var reasons []string

	if len(trimmed) == 0 {
		return ValidationResult{Passed: false, Reasons: []string{"empty response"}}
	}
	if len(trimmed) < 80 {
		reasons = append(reasons, fmt.Sprintf("response too short (%d chars; min 80)", len(trimmed)))
	}
	for _, re := range fillerPatterns {
		if re.MatchString(trimmed) {
			reasons = append(reasons, fmt.Sprintf("filler/hedge phrase detected: %s", re.String()))
		}
	}
	// Soft anchor: if a validation checklist was supplied, the response
	// should share at least one token with it (≥3 chars per tokenize()).
	if bundle != nil && len(bundle.ValidationSteps) > 0 {
		checklistTokens := map[string]struct{}{}
		for _, s := range bundle.ValidationSteps {
			for t := range tokenize(s) {
				checklistTokens[t] = struct{}{}
			}
		}
		respTokens := tokenize(trimmed)
		overlap := 0
		for t := range checklistTokens {
			if _, ok := respTokens[t]; ok {
				overlap++
			}
		}
		if len(checklistTokens) > 0 && overlap == 0 {
			reasons = append(reasons, "response shares no tokens with validation checklist (may not have followed prior patterns)")
		}
	}

	return ValidationResult{Passed: len(reasons) == 0, Reasons: reasonsOrEmpty(reasons)}
}

func reasonsOrEmpty(r []string) []string {
	if r == nil {
		return []string{}
	}
	return r
}
