package mapping

import (
	"testing"
	"time"

	"qctextbuilder/internal/domain"
)

func TestSuggestFieldValues_FillsEmptyMappedFields(t *testing.T) {
	t.Parallel()

	fields := []domain.TemplateField{
		{Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero},
		{Path: "services.servicesTitle_r4830_8", KeyName: "servicesTitle_r4830_8", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionServices},
		{Path: "services.servicesDescription_r4830_9", KeyName: "servicesDescription_r4830_9", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionServices},
		{Path: "text.buttonText_c1165_1", KeyName: "buttonText_c1165_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionCTA},
	}

	result := SuggestFieldValues(SuggestionRequest{
		Fields: fields,
		GlobalData: map[string]any{
			"companyName":  "Muster AG",
			"businessType": "Solar",
		},
		DraftContext: &domain.DraftContext{
			LLM: domain.DraftLLMContext{
				WebsiteSummary: "Wir planen und installieren Solaranlagen fuer KMU und Privatkunden.",
				StyleProfile: domain.DraftStyleProfile{
					ContentTone: "professionell",
				},
			},
		},
		Existing: map[string]string{},
	})

	if _, ok := result.ByFieldPath["text.textTitle_m1710_1"]; !ok {
		t.Fatalf("expected hero title suggestion")
	}
	if got := result.ByFieldPath["text.buttonText_c1165_1"].Value; got == "" {
		t.Fatalf("expected cta suggestion")
	}
	if got := result.ByFieldPath["services.servicesDescription_r4830_9"].Slot; got != "service_items[0].description" {
		t.Fatalf("unexpected slot: %q", got)
	}
}

func TestSuggestFieldValues_RespectsExistingValues(t *testing.T) {
	t.Parallel()

	fields := []domain.TemplateField{
		{Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero},
	}

	result := SuggestFieldValues(SuggestionRequest{
		Fields: fields,
		GlobalData: map[string]any{
			"companyName": "Muster AG",
		},
		Existing: map[string]string{
			"text.textTitle_m1710_1": "Schon gesetzt",
		},
	})

	if len(result.Suggestions) != 0 {
		t.Fatalf("expected no suggestions, got %d", len(result.Suggestions))
	}
}

func TestGenerateAllSuggestions_IncludesFilledFields(t *testing.T) {
	t.Parallel()

	fields := []domain.TemplateField{
		{Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero},
	}
	state := GenerateAllSuggestions(SuggestionRequest{
		Fields: fields,
		GlobalData: map[string]any{
			"companyName": "Muster AG",
		},
		Existing: map[string]string{
			"text.textTitle_m1710_1": "Bereits gesetzt",
		},
	}, domain.DraftSuggestionState{}, time.Now().UTC())

	if _, ok := state.ByFieldPath["text.textTitle_m1710_1"]; !ok {
		t.Fatalf("expected suggestion for filled field")
	}
}

func TestApplySuggestionsToEmptyFields_DoesNotOverwriteExisting(t *testing.T) {
	t.Parallel()

	now := time.Now().UTC()
	values, state := ApplySuggestionsToEmptyFields(map[string]string{
		"field.hero": "Custom",
	}, domain.DraftSuggestionState{
		ByFieldPath: map[string]domain.DraftSuggestion{
			"field.hero": {
				FieldPath: "field.hero",
				Value:     "Suggestion",
				Status:    domain.DraftSuggestionStatusSuggested,
			},
			"field.cta": {
				FieldPath: "field.cta",
				Value:     "Jetzt anfragen",
				Status:    domain.DraftSuggestionStatusSuggested,
			},
		},
	}, now)

	if got := values["field.hero"]; got != "Custom" {
		t.Fatalf("expected existing value unchanged, got %q", got)
	}
	if got := values["field.cta"]; got != "Jetzt anfragen" {
		t.Fatalf("expected empty value filled, got %q", got)
	}
	if got := state.ByFieldPath["field.hero"].Status; got != domain.DraftSuggestionStatusSuggested {
		t.Fatalf("expected hero status unchanged, got %q", got)
	}
	if got := state.ByFieldPath["field.cta"].Status; got != domain.DraftSuggestionStatusApplied {
		t.Fatalf("expected cta status applied, got %q", got)
	}
}

func TestApplyAllSuggestions_OverwritesExisting(t *testing.T) {
	t.Parallel()

	now := time.Now().UTC()
	values, state := ApplyAllSuggestions(map[string]string{
		"field.hero": "Custom",
	}, domain.DraftSuggestionState{
		ByFieldPath: map[string]domain.DraftSuggestion{
			"field.hero": {
				FieldPath: "field.hero",
				Value:     "Suggestion",
				Status:    domain.DraftSuggestionStatusSuggested,
			},
			"field.cta": {
				FieldPath: "field.cta",
				Value:     "Jetzt anfragen",
				Status:    domain.DraftSuggestionStatusSuggested,
			},
		},
	}, now)

	if got := values["field.hero"]; got != "Suggestion" {
		t.Fatalf("expected existing value overwritten, got %q", got)
	}
	if got := values["field.cta"]; got != "Jetzt anfragen" {
		t.Fatalf("expected cta applied, got %q", got)
	}
	if got := state.ByFieldPath["field.hero"].Status; got != domain.DraftSuggestionStatusApplied {
		t.Fatalf("expected hero status applied, got %q", got)
	}
	if got := state.ByFieldPath["field.cta"].Status; got != domain.DraftSuggestionStatusApplied {
		t.Fatalf("expected cta status applied, got %q", got)
	}
}

func TestRegenerateFieldSuggestion_OnlyChangesTargetField(t *testing.T) {
	t.Parallel()

	fields := []domain.TemplateField{
		{Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero},
		{Path: "text.buttonText_c1165_1", KeyName: "buttonText_c1165_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionCTA},
	}
	current := domain.DraftSuggestionState{
		ByFieldPath: map[string]domain.DraftSuggestion{
			"text.textTitle_m1710_1":  {FieldPath: "text.textTitle_m1710_1", Value: "Old Hero"},
			"text.buttonText_c1165_1": {FieldPath: "text.buttonText_c1165_1", Value: "Old CTA"},
		},
	}

	updated := RegenerateFieldSuggestion(SuggestionRequest{
		Fields: fields,
		GlobalData: map[string]any{
			"companyName": "Muster AG",
		},
	}, current, "text.buttonText_c1165_1", time.Now().UTC())

	if got := updated.ByFieldPath["text.textTitle_m1710_1"].Value; got != "Old Hero" {
		t.Fatalf("expected untargeted field unchanged, got %q", got)
	}
	if got := updated.ByFieldPath["text.buttonText_c1165_1"].Value; got == "" || got == "Old CTA" {
		t.Fatalf("expected target field regenerated, got %q", got)
	}
}
