package knowledge

import (
	"strings"
	"unicode/utf8"

	"github.com/google/uuid"
)

const (
	maxPatrolLabelRunes = 14
	minBreadthNodeCount = 12
)

func SupplementGraphFromResearchMap(g *Graph, seed string, pillars, questions []string) {
	if g == nil {
		return
	}
	seen := nodeLabelSet(g.Nodes)
	ensureSeedCore(g, seed, seen)
	for _, pillar := range pillars {
		if len(g.Nodes) >= 32 {
			break
		}
		addBreadthNode(g, strings.TrimSpace(pillar), 1, "symptom", seen, pillar, "")
	}
	for _, question := range questions {
		if len(g.Nodes) >= 32 {
			break
		}
		q := strings.TrimSpace(question)
		if q == "" {
			continue
		}
		label := patrolLabelFromQuestion(q)
		addBreadthNode(g, label, 2, "pain", seen, q, defaultPlacementForQuestion(q))
	}
}

func ensureSeedCore(g *Graph, seed string, seen map[string]struct{}) {
	seed = strings.TrimSpace(seed)
	if seed == "" {
		return
	}
	if _, ok := seen[strings.ToLower(seed)]; ok {
		return
	}
	g.Nodes = append([]Node{{
		ID:              uuid.NewString(),
		Label:           seed,
		NodeKind:        "pain",
		Type:            "core",
		Layer:           0,
		Relation:        "核心種子主題，使用者圍繞此困擾在社群發文求助",
		PlacementValue:  "核心討論串最常求推薦與真實心得，適合以產品使用經驗自然回覆",
		ProductFitScore: 90,
	}}, g.Nodes...)
	seen[strings.ToLower(seed)] = struct{}{}
}

func addBreadthNode(g *Graph, label string, layer int, kind string, seen map[string]struct{}, relation, placement string) {
	label = strings.TrimSpace(label)
	if label == "" {
		return
	}
	key := strings.ToLower(label)
	if _, ok := seen[key]; ok {
		return
	}
	if relation == "" {
		relation = "與種子主題相關的「" + label + "」討論，常見於 Threads 求助串"
	}
	if placement == "" {
		placement = "這類帖常求產品推薦或使用心得，適合以自身經驗自然回覆"
	}
	g.Nodes = append(g.Nodes, Node{
		ID:              uuid.NewString(),
		Label:           label,
		NodeKind:        kind,
		Type:            breadthNodeType(layer, kind),
		Layer:           layer,
		Relation:        relation,
		PlacementValue:  placement,
		ProductFitScore: defaultProductFit(kind, layer),
	})
	seen[key] = struct{}{}
}

func breadthNodeType(layer int, kind string) string {
	if layer == 0 {
		return "core"
	}
	if kind == "cause" {
		return "cause"
	}
	if kind == "symptom" {
		return "symptom"
	}
	return "mechanism"
}

func nodeLabelSet(nodes []Node) map[string]struct{} {
	seen := map[string]struct{}{}
	for _, node := range nodes {
		label := strings.ToLower(strings.TrimSpace(node.Label))
		if label != "" {
			seen[label] = struct{}{}
		}
	}
	return seen
}

func patrolLabelFromQuestion(question string) string {
	question = strings.TrimSpace(question)
	if question == "" {
		return ""
	}
	if utf8.RuneCountInString(question) <= maxPatrolLabelRunes {
		return question
	}
	runes := []rune(question)
	return string(runes[:maxPatrolLabelRunes])
}

func defaultPlacementForQuestion(question string) string {
	return "受眾常這樣發文求助，適合在留言區以產品使用經驗回覆「" + strings.TrimSpace(question) + "」這類問題"
}

func GraphNeedsBootstrap(g Graph) bool {
	return len(g.Nodes) < minBreadthNodeCount
}
