package placement

import (
	"strings"

	libkg "haixun-backend/internal/library/knowledge"
	"haixun-backend/internal/library/websearch"
)

const defaultPatrolProductFit = 78

// CollectPatrolTagQueries builds dual-track crawl jobs from user-edited patrol keywords only.
func CollectPatrolTagQueries(keywords []string, nodes []libkg.Node, provider websearch.Provider) []TagQuery {
	keywords = libkg.NormalizePatrolKeywordList(keywords)
	if len(keywords) == 0 {
		return nil
	}

	out := make([]TagQuery, 0, len(keywords)*3)
	for _, tag := range keywords {
		fit := productFitForPatrolTag(tag, nodes)
		if q := BuildRelevanceQuery(provider, tag); q != "" {
			out = append(out, TagQuery{
				Tag:             tag,
				Query:           q,
				Dimension:       QueryRelevance,
				ProductFitScore: fit,
			})
		}
		if q7 := BuildRecencyQuery(provider, tag, IdealMaxPostAgeDays); q7 != "" {
			out = append(out, TagQuery{
				Tag:             tag,
				Query:           q7,
				Dimension:       QueryRecency,
				ProductFitScore: fit,
				RecencyDays:     IdealMaxPostAgeDays,
			})
		}
		if q30 := BuildRecencyQuery(provider, tag, MaxPostAgeDays); q30 != "" {
			if q7 := BuildRecencyQuery(provider, tag, IdealMaxPostAgeDays); q30 != q7 {
				out = append(out, TagQuery{
					Tag:             tag,
					Query:           q30,
					Dimension:       QueryRecency,
					ProductFitScore: fit,
					RecencyDays:     MaxPostAgeDays,
				})
			}
		}
	}
	return out
}

func productFitForPatrolTag(tag string, nodes []libkg.Node) int {
	tagKey := patrolTagMatchKey(tag)
	best := 0
	bestNodeID := ""
	for _, node := range nodes {
		score := node.ProductFitScore
		if score <= 0 {
			continue
		}
		matched := false
		for _, candidate := range append(append([]string{}, node.DerivedTags.Relevance...), node.DerivedTags.Recency...) {
			if patrolTagMatchKey(candidate) == tagKey {
				matched = true
				break
			}
		}
		if !matched && patrolTagMatchKey(node.Label) != tagKey {
			continue
		}
		if score > best {
			best = score
			bestNodeID = node.ID
		}
	}
	if best > 0 {
		return best
	}
	_ = bestNodeID
	return defaultPatrolProductFit
}

func patrolTagMatchKey(tag string) string {
	tag = strings.TrimSpace(tag)
	for _, suffix := range []string{" 推薦", " 請問", " 怎麼辦", " 好用嗎", " 有人用過嗎", " 有推薦嗎", " 請益"} {
		if strings.HasSuffix(tag, suffix) {
			tag = strings.TrimSuffix(tag, suffix)
			break
		}
	}
	return strings.TrimSpace(tag)
}

// ResolveTagQueries prefers explicit patrol keywords over graph node selection.
func ResolveTagQueries(nodes []libkg.Node, patrolKeywords []string, provider websearch.Provider) []TagQuery {
	if len(patrolKeywords) > 0 {
		return CollectPatrolTagQueries(patrolKeywords, nodes, provider)
	}
	return CollectTagQueries(nodes, provider)
}
