package auth

import (
	"reflect"
	"testing"

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

func TestResolveLookupDisplayNameUserBranchUnchanged(t *testing.T) {
	userSchema := &models.ObjectMetadata{
		APIName: constants.TableUser,
		Fields: []models.FieldMetadata{
			{APIName: "Username", Type: constants.FieldTypeString, IsNameField: true},
			{APIName: "Email", Type: constants.FieldTypeEmail, IsNameField: true},
			{APIName: "FirstName", Type: constants.FieldTypeString},
			{APIName: "LastName", Type: constants.FieldTypeString},
			{APIName: "Name", Type: constants.FieldTypeString, IsNameField: true},
		},
	}

	t.Run("full name", func(t *testing.T) {
		rec := models.SObject{
			"Username":  "alice",
			"FirstName": "Alice",
			"LastName":  "Wonderland",
		}
		got := ResolveLookupDisplayName(userSchema, rec)
		if got != "Alice Wonderland" {
			t.Fatalf("expected %q, got %q", "Alice Wonderland", got)
		}
	})

	t.Run("username only", func(t *testing.T) {
		rec := models.SObject{"Username": "bob"}
		got := ResolveLookupDisplayName(userSchema, rec)
		if got != "bob" {
			t.Fatalf("expected %q, got %q", "bob", got)
		}
	})

	t.Run("physical name flags do not compete with identity display", func(t *testing.T) {
		rec := models.SObject{
			"Username":  "barnett.su@example.com",
			"Email":     "contact-address@example.com",
			"FirstName": "Barnett",
			"LastName":  "Su",
			"Name":      "stale-projection",
		}
		got := ResolveLookupDisplayName(userSchema, rec)
		if got != "Barnett Su" {
			t.Fatalf("expected %q, got %q", "Barnett Su", got)
		}
		wantFields := []string{"Username", "FirstName", "LastName"}
		if gotFields := recorddisplay.LookupFieldNames(userSchema); !reflect.DeepEqual(gotFields, wantFields) {
			t.Fatalf("LookupFieldNames(User) = %#v, want %#v", gotFields, wantFields)
		}
	})
}

func TestResolveLookupDisplayNameIsNameFieldIsAuthoritative(t *testing.T) {
	// Contract-like schema: ContractNumber is IsNameField, no Name field declared.
	contractSchema := &models.ObjectMetadata{
		APIName: "Contract",
		Fields: []models.FieldMetadata{
			{APIName: "ContractNumber", Type: constants.FieldTypeString, IsNameField: true},
		},
	}

	t.Run("non-blank name field", func(t *testing.T) {
		rec := models.SObject{"ContractNumber": "CT-001"}
		got := ResolveLookupDisplayName(contractSchema, rec)
		if got != "CT-001" {
			t.Fatalf("expected %q, got %q", "CT-001", got)
		}
	})

	t.Run("blank name field must NOT fall through to orphan Name", func(t *testing.T) {
		rec := models.SObject{"ContractNumber": "", "Name": "stale-orphan"}
		got := ResolveLookupDisplayName(contractSchema, rec)
		if got != "" {
			t.Fatalf("expected empty string, got %q", got)
		}
	})

	t.Run("missing name field must NOT fall through to orphan Name", func(t *testing.T) {
		rec := models.SObject{"Name": "stale-orphan"}
		got := ResolveLookupDisplayName(contractSchema, rec)
		if got != "" {
			t.Fatalf("expected empty string, got %q", got)
		}
	})
}

func TestResolveLookupDisplayNameLegacyNoIsNameField(t *testing.T) {
	// Schema with no IsNameField declared — legacy fallback should fire.
	legacySchema := &models.ObjectMetadata{
		APIName: "LegacyObject",
		Fields: []models.FieldMetadata{
			{APIName: "SomeField", Type: constants.FieldTypeString},
		},
	}

	t.Run("Name present", func(t *testing.T) {
		rec := models.SObject{"Name": "Acme"}
		got := ResolveLookupDisplayName(legacySchema, rec)
		if got != "Acme" {
			t.Fatalf("expected %q, got %q", "Acme", got)
		}
	})

	t.Run("DeveloperName fallback", func(t *testing.T) {
		rec := models.SObject{"DeveloperName": "Sales_Team"}
		got := ResolveLookupDisplayName(legacySchema, rec)
		if got != "Sales_Team" {
			t.Fatalf("expected %q, got %q", "Sales_Team", got)
		}
	})

	t.Run("Username fallback", func(t *testing.T) {
		rec := models.SObject{"Username": "admin"}
		got := ResolveLookupDisplayName(legacySchema, rec)
		if got != "admin" {
			t.Fatalf("expected %q, got %q", "admin", got)
		}
	})

	t.Run("no matching field returns empty", func(t *testing.T) {
		rec := models.SObject{"SomeField": "value"}
		got := ResolveLookupDisplayName(legacySchema, rec)
		if got != "" {
			t.Fatalf("expected empty string, got %q", got)
		}
	})
}

func TestResolveLookupDisplayNameNilSchema(t *testing.T) {
	rec := models.SObject{"Name": "Acme"}
	got := ResolveLookupDisplayName(nil, rec)
	if got != "" {
		t.Fatalf("expected empty string for nil schema, got %q", got)
	}
}

func TestResolveLookupDisplayNameNilRecord(t *testing.T) {
	schema := &models.ObjectMetadata{APIName: "Account"}
	got := ResolveLookupDisplayName(schema, nil)
	if got != "" {
		t.Fatalf("expected empty string for nil record, got %q", got)
	}
}
