package activeemeatenant

import (
	"testing"
	"time"

	activeemeamod "github.com/tidbcloud/devops/models/activeemea"
	"github.com/tidbcloud/devops/pkg/infra/config"
)

func TestEmailDomain(t *testing.T) {
	tests := []struct {
		name  string
		email string
		want  string
	}{
		{name: "plain email", email: "User@Example.COM", want: "example.com"},
		{name: "mail address", email: "Example User <user@company.co.uk>", want: "company.co.uk"},
		{name: "invalid", email: "not-an-email", want: ""},
		{name: "empty", email: "", want: ""},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := emailDomain(tt.email); got != tt.want {
				t.Fatalf("emailDomain() = %q, want %q", got, tt.want)
			}
		})
	}
}

func TestAccountCountryAllowListDefault(t *testing.T) {
	s := &svc{conf: config.ActiveEMEATenantReportConfig{}}
	if !s.accountCountryAllowed("DE") {
		t.Fatalf("DE should be allowed by default")
	}
	if !s.accountCountryAllowed("gb") {
		t.Fatalf("GB should be allowed by default")
	}
	if s.accountCountryAllowed("FR") {
		t.Fatalf("FR should not be allowed by default")
	}
}

func TestMinActiveClusterCount(t *testing.T) {
	zero := 0
	two := 2
	negative := -1
	tests := []struct {
		name string
		conf config.ActiveEMEATenantReportConfig
		want int
	}{
		{name: "nil fallback", conf: config.ActiveEMEATenantReportConfig{}, want: defaultMinClusterCount},
		{name: "explicit zero skips cluster gate", conf: config.ActiveEMEATenantReportConfig{MinActiveClusterCount: &zero}, want: 0},
		{name: "positive value", conf: config.ActiveEMEATenantReportConfig{MinActiveClusterCount: &two}, want: 2},
		{name: "negative fallback", conf: config.ActiveEMEATenantReportConfig{MinActiveClusterCount: &negative}, want: defaultMinClusterCount},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			s := &svc{conf: tt.conf}
			if got := s.minActiveClusterCount(); got != tt.want {
				t.Fatalf("minActiveClusterCount() = %d, want %d", got, tt.want)
			}
		})
	}
}

func TestParseDomainEnrichment(t *testing.T) {
	got, err := parseDomainEnrichment("```json\n{\"company_name\":\"Acme\",\"headquarter\":\"Berlin, Germany\",\"headquarter_country_code\":\"DE\",\"vertical\":\"SaaS\",\"business_model\":\"B2B\",\"ai_confidence_level\":\"high\"}\n```")
	if err != nil {
		t.Fatalf("parseDomainEnrichment() error = %v", err)
	}
	if got.CompanyName != "Acme" || got.HeadquarterCountryCode != "DE" || got.AIConfidenceLevel != "high" {
		t.Fatalf("parseDomainEnrichment() = %+v", got)
	}
}

