package knowledge

import (
	"sort"
	"strings"
)

// SelectBestSearchKeywords pools research map, graph, product, and optional hints,
// then returns the most intent-relevant phrases for Search API (not UI display order).
func SelectBestSearchKeywords(explicit, saved []string, in PatrolTagInput, nodes []Node, limit int) []string {
	if limit <= 0 {
		limit = MaxScanPatrolKeywords
	}
	profile := BuildIntentProfile(in)
	candidates := BuildPatrolCandidates(in, nodes)

	for i, tag := range NormalizePatrolKeywordList(explicit) {
		addPatrolCandidate(&candidates, tag, 156-i, "掃描指定", patrolIntentRelevance)
	}
	for i, tag := range NormalizePatrolKeywordList(saved) {
		if containsNormalizedTag(explicit, tag) {
			continue
		}
		addPatrolCandidate(&candidates, tag, 88-i, "研究地圖儲存", patrolIntentRelevance)
	}

	type ranked struct {
		tag   string
		score int
	}
	scored := make([]ranked, 0, len(candidates))
	seen := map[string]struct{}{}
	for _, item := range selectTopPatrolCandidates(candidates, len(candidates)+32) {
		tag := strings.TrimSpace(item.Tag)
		if tag == "" {
			continue
		}
		key := patrolTagDedupeKey(tag)
		if _, ok := seen[key]; ok {
			continue
		}
		seen[key] = struct{}{}
		if IsTangentialToIntent(tag, profile) {
			continue
		}
		intent := ScoreIntentSimilarity(tag, profile)
		if intent < 8 && item.Score < 65 {
			continue
		}
		final := (item.Score*2 + intent*4) / 6
		if final <= 0 {
			continue
		}
		scored = append(scored, ranked{tag: tag, score: final})
	}

	sort.SliceStable(scored, func(i, j int) bool {
		if scored[i].score == scored[j].score {
			return scored[i].tag < scored[j].tag
		}
		return scored[i].score > scored[j].score
	})

	out := make([]string, 0, limit)
	for _, item := range scored {
		out = append(out, item.tag)
		if len(out) >= limit {
			break
		}
	}
	return out
}

func containsNormalizedTag(items []string, target string) bool {
	targetKey := patrolTagDedupeKey(target)
	for _, item := range items {
		if patrolTagDedupeKey(item) == targetKey {
			return true
		}
	}
	return false
}
