package analytics

import (
	"testing"

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

func TestGetLookupDisplayFieldsIncludesUserDisplayParts(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: constants.TableUser,
		Fields: []models.FieldMetadata{
			{APIName: constants.FieldID, IsSystem: true},
			{APIName: constants.FieldName, IsNameField: true},
			{APIName: constants.FieldFirstName},
			{APIName: constants.FieldLastName},
			{APIName: constants.FieldUsername},
		},
	}

	fields := getLookupDisplayFields(schema)
	for _, want := range []string{
		constants.FieldName,
		constants.FieldFirstName,
		constants.FieldLastName,
		constants.FieldUsername,
	} {
		if !utils.ContainsString(fields, want) {
			t.Fatalf("expected %s in lookup display fields: %#v", want, fields)
		}
	}
}

func TestExtractLookupDisplayNameFallsBackToUsername(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: constants.TableUser,
		Fields: []models.FieldMetadata{
			{APIName: constants.FieldID, IsSystem: true},
			{APIName: constants.FieldName, IsNameField: true},
			{APIName: constants.FieldUsername},
		},
	}

	rec := models.SObject{
		constants.FieldID:       "005xx",
		constants.FieldName:     nil,
		constants.FieldUsername: "owner@example.com",
	}

	if got := extractLookupDisplayName(schema, rec); got != "owner@example.com" {
		t.Fatalf("expected username fallback, got %q", got)
	}
}

func TestExtractLookupDisplayNameConstructsUserNameFromFirstAndLast(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: constants.TableUser,
		Fields: []models.FieldMetadata{
			{APIName: constants.FieldID, IsSystem: true},
			{APIName: constants.FieldName, IsNameField: true},
			{APIName: constants.FieldFirstName},
			{APIName: constants.FieldLastName},
			{APIName: constants.FieldUsername},
		},
	}

	rec := models.SObject{
		constants.FieldID:        "005xx",
		constants.FieldName:      nil,
		constants.FieldFirstName: "Selva",
		constants.FieldLastName:  "Ganesh Gopal",
		constants.FieldUsername:  "owner@example.com",
	}

	if got := extractLookupDisplayName(schema, rec); got != "Selva Ganesh Gopal" {
		t.Fatalf("expected constructed user name, got %q", got)
	}
}

func TestBuildQueryFieldsHonorsRequestedFieldsAndResolvesNameSuffix(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: "campaignmember",
		Fields: []models.FieldMetadata{
			{APIName: "Id", IsSystem: true},
			{APIName: "CampaignId", Type: constants.FieldTypeReference, ReferenceTo: []string{"campaign"}},
			{APIName: "LeadId", Type: constants.FieldTypeReference, ReferenceTo: []string{"lead"}},
			{APIName: "ContactId", Type: constants.FieldTypeReference, ReferenceTo: []string{"contact"}},
			{APIName: "LeadOrContactId", Type: constants.FieldTypeReference, ReferenceTo: []string{"lead", "contact"}, IsPolymorphic: true},
			{APIName: "Region__c", Type: constants.FieldTypeFormula},
		},
	}
	visible := []string{"Id", "CampaignId", "LeadId", "ContactId", "LeadOrContactId", "LeadOrContactId_type", "Region__c"}
	req := models.QueryRequest{
		ObjectAPIName: "campaignmember",
		SelectFields:  []string{"Id", "CampaignId", "CampaignId_Name", "LeadId", "LeadId_Name", "ContactId", "ContactId_Name", "Region__c"},
	}

	fields := buildQueryFields(schema, req, visible)

	for _, want := range []string{"Id", "CampaignId", "LeadId", "ContactId", "Region__c"} {
		if !utils.ContainsString(fields, want) {
			t.Fatalf("expected field %s in query fields: %#v", want, fields)
		}
	}
	if utils.ContainsString(fields, "LeadOrContactId_type") {
		t.Fatalf("did not expect polymorphic type helper column when not requested: %#v", fields)
	}
}

func TestBuildQueryFieldsDoesNotNeedMissingPolymorphicTypeColumn(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: "task",
		Fields: []models.FieldMetadata{
			{APIName: "Id", IsSystem: true},
			{APIName: "WhoId", Type: constants.FieldTypeReference, ReferenceTo: []string{"lead", "contact"}, IsPolymorphic: true},
			{APIName: "Region__c", Type: constants.FieldTypeFormula},
		},
	}
	visible := []string{"Id", "WhoId", "Region__c"}
	req := models.QueryRequest{
		ObjectAPIName: "task",
		SelectFields:  []string{"Id", "WhoId", "Region__c"},
	}

	fields := buildQueryFields(schema, req, visible)
	if utils.ContainsString(fields, "WhoId_type") {
		t.Fatalf("did not expect missing polymorphic helper column in query fields: %#v", fields)
	}
}