func TestIsDomainEnrichmentFresh(t *testing.T) {
	now := time.Date(2026, 5, 9, 0, 0, 0, 0, time.UTC)
	future := now.Add(time.Hour)
	past := now.Add(-time.Hour)

	tests := []struct {
		name       string
		enrichment *activeemeamod.CompanyDomainEnrichment
		want       bool
	}{
		{name: "nil", enrichment: nil, want: false},
		{name: "fresh", enrichment: &activeemeamod.CompanyDomainEnrichment{
			SchemaVersion:          "v1",
			HeadquarterCountryCode: "DE",
			ExpiresAt:              &future,
		}, want: true},
		{name: "expired", enrichment: &activeemeamod.CompanyDomainEnrichment{
			SchemaVersion:          "v1",
			HeadquarterCountryCode: "DE",
			ExpiresAt:              &past,
		}, want: false},
		{name: "schema mismatch", enrichment: &activeemeamod.CompanyDomainEnrichment{
			SchemaVersion:          "v0",
			HeadquarterCountryCode: "DE",
			ExpiresAt:              &future,
		}, want: false},
		{name: "missing country", enrichment: &activeemeamod.CompanyDomainEnrichment{
			SchemaVersion: "v1",
			ExpiresAt:     &future,
		}, want: false},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := isDomainEnrichmentFresh(tt.enrichment, "v1", now); got != tt.want {
				t.Fatalf("isDomainEnrichmentFresh() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestShouldRefreshProfile(t *testing.T) {
	now := time.Date(2026, 5, 9, 0, 0, 0, 0, time.UTC)
	recent := now.Add(-time.Hour)
	old := now.Add(-25 * time.Hour)

	if !shouldRefreshProfile(nil, 24*time.Hour, now) {
		t.Fatalf("nil lastSyncedAt should refresh")
	}
	if shouldRefreshProfile(&recent, 24*time.Hour, now) {
		t.Fatalf("recent profile should not refresh")
	}
	if !shouldRefreshProfile(&old, 24*time.Hour, now) {
		t.Fatalf("old profile should refresh")
	}
}

func TestReportCSV(t *testing.T) {
	data, err := reportCSV([]*reportItem{{
		ReportDate:             "2026-05-09",
		TenantID:               1001,
		TenantName:             "Acme",
		OrgEmail:               "owner@acme.example",
		EmailDomain:            "acme.example",
		AccountCountry:         "DE",
		TenantRegion:           "EMEA",
		ClusterCount:           1,
		ClusterIDs:             "101,102",
		BillingConfigID:        2001,
		CardBrand:              "visa",
		CardCountry:            "DE",
		CardLast4:              "4242",
		CompanyName:            "Acme",
		Headquarter:            "Berlin, Germany",
		HeadquarterCountryCode: "DE",
		HeadquarterRegion:      "EMEA",
		ConfidenceLevel:        "high",
		OpsURL:                 "https://ops.example.com/orgs/1001",
	}})
	if err != nil {
		t.Fatalf("reportCSV() error = %v", err)
	}

	want := "Report Date,Tenant ID,Tenant Name,Org Email,Email Domain,Account Country,Tenant Region,Cluster Count,Cluster IDs,Billing Config ID,Card Brand,Card Country,Card Last4,Company Name,Headquarter,Headquarter Country Code,Headquarter Region,Confidence Level,Ops URL\n2026-05-09,1001,Acme,owner@acme.example,acme.example,DE,EMEA,1,\"101,102\",2001,visa,DE,4242,Acme,\"Berlin, Germany\",DE,EMEA,high,https://ops.example.com/orgs/1001\n"
	if string(data) != want {
		t.Fatalf("reportCSV() = %q, want %q", string(data), want)
	}
}

func TestReportS3Key(t *testing.T) {
	s := &svc{}
	got := s.reportS3Key("2026-05-09", time.Date(2026, 5, 9, 1, 2, 3, 0, time.UTC))
	want := "active-emea-tenant-report/date=2026-05-09/report_20260509010203.csv"
	if got != want {
		t.Fatalf("reportS3Key() = %q, want %q", got, want)
	}
}

func TestBuildReportCard(t *testing.T) {
	card := buildReportCard("2026-05-09", 18, "https://pingcap.feishu.cn/sheets/test")
	if card.Type() != "interactive" {
		t.Fatalf("card.Type() = %q, want interactive", card.Type())
	}
	if card.Header.Title.Content != "Active EMEA tenant report 2026-05-09 generated." {
		t.Fatalf("card title = %q", card.Header.Title.Content)
	}
	if len(card.Elements) != 1 {
		t.Fatalf("card elements = %d, want 1", len(card.Elements))
	}
	want := "**Active Tenants:** 18\n**Sheet:** [Open Report](https://pingcap.feishu.cn/sheets/test)"
	if card.Elements[0].Text.Content != want {
		t.Fatalf("card content = %q, want %q", card.Elements[0].Text.Content, want)
	}
}
