package gtm

import (
	"github.com/go-logr/logr"
	. "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
	"github.com/tidbcloud/devops/entity/userbehavior"
	"github.com/tidbcloud/devops/pkg/infra/config"
	"github.com/tidbcloud/devops/pkg/infra/utils/pointer"
)

var _ = Describe("SimpleQualifier", func() {
	It("evaluates enrichment completeness and confidence", func() {
		q := &SimpleQualifier{logger: logr.Discard()}

		tests := []struct {
			name       string
			enrichment *CompanyEnrichment
			wantQual   bool
			wantReason string
		}{
			{
				name: "all fields complete",
				enrichment: &CompanyEnrichment{
					CompanyName:     "ViewEngine AI",
					Vertical:        "AI/ML Platform",
					BusinessModel:   "B2B SaaS",
					ConfidenceLevel: "high",
				},
				wantQual:   true,
				wantReason: "All required fields present and valid",
			},
			{
				name: "company name unknown",
				enrichment: &CompanyEnrichment{
					CompanyName:     "Unknown",
					Vertical:        "AI/ML Platform",
					BusinessModel:   "B2B SaaS",
					ConfidenceLevel: "high",
				},
				wantQual: false,
			},
			{
				name: "empty vertical",
				enrichment: &CompanyEnrichment{
					CompanyName:     "ViewEngine AI",
					Vertical:        "",
					BusinessModel:   "B2B SaaS",
					ConfidenceLevel: "high",
				},
				wantQual: false,
			},
			{
				name: "low confidence",
				enrichment: &CompanyEnrichment{
					CompanyName:     "ViewEngine AI",
					Vertical:        "AI/ML Platform",
					BusinessModel:   "B2B SaaS",
					ConfidenceLevel: "low",
				},
				wantQual: false,
			},
		}

		for _, tt := range tests {
			tt := tt
			By(tt.name)
			gotQual, gotReason := q.IsQualified(tt.enrichment)
			Expect(gotQual).To(Equal(tt.wantQual))
			if tt.wantReason != "" {
				Expect(gotReason).To(ContainSubstring(tt.wantReason))
			}
		}
	})
})

var _ = Describe("ReferenceMatcher", func() {
	It("matches leads against use case profiles", func() {
		profiles := []config.UseCaseProfile{
			{
				Name:                   "ai-llm-platform",
				Description:            "AI/LLM platforms",
				CustomerReferences:     []string{"manus", "dify"},
				RequiredKeywords:       []string{"ai", "machine learning", "llm"},
				PreferredBusinessModel: "b2b",
			},
		}

		m := NewReferenceMatcher(logr.Discard(), profiles)

		tests := []struct {
			name        string
			lead        *userbehavior.GTMLead
			wantMatched bool
			wantProfile string
		}{
			{
				name: "matches AI/LLM profile",
				lead: &userbehavior.GTMLead{
					Vertical:      pointer.Pointer("AI/ML Platform"),
					BusinessModel: pointer.Pointer("B2B SaaS"),
				},
				wantMatched: true,
				wantProfile: "ai-llm-platform",
			},
			{
				name: "matches multi-word keyword in vertical",
				lead: &userbehavior.GTMLead{
					Vertical:      pointer.Pointer("Machine Learning Infrastructure"),
					BusinessModel: pointer.Pointer("B2B SaaS"),
				},
				wantMatched: true,
				wantProfile: "ai-llm-platform",
			},
			{
				name: "no keyword match",
				lead: &userbehavior.GTMLead{
					Vertical:      pointer.Pointer("E-commerce"),
					BusinessModel: pointer.Pointer("B2B SaaS"),
				},
				wantMatched: false,
			},
			{
				name: "wrong business model",
				lead: &userbehavior.GTMLead{
					Vertical:      pointer.Pointer("AI/ML Platform"),
					BusinessModel: pointer.Pointer("B2C"),
				},
				wantMatched: false,
			},
			{
				name: "does not match when only business model contains required keyword",
				lead: &userbehavior.GTMLead{
					Vertical:      pointer.Pointer("Email Service Provider"),
					BusinessModel: pointer.Pointer("B2B AI tooling"),
				},
				wantMatched: false,
			},
			{
				name: "does not match unrelated real-world verticals",
				lead: &userbehavior.GTMLead{
					Vertical:      pointer.Pointer("Logistics & Supply Chain"),
					BusinessModel: pointer.Pointer("B2B"),
				},
				wantMatched: false,
			},
		}

		for _, tt := range tests {
			tt := tt
			By(tt.name)
			result := m.Match(tt.lead)
			Expect(result.Matched).To(Equal(tt.wantMatched))
			if tt.wantMatched {
				Expect(result.UseCaseProfile).To(Equal(tt.wantProfile))
				Expect(result.CustomerReferences).ToNot(BeEmpty())
			}
		}
	})
})

