package metadata

import (
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

// TestEnrichWithSystemFieldsPreservesIsNameField is Test D from issue #1079.
//
// EnrichWithSystemFields is the custom-object creation path. It must:
//   - Preserve IsNameField=true on user-declared name fields (no override).
//   - NOT inject a default Name field when IsNameField is already declared.
//   - Inject a default Name field when no IsNameField and no "Name" column exist.
//
// This test locks the behavior so that the pack-apply autonumber stamp
// (issue #1079 fix) cannot accidentally regress the custom-object path.
func TestEnrichWithSystemFieldsPreservesIsNameField(t *testing.T) {
	t.Run("preserves explicit IsNameField on autonumber display field", func(t *testing.T) {
		schema := &models.ObjectMetadata{
			APIName: "Order",
			Fields: []models.FieldMetadata{
				{APIName: "OrderNumber", Label: "Order Number", Type: constants.FieldTypeAutonumber, IsNameField: true},
				{APIName: "Status", Label: "Status", Type: constants.FieldTypeString},
			},
		}

		EnrichWithSystemFields(schema, nil)

		var hasNameField bool
		for _, f := range schema.Fields {
			if f.APIName == "OrderNumber" && f.IsNameField {
				hasNameField = true
			}
		}
		if !hasNameField {
			t.Error("EnrichWithSystemFields removed IsNameField=true from OrderNumber")
		}

		// Must not inject a redundant default Name field when IsNameField already exists.
		for _, f := range schema.Fields {
			if f.APIName == constants.FieldName && f.IsNameField {
				t.Errorf("EnrichWithSystemFields injected a default Name field when IsNameField was already set on OrderNumber")
			}
		}
	})

	t.Run("injects Name field when no IsNameField and no Name column", func(t *testing.T) {
		schema := &models.ObjectMetadata{
			APIName: "Foo__c",
			Fields: []models.FieldMetadata{
				{APIName: "Description__c", Label: "Description", Type: constants.FieldTypeString},
			},
		}

		EnrichWithSystemFields(schema, nil)

		var hasNameField bool
		for _, f := range schema.Fields {
			if f.IsNameField {
				hasNameField = true
				break
			}
		}
		if !hasNameField {
			t.Error("EnrichWithSystemFields must inject a Name field (IsNameField=true) when no name field exists")
		}
	})

	t.Run("does not double-inject Name when Name column already present", func(t *testing.T) {
		schema := &models.ObjectMetadata{
			APIName: "Contact",
			Fields: []models.FieldMetadata{
				{APIName: "Name", Label: "Full Name", Type: constants.FieldTypeString},
			},
		}

		EnrichWithSystemFields(schema, nil)

		var nameCount int
		for _, f := range schema.Fields {
			if f.APIName == constants.FieldName {
				nameCount++
			}
		}
		if nameCount > 1 {
			t.Errorf("EnrichWithSystemFields injected Name field %d times, want at most 1", nameCount)
		}
	})
}

// TestEnrichWithSystemFields_IsNameFieldSetForInjectedName verifies that when
// EnrichWithSystemFields injects a default "Name" field for a custom object that
// has no existing IsNameField, the injected field carries IsNameField=true.
//
// This is a regression assertion for scope item 4 of 1079-fix-analytics-heuristic-removal:
// any future change to EnrichWithSystemFields must preserve IsNameField=true on the
// injected Name field so that analytics' metadataNameField() can identify it.
func TestEnrichWithSystemFields_IsNameFieldSetForInjectedName(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: "CustomObject__c",
		Fields:  []models.FieldMetadata{},
	}
	EnrichWithSystemFields(schema, nil)

	nameFieldCount := 0
	var nameFieldIsNameField bool
	for _, f := range schema.Fields {
		if f.APIName == constants.FieldName {
			nameFieldCount++
			nameFieldIsNameField = f.IsNameField
		}
	}

	if nameFieldCount != 1 {
		t.Errorf("EnrichWithSystemFields: expected exactly 1 Name field, got %d", nameFieldCount)
	}
	if !nameFieldIsNameField {
		t.Errorf("EnrichWithSystemFields: injected Name field must have IsNameField=true")
	}
}

// TestEnrichWithSystemFields_ExistingIsNameFieldPreserved verifies that when an object
// already has a field with IsNameField=true (e.g. OrderNumber on Order), EnrichWithSystemFields
// does NOT inject a second Name field.
func TestEnrichWithSystemFields_ExistingIsNameFieldPreserved(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: "Order",
		Fields: []models.FieldMetadata{
			{APIName: "Id", Type: constants.FieldTypeString},
			{APIName: "OrderNumber", Type: constants.FieldTypeAutonumber, IsNameField: true},
		},
	}
	EnrichWithSystemFields(schema, nil)

	nameFieldCount := 0
	isNameFieldCount := 0
	for _, f := range schema.Fields {
		if f.APIName == constants.FieldName {
			nameFieldCount++
		}
		if f.IsNameField {
			isNameFieldCount++
		}
	}

	// No "Name" field should be injected since IsNameField is already set.
	if nameFieldCount != 0 {
		t.Errorf("EnrichWithSystemFields: must not inject Name field when IsNameField already set; got %d Name fields", nameFieldCount)
	}
	// Exactly one IsNameField must remain.
	if isNameFieldCount != 1 {
		t.Errorf("EnrichWithSystemFields: expected exactly 1 IsNameField field, got %d", isNameFieldCount)
	}
}
