package domain

import "testing"

func fitReasons() []ProductFitReason {
	return []ProductFitReason{
		{Dimension: ProductFitPain, Score: 30, Reason: "貼文描述漏水", CandidateExcerpt: "天花板一直漏水", ProductBasis: "漏水"},
		{Dimension: ProductFitScenario, Score: 20, Reason: "有居家處理情境", CandidateExcerpt: "想找人處理", ProductBasis: "居家修繕"},
		{Dimension: ProductFitAudience, Score: 10, Reason: "文字支持自住家庭", CandidateExcerpt: "家裡", ProductBasis: "自住家庭"},
		{Dimension: ProductFitCapability, Score: 10, Reason: "能力詞可處理", CandidateExcerpt: "抓漏", ProductBasis: "抓漏"},
	}
}

func TestProductMatchFitBandsAndEligibility(t *testing.T) {
	cases := []struct {
		score    int
		band     string
		eligible bool
	}{
		{100, ProductFitBandStrong, true}, {75, ProductFitBandStrong, true}, {74, ProductFitBandPossible, true}, {45, ProductFitBandPossible, true}, {44, ProductFitBandWeak, false},
	}
	for _, tc := range cases {
		m := &ProductMatch{BrandID: "b", ProductID: "p", ProductFitScore: tc.score, ProductFitBand: ProductFitBandFromScore(tc.score), Reasons: fitReasons()}
		// Adapt reason total to table boundary while keeping evidence contract.
		m.Reasons[0].Score, m.Reasons[1].Score, m.Reasons[2].Score, m.Reasons[3].Score = tc.score, 0, 0, 0
		if tc.score > 35 {
			m.Reasons[0].Score = 35
			m.Reasons[1].Score = tc.score - 35
		}
		if m.Reasons[1].Score > 25 {
			m.Reasons[1].Score = 25
			m.Reasons[2].Score = tc.score - 60
		}
		if m.Reasons[2].Score > 20 {
			m.Reasons[2].Score = 20
			m.Reasons[3].Score = tc.score - 80
		}
		if tc.score > 0 {
			for i := range m.Reasons {
				if m.Reasons[i].Score == 0 {
					m.Reasons[i].CandidateExcerpt = "證據"
					m.Reasons[i].ProductBasis = "依據"
				}
			}
		}
		if err := m.ValidateForWrite(); err != nil {
			t.Fatalf("score %d: %v", tc.score, err)
		}
		if m.ProductFitBand != tc.band || m.Eligible != tc.eligible {
			t.Fatalf("score %d got band=%s eligible=%v", tc.score, m.ProductFitBand, m.Eligible)
		}
	}
}

func TestProductMatchPositiveReasonNeedsEvidence(t *testing.T) {
	m := &ProductMatch{BrandID: "b", ProductID: "p", ProductFitScore: 10, Reasons: fitReasons()}
	m.Reasons[0].Score = 10
	m.Reasons[1].Score, m.Reasons[2].Score, m.Reasons[3].Score = 0, 0, 0
	m.Reasons[0].CandidateExcerpt = ""
	if err := m.ValidateForWrite(); err == nil {
		t.Fatal("positive reason without excerpt must fail")
	}
}