var _ = Describe("EmailComposer", func() {
	It("renders body with contact first name when available", func() {
		composer := NewEmailComposer(logr.Discard(), nil)

		body := composer.renderEmailBody(&userbehavior.GTMLead{
			ContactName:      pointer.Pointer("Alex Wang"),
			ContactFirstName: pointer.Pointer("Alex"),
			CompanyName:      pointer.Pointer("Example AI"),
		}, MatchResult{
			UseCaseProfile:     "ai-llm-platform",
			CustomerReferences: []string{"manus", "dify"},
		})

		Expect(body).To(ContainSubstring("Hi Alex,"))
		Expect(body).ToNot(ContainSubstring("Hi Alex Wang,"))
		Expect(body).To(ContainSubstring("I saw that you recently created clusters in TiDB Cloud"))
		Expect(body).To(ContainSubstring("what you're building at Example AI."))
		Expect(body).To(ContainSubstring("AI/LLM-driven products and helping them scale early"))
		Expect(body).To(ContainSubstring("Would it be worth a quick 15-minute conversation this week?"))
		Expect(body).To(ContainSubstring("Manus AI - Agents at Scale: https://www.youtube.com/watch?v=PP4Ht_JWA7k"))
		Expect(body).To(ContainSubstring("Best,\nChris\nTiDB Cloud Team"))
	})

	It("renders body with contact name fallback when first name is absent", func() {
		composer := NewEmailComposer(logr.Discard(), nil)

		body := composer.renderEmailBody(&userbehavior.GTMLead{
			ContactName: pointer.Pointer("Alex Wang"),
			CompanyName: pointer.Pointer("Example AI"),
		}, MatchResult{
			UseCaseProfile:     "ai-llm-platform",
			CustomerReferences: []string{"manus", "dify"},
		})

		Expect(body).To(ContainSubstring("Hi Alex Wang,"))
	})

	It("uses a generic snippet for matched profiles without dedicated copy", func() {
		composer := NewEmailComposer(logr.Discard(), nil)

		body := composer.renderEmailBody(&userbehavior.GTMLead{
			ContactFirstName: pointer.Pointer("Taylor"),
			CompanyName:      pointer.Pointer("Example Startup"),
		}, MatchResult{
			Matched:            true,
			UseCaseProfile:     "new-profile",
			CustomerReferences: []string{"customer-a", "customer-b"},
		})

		Expect(body).To(ContainSubstring("Hi Taylor,"))
		Expect(body).To(ContainSubstring("working with product teams building on TiDB Cloud"))
		Expect(body).To(ContainSubstring("credits, architecture guidance, and POC support"))
	})

	It("wraps rendered body in HTML when composing email", func() {
		composer := NewEmailComposer(logr.Discard(), nil)

		email, err := composer.ComposeEmail(GinkgoT().Context(), &userbehavior.GTMLead{
			ContactFirstName: pointer.Pointer("Alex"),
			CompanyName:      pointer.Pointer("Example AI"),
		}, MatchResult{
			Matched:            true,
			UseCaseProfile:     "ai-llm-platform",
			CustomerReferences: []string{"manus", "dify"},
		})

		Expect(err).ToNot(HaveOccurred())
		Expect(email.Subject).To(Equal("Example AI + TiDB Cloud"))
		Expect(email.HTMLBody).To(ContainSubstring("<!DOCTYPE html>"))
		Expect(email.HTMLBody).To(ContainSubstring("Hi Alex,<br>"))
	})
})
