package knowledge

import "testing"

func TestNormalizePlacementReason(t *testing.T) {
	got := normalizePlacementReason("high", "", "pain", 90)
	if got == "" || got == "high" {
		t.Fatalf("expected prose for legacy high, got %q", got)
	}

	got = normalizePlacementReason("換季泛紅帖常求溫和修護產品", "", "pain", 85)
	if got != "換季泛紅帖常求溫和修護產品" {
		t.Fatalf("expected prose preserved, got %q", got)
	}
}

func TestExtractJSONObject(t *testing.T) {
	valid := `{"nodes":[{"label":"a","evidenceUrls":[]}],"edges":[]}`
	cases := []struct {
		name    string
		raw     string
		wantErr bool
	}{
		{name: "plain", raw: valid},
		{name: "prefixed text", raw: "分析完成。\n" + valid},
		{name: "code fence", raw: "說明如下：\n```json\n" + valid + "\n```"},
		{name: "trailing object", raw: valid + `,{"summary":"ignored"}`},
		{name: "brace in string", raw: `{"nodes":[{"label":"含{符號}的節點","evidenceUrls":[]}],"edges":[]}`},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			payload, err := extractJSONObject(tc.raw)
			if tc.wantErr {
				if err == nil {
					t.Fatal("expected error")
				}
				return
			}
			if err != nil {
				t.Fatal(err)
			}
			graph, err := ParseSynthOutput(string(payload), SynthInput{Seed: "種子"}, nil)
			if err != nil {
				t.Fatal(err)
			}
			if len(graph.Nodes) == 0 {
				t.Fatal("expected nodes")
			}
		})
	}
}

func TestParseSynthOutputPlacementReason(t *testing.T) {
	raw := `{
  "nodes": [
    {
      "label": "換季泛紅",
      "nodeKind": "symptom",
      "type": "symptom",
      "layer": 1,
      "relation": "溫差變化會讓敏感肌臉頰泛紅刺痛",
      "placementValue": "求助帖常問舒緩產品，可分享溫和修護的實際經驗",
      "productFitScore": 82,
      "evidenceUrls": []
    }
  ],
  "edges": []
}`
	graph, err := ParseSynthOutput(raw, SynthInput{Seed: "敏感肌"}, nil)
	if err != nil {
		t.Fatal(err)
	}
	if len(graph.Nodes) < 2 {
		t.Fatalf("expected core + parsed node, got %d nodes", len(graph.Nodes))
	}
	node := graph.Nodes[len(graph.Nodes)-1]
	if node.Relation == "" {
		t.Fatal("expected relation")
	}
	if node.PlacementValue == "" || node.PlacementValue == "high" {
		t.Fatalf("expected placement prose, got %q", node.PlacementValue)
	}
}
