package usecase

import (
	"testing"

	"apps/backend/internal/module/radar/domain"
)

func TestMergeProductMatchArbitratesAndRecomputesOnlyFit(t *testing.T) {
	o := integrationOpportunity(1)
	first := integrationMatch("p1", 60)
	first.BrandNameSnapshot, first.ProductLabelSnapshot = "品牌", "產品一"
	if err := mergeProductMatchIntoOpportunity(o, first); err != nil {
		t.Fatal(err)
	}
	if o.PrimaryProductID != "p1" || o.PrimaryProductFitScore != 60 || o.IntentScore != 76 {
		t.Fatalf("first primary/fit: %+v", o)
	}
	// The other four reasons remain exactly as supplied.
	if o.Reasons[0].Score != 20 || o.Reasons[1].Score != 20 || o.Reasons[2].Score != 10 || o.Reasons[3].Score != 20 {
		t.Fatalf("non-fit reasons changed: %+v", o.Reasons)
	}

	higher := integrationMatch("p2", 80)
	higher.MatchedAt = first.MatchedAt + 1
	if err := mergeProductMatchIntoOpportunity(o, higher); err != nil {
		t.Fatal(err)
	}
	if o.PrimaryProductID != "p2" || o.PrimaryProductFitScore != 80 || o.IntentScore != 78 {
		t.Fatalf("higher match did not replace primary: %+v", o)
	}
}

func TestMergeProductMatchTieAndManualOverride(t *testing.T) {
	o := integrationOpportunity(1)
	a, b := integrationMatch("a", 80), integrationMatch("b", 80)
	a.MatchedAt, b.MatchedAt = 20, 10
	if err := mergeProductMatchIntoOpportunity(o, a); err != nil {
		t.Fatal(err)
	}
	if err := mergeProductMatchIntoOpportunity(o, b); err != nil {
		t.Fatal(err)
	}
	if o.PrimaryProductID != "b" {
		t.Fatalf("earlier tie should win, got %q", o.PrimaryProductID)
	}
	o.PrimaryProductOverridden = true
	o.PrimaryProductID = "a"
	domain.ApplyPrimaryProduct(o)
	c := integrationMatch("c", 100)
	if err := mergeProductMatchIntoOpportunity(o, c); err != nil {
		t.Fatal(err)
	}
	if o.PrimaryProductID != "a" {
		t.Fatalf("manual override was replaced: %q", o.PrimaryProductID)
	}
}

func TestMergeProductMatchSameProductOnlyMergesSources(t *testing.T) {
	o := integrationOpportunity(1)
	first := integrationMatch("p1", 60)
	first.WatchIDs, first.MatchedTerms = []string{"w1"}, []string{"痛點"}
	if err := mergeProductMatchIntoOpportunity(o, first); err != nil {
		t.Fatal(err)
	}
	second := integrationMatch("p1", 100)
	second.BrandNameSnapshot, second.ProductLabelSnapshot = "新版品牌", "新版產品"
	second.WatchIDs, second.MatchedTerms = []string{"w2"}, []string{"情境"}
	if err := mergeProductMatchIntoOpportunity(o, second); err != nil {
		t.Fatal(err)
	}
	if len(o.ProductMatches) != 1 || o.ProductMatches[0].ProductFitScore != 60 || o.ProductMatches[0].ProductLabelSnapshot != "" {
		t.Fatalf("same product was rejudged/replaced: %+v", o.ProductMatches)
	}
	if len(o.ProductMatches[0].WatchIDs) != 2 || len(o.ProductMatches[0].MatchedTerms) != 2 {
		t.Fatalf("source merge missing: %+v", o.ProductMatches[0])
	}
}
