package mapping

import (
	"testing"

	"qctextbuilder/internal/domain"
)

func TestMapTemplateFieldsToSemanticSlots(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.introTitle_c7886_1",
			KeyName:        "introTitle_c7886_1",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionIntro,
		},
		{
			Path:           "text.introDescription_c7886_2",
			KeyName:        "introDescription_c7886_2",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionIntro,
		},
		{
			Path:           "services.serviceTitle_r4830_1",
			KeyName:        "serviceTitle_r4830_1",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionServices,
		},
		{
			Path:           "services.serviceDescription_r4830_2",
			KeyName:        "serviceDescription_r4830_2",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionServices,
		},
		{
			Path:           "team.teamMemberName_r4748_1",
			KeyName:        "teamMemberName_r4748_1",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "team.teamDescription_r4748_2",
			KeyName:        "teamDescription_r4748_2",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "testimonials.testimonialTitle_r1508_1",
			KeyName:        "testimonialTitle_r1508_1",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialDescription_r1508_2",
			KeyName:        "testimonialDescription_r1508_2",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialName_r1508_3",
			KeyName:        "testimonialName_r1508_3",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "text.buttonText_c1165_1",
			KeyName:        "buttonText_c1165_1",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionCTA,
		},
	}

	got := MapTemplateFieldsToSemanticSlots(fields)
	if len(got.Targets) != 11 {
		t.Fatalf("expected 11 targets, got %d", len(got.Targets))
	}

	assertHasSlotPath(t, got, "hero.title", "text.textTitle_m1710_1")
	assertHasSlotPath(t, got, "intro.title", "text.introTitle_c7886_1")
	assertHasSlotPath(t, got, "intro.description", "text.introDescription_c7886_2")
	assertHasSlotPath(t, got, "service_items[0].title", "services.serviceTitle_r4830_1")
	assertHasSlotPath(t, got, "service_items[0].description", "services.serviceDescription_r4830_2")
	assertHasSlotPath(t, got, "team_items[0].name", "team.teamMemberName_r4748_1")
	assertHasSlotPath(t, got, "team_items[0].description", "team.teamDescription_r4748_2")
	assertHasSlotPath(t, got, "testimonial_items[0].title", "testimonials.testimonialTitle_r1508_1")
	assertHasSlotPath(t, got, "testimonial_items[0].description", "testimonials.testimonialDescription_r1508_2")
	assertHasSlotPath(t, got, "testimonial_items[0].name", "testimonials.testimonialName_r1508_3")
	assertHasSlotPath(t, got, "cta.text", "text.buttonText_c1165_1")
}

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

	fields := []domain.TemplateField{
		{
			Path:      "welcome.headline_m1710_1",
			KeyName:   "headline_m1710_1",
			Section:   "welcome",
			FieldKind: "text",
			IsEnabled: true,
		},
	}

	got := MapTemplateFieldsToSemanticSlots(fields)
	assertHasSlotPath(t, got, "hero.title", "welcome.headline_m1710_1")
}

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

	fields := []domain.TemplateField{
		{
			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:           "services.servicesTitle_r4830_10",
			KeyName:        "servicesTitle_r4830_10",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionServices,
		},
		{
			Path:           "services.servicesDescription_r4830_11",
			KeyName:        "servicesDescription_r4830_11",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionServices,
		},
		{
			Path:           "services.servicesTitle_r4830_12",
			KeyName:        "servicesTitle_r4830_12",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionServices,
		},
		{
			Path:           "services.servicesDescription_r4830_13",
			KeyName:        "servicesDescription_r4830_13",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionServices,
		},
		{
			Path:           "text.textName_r4748_17",
			KeyName:        "textName_r4748_17",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "text.textDescription_r4748_18",
			KeyName:        "textDescription_r4748_18",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "text.textName_r4748_19",
			KeyName:        "textName_r4748_19",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "text.textDescription_r4748_20",
			KeyName:        "textDescription_r4748_20",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "text.textName_r4748_21",
			KeyName:        "textName_r4748_21",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "text.textDescription_r4748_22",
			KeyName:        "textDescription_r4748_22",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTeam,
		},
		{
			Path:           "testimonials.testimonialsName_r1508_23",
			KeyName:        "testimonialsName_r1508_23",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsTitle_r1508_24",
			KeyName:        "testimonialsTitle_r1508_24",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsDescription_r1508_25",
			KeyName:        "testimonialsDescription_r1508_25",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsName_r1508_26",
			KeyName:        "testimonialsName_r1508_26",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsTitle_r1508_27",
			KeyName:        "testimonialsTitle_r1508_27",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsDescription_r1508_28",
			KeyName:        "testimonialsDescription_r1508_28",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsName_r1508_29",
			KeyName:        "testimonialsName_r1508_29",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsTitle_r1508_30",
			KeyName:        "testimonialsTitle_r1508_30",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsDescription_r1508_31",
			KeyName:        "testimonialsDescription_r1508_31",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsName_r1508_32",
			KeyName:        "testimonialsName_r1508_32",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsTitle_r1508_33",
			KeyName:        "testimonialsTitle_r1508_33",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
		{
			Path:           "testimonials.testimonialsDescription_r1508_34",
			KeyName:        "testimonialsDescription_r1508_34",
			FieldKind:      "text",
			IsEnabled:      true,
			WebsiteSection: domain.WebsiteSectionTestimonials,
		},
	}

	got := MapTemplateFieldsToSemanticSlots(fields)

	assertHasSlotPath(t, got, "service_items[0].title", "services.servicesTitle_r4830_8")
	assertHasSlotPath(t, got, "service_items[0].description", "services.servicesDescription_r4830_9")
	assertHasSlotPath(t, got, "service_items[1].title", "services.servicesTitle_r4830_10")
	assertHasSlotPath(t, got, "service_items[1].description", "services.servicesDescription_r4830_11")
	assertHasSlotPath(t, got, "service_items[2].title", "services.servicesTitle_r4830_12")
	assertHasSlotPath(t, got, "service_items[2].description", "services.servicesDescription_r4830_13")

	assertHasSlotPath(t, got, "team_items[0].name", "text.textName_r4748_17")
	assertHasSlotPath(t, got, "team_items[0].description", "text.textDescription_r4748_18")
	assertHasSlotPath(t, got, "team_items[1].name", "text.textName_r4748_19")
	assertHasSlotPath(t, got, "team_items[1].description", "text.textDescription_r4748_20")
	assertHasSlotPath(t, got, "team_items[2].name", "text.textName_r4748_21")
	assertHasSlotPath(t, got, "team_items[2].description", "text.textDescription_r4748_22")

	assertHasSlotPath(t, got, "testimonial_items[0].name", "testimonials.testimonialsName_r1508_23")
	assertHasSlotPath(t, got, "testimonial_items[0].title", "testimonials.testimonialsTitle_r1508_24")
	assertHasSlotPath(t, got, "testimonial_items[0].description", "testimonials.testimonialsDescription_r1508_25")
	assertHasSlotPath(t, got, "testimonial_items[1].name", "testimonials.testimonialsName_r1508_26")
	assertHasSlotPath(t, got, "testimonial_items[1].title", "testimonials.testimonialsTitle_r1508_27")
	assertHasSlotPath(t, got, "testimonial_items[1].description", "testimonials.testimonialsDescription_r1508_28")
	assertHasSlotPath(t, got, "testimonial_items[2].name", "testimonials.testimonialsName_r1508_29")
	assertHasSlotPath(t, got, "testimonial_items[2].title", "testimonials.testimonialsTitle_r1508_30")
	assertHasSlotPath(t, got, "testimonial_items[2].description", "testimonials.testimonialsDescription_r1508_31")
	assertHasSlotPath(t, got, "testimonial_items[3].name", "testimonials.testimonialsName_r1508_32")
	assertHasSlotPath(t, got, "testimonial_items[3].title", "testimonials.testimonialsTitle_r1508_33")
	assertHasSlotPath(t, got, "testimonial_items[3].description", "testimonials.testimonialsDescription_r1508_34")

	assertSlotCount(t, got, "team_items[0].name", 1)
	assertSlotCount(t, got, "team_items[0].description", 1)
	assertSlotCount(t, got, "testimonial_items[0].name", 1)
	assertSlotCount(t, got, "testimonial_items[0].title", 1)
	assertSlotCount(t, got, "testimonial_items[0].description", 1)
}

func assertHasSlotPath(t *testing.T, mapping SemanticSlotMapping, slot string, path string) {
	t.Helper()
	candidates := mapping.BySlot[slot]
	for _, item := range candidates {
		if item.FieldPath == path {
			return
		}
	}
	t.Fatalf("slot %q missing path %q", slot, path)
}

func assertSlotCount(t *testing.T, mapping SemanticSlotMapping, slot string, expected int) {
	t.Helper()
	if got := len(mapping.BySlot[slot]); got != expected {
		t.Fatalf("slot %q has %d candidates, want %d", slot, got, expected)
	}
}
