package rest

import (
	"context"
	"testing"

	"github.com/nexuscrm/backend/internal/application/services"
	"github.com/nexuscrm/backend/internal/domain/ports"
	"github.com/nexuscrm/backend/internal/features/records"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

type lookupTestRecordRepo struct {
	findMany func(ctx context.Context, tableName string, ids []string) (map[string]models.SObject, error)
}

func (r *lookupTestRecordRepo) Exists(context.Context, string, string) (bool, error) {
	return false, nil
}

func (r *lookupTestRecordRepo) GetLock(context.Context, string, string) (models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) Insert(context.Context, string, models.SObject) error {
	return nil
}

func (r *lookupTestRecordRepo) BulkInsert(context.Context, string, []models.SObject, []string, interface{}) error {
	return nil
}

func (r *lookupTestRecordRepo) BulkInsertWithLanding(_ context.Context, _ string, records []models.SObject, _ []string, _ interface{}) ([]bool, error) {
	landed := make([]bool, len(records))
	for i := range landed {
		landed[i] = true
	}
	return landed, nil
}

func (r *lookupTestRecordRepo) Update(context.Context, string, string, models.SObject) error {
	return nil
}

func (r *lookupTestRecordRepo) Delete(context.Context, string, string) error {
	return nil
}

func (r *lookupTestRecordRepo) GetChildren(context.Context, string, string, string) ([]models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) ExistsByField(context.Context, string, string, interface{}) (bool, error) {
	return false, nil
}

func (r *lookupTestRecordRepo) FindOne(context.Context, string, string) (models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) FindMany(ctx context.Context, tableName string, ids []string) (map[string]models.SObject, error) {
	if r.findMany != nil {
		return r.findMany(ctx, tableName, ids)
	}
	return map[string]models.SObject{}, nil
}

func (r *lookupTestRecordRepo) FindOneByField(context.Context, string, string, interface{}) (models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) FindAny(context.Context, string, string) (models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) PhysicalDelete(context.Context, string, string) error {
	return nil
}

func (r *lookupTestRecordRepo) DeleteByField(context.Context, string, string, interface{}) error {
	return nil
}

func (r *lookupTestRecordRepo) CheckUniqueness(context.Context, *models.ObjectMetadata, string, interface{}, string) (bool, error) {
	return false, nil
}

func (r *lookupTestRecordRepo) FindRecycleBinItemsByUser(context.Context, string) ([]models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) FindAllRecycleBinItems(context.Context) ([]models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) FindRecycleBinEntry(context.Context, string) (models.SObject, error) {
	return nil, nil
}

func (r *lookupTestRecordRepo) CheckQueueSupport(context.Context, string, string) (bool, error) {
	return false, nil
}

func (r *lookupTestRecordRepo) GetRecordType(context.Context, string) (string, error) {
	return "", nil
}

func (r *lookupTestRecordRepo) FindObjectTypesForIDs(context.Context, []string, []string) (map[string]string, error) {
	return nil, nil
}

var _ ports.RecordRepository = (*lookupTestRecordRepo)(nil)

func TestHydrateQueryLookupsBatch_ConstructsUserDisplayName(t *testing.T) {
	repo := &lookupTestRecordRepo{
		findMany: func(_ context.Context, tableName string, ids []string) (map[string]models.SObject, error) {
			if tableName != constants.TableUser {
				t.Fatalf("expected lookup table %s, got %s", constants.TableUser, tableName)
			}
			if len(ids) != 1 || ids[0] != "005-user" {
				t.Fatalf("unexpected lookup ids: %#v", ids)
			}
			return map[string]models.SObject{
				"005-user": {
					constants.FieldID:        "005-user",
					constants.FieldFirstName: "Selva",
					constants.FieldLastName:  "Ganesh Gopal",
					constants.FieldUsername:  "selva.ganesh@pingcap.com",
				},
			}, nil
		},
	}

	handler := &QueryHandler{
		svcMgr: &services.ServiceManager{
			Persistence: records.NewPersistenceService(repo, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil),
		},
	}

	schema := &models.ObjectMetadata{
		APIName: "CampaignMemberStatus",
		Fields: []models.FieldMetadata{
			{
				APIName:     constants.FieldCreatedByID,
				Type:        constants.FieldTypeReference,
				ReferenceTo: []string{constants.TableUser},
			},
		},
	}

	rows := []models.SObject{
		{
			constants.FieldID:          "01Y-status",
			constants.FieldCreatedByID: "005-user",
		},
	}

	user := &models.UserSession{ID: "test-user", IsSystemAdmin: true}
	handler.hydrateQueryLookupsBatch(context.Background(), schema, rows, user)

	if got := rows[0][constants.FieldCreatedByID+"_Name"]; got != "Selva Ganesh Gopal" {
		t.Fatalf("expected constructed user display name, got %#v", got)
	}
}
