//go:build integration

package rest_test

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/nexuscrm/backend/internal/application/services"
	"github.com/nexuscrm/backend/internal/bootstrap"
	"github.com/nexuscrm/backend/internal/features/analytics"
	"github.com/nexuscrm/backend/internal/features/events"
	"github.com/nexuscrm/backend/internal/features/metadata"
	"github.com/nexuscrm/backend/internal/features/permissions"
	"github.com/nexuscrm/backend/internal/features/records"
	"github.com/nexuscrm/backend/internal/infrastructure/database"
	"github.com/nexuscrm/backend/internal/infrastructure/persistence"
	"github.com/nexuscrm/backend/internal/interfaces/rest"
	"github.com/nexuscrm/backend/pkg/auth"
	"github.com/nexuscrm/backend/pkg/formula"
	"github.com/nexuscrm/backend/pkg/logging"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// =============================================================================
// Test Helpers
// =============================================================================

type TestHandlers struct {
	System              *rest.SystemHandler
	SObject             *rest.SObjectHandler
	Query               *rest.QueryHandler
	Search              *rest.SearchHandler
	Composite           *rest.CompositeHandler
	CompositeCollection *rest.CompositeCollectionsHandler
}

func GetTestUser(id string, profileId string) *models.UserSession {
	return &models.UserSession{
		ID:            id,
		ProfileID:     profileId,
		IsSystemAdmin: profileId == constants.ProfileSystemAdmin,
	}
}

// SetupHandlerHelper initializes the ServiceManager and Handler for testing
func SetupHandlerHelper(t *testing.T) (*services.ServiceManager, TestHandlers, *gin.Engine) {
	conn, metadataSvc := records.SetupIntegrationTest(t)
	db := conn.DB()

	// Bootstrap
	err := bootstrap.InitializeSchema(conn)
	require.NoError(t, err, "Bootstrap failed")

	// Assemble Dependencies
	recordRepo := persistence.NewRecordRepository(db)
	userRepo := persistence.NewUserRepository(db)
	permRepo := persistence.NewPermissionRepository(db)
	rollupRepo := persistence.NewRollupRepository(db)
	txManager := persistence.NewTransactionManager(conn)
	outboxRepo := persistence.NewOutboxRepository(db)
	queryRepo := persistence.NewQueryRepository(db)

	// Services
	permSvc := permissions.NewPermissionService(permRepo, metadataSvc, userRepo)
	rollupSvc := analytics.NewRollupService(rollupRepo, metadataSvc, txManager, logging.New(context.Background()))
	eventBus := events.NewEventBus()
	outboxSvc := events.NewOutboxService(outboxRepo, eventBus, txManager)
	validationSvc := metadata.NewValidationService(formula.NewEngine())

	// Core Persistence
	ps := records.NewPersistenceService(recordRepo, rollupSvc, metadataSvc, permSvc, eventBus, validationSvc, txManager, outboxSvc, logging.New(context.Background()), nil, nil, nil, nil)

	// Query Service
	querySvc := analytics.NewQueryService(queryRepo, metadataSvc, permSvc, logging.New(context.Background()))

	// System Service
	systemRepo := persistence.NewSystemRepository(db)
	systemSvc := services.NewSystemManager(ps, systemRepo)

	// Construct ServiceManager
	sm := &services.ServiceManager{
		Metadata:    metadataSvc,
		Persistence: ps,
		Permissions: permSvc,
		QuerySvc:    querySvc,
		System:      systemSvc,
	}

	// Setup Router (Initialized BEFORE handlers to allow injection)
	gin.SetMode(gin.TestMode)
	r := gin.New()

	// Middleware to inject User (Mock Auth)
	r.Use(func(c *gin.Context) {
		c.Set(constants.ContextKeyUser, auth.UserSession{
			ID:        "test-admin",
			Name:      "Test Admin",
			ProfileId: constants.ProfileSystemAdmin,
			Email:     "admin@test.com",
		})
		c.Next()
	})

	// Create Handlers
	handlers := TestHandlers{
		System:              rest.NewSystemHandler(sm),
		SObject:             rest.NewSObjectHandler(sm, nil),
		Query:               rest.NewQueryHandler(sm),
		Search:              rest.NewSearchHandler(sm),
		Composite:           rest.NewCompositeHandler(r),
		CompositeCollection: rest.NewCompositeCollectionsHandler(sm.Persistence, sm.Metadata),
	}

	return sm, handlers, r
}

// assertSalesforceError validates SF-style error format
func assertSalesforceError(t *testing.T, body []byte, expectedCode string) {
	var resp []map[string]interface{}
	require.NoError(t, json.Unmarshal(body, &resp))
	require.NotEmpty(t, resp, "Error response should not be empty")
	assert.Equal(t, expectedCode, resp[0]["errorCode"], "Error code mismatch")
	assert.NotEmpty(t, resp[0]["message"], "Error message should not be empty")
}

// assertRecordAttributes validates record has SF-style attributes
func assertRecordAttributes(t *testing.T, record map[string]interface{}, objectName string) {
	attrs, ok := record["attributes"].(map[string]interface{})
	require.True(t, ok, "Record should have attributes")
	assert.Equal(t, objectName, attrs["type"])
	assert.Contains(t, attrs["url"].(string), objectName)
}

// =============================================================================
// SObject API Tests - List Objects
// =============================================================================

func TestSystemHandler_ListObjects(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)

	// Register Route
	r.GET("/services/data/v63.0/sobjects", handlers.SObject.ListObjects)

	// Create a Custom Object to verify it appears
	ctx := context.Background()
	uniq := fmt.Sprintf("obj_%d", time.Now().UnixNano())
	objMeta := &models.ObjectMetadata{
		APIName:  uniq,
		Label:    "Integration Test Object " + uniq,
		IsCustom: true,
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, objMeta))
	sm.Metadata.RefreshCache(ctx)

	// Execute Request
	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/sobjects", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert Response
	assert.Equal(t, http.StatusOK, w.Code)

	var response map[string]interface{}
	err := json.Unmarshal(w.Body.Bytes(), &response)
	require.NoError(t, err)

	// Verify Structure - Salesforce compatibility fields
	assert.Equal(t, "UTF-8", response["encoding"], "Should have encoding field")
	assert.NotNil(t, response["maxBatchSize"], "Should have maxBatchSize field")

	sobjects, ok := response["sobjects"].([]interface{})
	require.True(t, ok, "response should contain 'sobjects' array")

	found := false
	for _, raw := range sobjects {
		s := raw.(map[string]interface{})
		if s["name"] == uniq {
			found = true
			assert.Equal(t, "Integration Test Object "+uniq, s["label"])
			assert.Equal(t, true, s["custom"])
			assert.Equal(t, true, s["queryable"])
			// Verify additional SF compatibility fields
			assert.NotNil(t, s["createable"])
			assert.NotNil(t, s["deletable"])
			assert.NotNil(t, s["updateable"])
			assert.NotNil(t, s["retrieveable"])
			break
		}
	}
	assert.True(t, found, "Created object should be listed")
}

// =============================================================================
// SObject API Tests - Describe Object
// =============================================================================

func TestSystemHandler_DescribeObject(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe", handlers.SObject.DescribeObject)

	// Create Schema with fields
	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("describe_test_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Describe Test %d", unix),
		PathField: func() *string {
			v := "Name"
			return &v
		}(),
		Fields: []models.FieldMetadata{
			{APIName: "Name", Type: constants.FieldTypeString, Label: "Name", IsNameField: true},
			{APIName: "Amount", Type: constants.FieldTypeCurrency, Label: "Amount"},
			{APIName: "IsActive", Type: constants.FieldTypeBoolean, Label: "Active"},
		},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	// Execute
	req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/%s/describe", objName), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))

	// Verify Salesforce-compatible response structure
	assert.Equal(t, objName, resp["name"])
	require.Equal(t, fmt.Sprintf("Describe Test %d", unix), resp["label"])
	assert.Equal(t, "Name", resp["pathField"])
	assert.NotNil(t, resp["createable"])
	assert.NotNil(t, resp["updateable"])
	assert.NotNil(t, resp["deletable"])
	assert.NotNil(t, resp["queryable"])

	// Verify Fields array
	fields, ok := resp["fields"].([]interface{})
	require.True(t, ok)
	assert.GreaterOrEqual(t, len(fields), 3, "Should have at least 3 fields")

	// Verify field structure matches SF format
	foundName := false
	for _, f := range fields {
		field := f.(map[string]interface{})
		if field["name"] == "Name" {
			foundName = true
			assert.Equal(t, "Name", field["label"])
			assert.Equal(t, "string", field["type"]) // SF type mapping
			assert.NotNil(t, field["createable"])
			assert.NotNil(t, field["updateable"])
			assert.NotNil(t, field["nillable"])
		}
	}
	assert.True(t, foundName, "Should have name field")

	// Verify URLs
	urls, ok := resp["urls"].(map[string]interface{})
	require.True(t, ok)
	assert.Contains(t, urls["sobject"].(string), objName)
	assert.Contains(t, urls["rowTemplate"].(string), objName)
}

func TestSystemHandler_DescribeObject_SystemFile(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe", handlers.SObject.DescribeObject)

	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/sobjects/_System_File/describe", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal(t, "_System_File", resp["name"])
	assert.Equal(t, "File attachments", resp["label"])
}

func TestSystemHandler_DescribeObject_SystemFile_WithCompatibilityAliasRoutes(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/_System_File/describe", func(c *gin.Context) {
		c.Params = append(c.Params, gin.Param{Key: "sobject", Value: "_System_File"})
		handlers.SObject.DescribeObject(c)
	})
	r.GET("/services/data/v63.0/sobjects/_System_File/:id/download", func(c *gin.Context) {
		c.Status(http.StatusNoContent)
	})
	r.DELETE("/services/data/v63.0/sobjects/_System_File/:id", func(c *gin.Context) {
		c.Status(http.StatusNoContent)
	})
	r.GET("/services/data/v63.0/sobjects/:sobject/describe", handlers.SObject.DescribeObject)

	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/sobjects/_System_File/describe", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal(t, "_System_File", resp["name"])
}

func TestSystemHandler_DescribeObject_NotFound(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe", handlers.SObject.DescribeObject)

	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/sobjects/nonexistent_object_xyz/describe", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusNotFound, w.Code)
	assertSalesforceError(t, w.Body.Bytes(), "NOT_FOUND")
}

// =============================================================================
// SObject API Tests - Describe Layouts
// =============================================================================

func TestSystemHandler_DescribeLayouts(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe/layouts", handlers.SObject.DescribeLayouts)

	// Create Schema
	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("layout_test_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Layout Test %d", unix),
		Fields: []models.FieldMetadata{
			{APIName: "Name", Type: constants.FieldTypeString, Label: "Name", IsNameField: true},
			{APIName: "Status", Type: constants.FieldTypeString, Label: "Status"},
		},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	// Execute
	req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/%s/describe/layouts", objName), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))

	// Salesforce parity: global describe/layouts returns null layouts
	assert.Nil(t, resp["layouts"], "Global describe/layouts should return null layouts (Salesforce parity)")

	// Salesforce parity: recordTypeMappings populated with Master record type
	mappings, ok := resp["recordTypeMappings"].([]interface{})
	require.True(t, ok, "Should have recordTypeMappings array")
	require.Len(t, mappings, 1, "Should have exactly one record type mapping (Master)")

	mapping := mappings[0].(map[string]interface{})
	assert.Equal(t, true, mapping["defaultRecordTypeMapping"], "Should be default mapping")
	assert.Equal(t, "012000000000000AAA", mapping["recordTypeId"], "Should use Master record type ID")
	assert.Equal(t, true, mapping["master"], "Should be marked as master")
	assert.NotEmpty(t, mapping["layoutId"], "Should have layoutId")

	assert.Equal(t, false, resp["recordTypeSelectorRequired"])
}

func TestSystemHandler_DescribeLayoutByRecordType(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe/layouts/:recordTypeId", handlers.SObject.DescribeLayoutByRecordType)

	// Create Schema
	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("layout_rt_test_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Layout RT Test %d", unix),
		Fields: []models.FieldMetadata{
			{APIName: "Name", Type: constants.FieldTypeString, Label: "Name", IsNameField: true},
			{APIName: "Status", Type: constants.FieldTypeString, Label: "Status"},
		},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	// Execute - use Master record type ID
	req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/%s/describe/layouts/012000000000000AAA", objName), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)

	var layout map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &layout))

	// Salesforce parity: specific layout endpoint returns layout directly (not wrapped in array).
	// The resolver now prefers the persisted default layout row, so assert against the
	// object's stored default layout ID rather than the old synthetic id format.
	layouts, err := sm.Metadata.GetAllLayouts(ctx, objName)
	require.NoError(t, err)
	require.NotEmpty(t, layouts, "object should have a persisted default layout")
	assert.Equal(t, layouts[0].ID, layout["id"])

	// Verify SF compatibility fields
	assert.NotNil(t, layout["detailLayoutSections"], "Should have detailLayoutSections")
	assert.NotNil(t, layout["editLayoutSections"], "Should have editLayoutSections")

	// Verify sections (Nexus compatibility)
	sections, ok := layout["sections"].([]interface{})
	require.True(t, ok, "Should have 'sections' field")
	assert.NotEmpty(t, sections)

	section0 := sections[0].(map[string]interface{})
	fields := section0["fields"].([]interface{})
	assert.GreaterOrEqual(t, len(fields), 2)
	assert.Contains(t, fields, "Name")

	// Verify relatedLists exists (empty for fresh objects with no child relationships)
	relatedLists, ok := layout["relatedLists"].([]interface{})
	require.True(t, ok, "Should have 'relatedLists' field")
	assert.Empty(t, relatedLists)
}

// =============================================================================
// SObject API Tests - CRUD Operations
// =============================================================================

func TestSystemHandler_CreateRecord(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.POST("/services/data/v63.0/sobjects/:sobject", handlers.SObject.CreateRecord)

	// Create Schema
	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("account_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Account API Test %d", unix),
		Fields: []models.FieldMetadata{
			{APIName: "Name", Type: constants.FieldTypeString, IsNameField: true},
		},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	// Payload
	payload := map[string]interface{}{
		"Name": "API Created Account",
	}
	body, _ := json.Marshal(payload)

	// Execute
	req, _ := http.NewRequest(http.MethodPost, "/services/data/v63.0/sobjects/"+objName, bytes.NewBuffer(body))
	req.Header.Set("Content-Type", "application/json")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert - Salesforce returns 201 with id, success, errors
	assert.Equal(t, http.StatusCreated, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
	assert.True(t, resp["success"].(bool), "success should be true")
	assert.NotEmpty(t, resp["id"], "id should not be empty")
	errors, ok := resp["errors"].([]interface{})
	require.True(t, ok)
	assert.Empty(t, errors, "errors should be empty on success")
}

func TestSystemHandler_CreateTaskWeeklyUpdateWithOpportunityWhatId(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.POST("/services/data/v63.0/sobjects/:sobject", handlers.SObject.CreateRecord)
	r.GET("/services/data/v63.0/sobjects/:sobject/:id", handlers.SObject.GetRecord)

	ctx := context.Background()

	opportunityMeta := &models.ObjectMetadata{
		APIName: "Opportunity",
		Label:   "Opportunity",
		Fields: []models.FieldMetadata{
			{APIName: "Name", Label: "Opportunity Name", Type: constants.FieldTypeString, Required: true, IsNameField: true},
			{APIName: "StageName", Label: "Stage", Type: constants.FieldTypeString, Required: true},
			{APIName: "CloseDate", Label: "Close Date", Type: constants.FieldTypeDate, Required: true},
		},
	}
	if err := sm.Metadata.CreateSchema(ctx, opportunityMeta); err != nil {
		t.Logf("Opportunity schema already exists or create error (non-fatal): %v", err)
	}

	taskMeta := &models.ObjectMetadata{
		APIName: "Task",
		Label:   "Task",
		Fields: []models.FieldMetadata{
			{APIName: "Subject", Label: "Subject", Type: constants.FieldTypeString, Required: true, IsNameField: true},
			{APIName: "Status", Label: "Status", Type: constants.FieldTypeString},
			{APIName: "ActivityDate", Label: "Date", Type: constants.FieldTypeDate},
			{APIName: "Type", Label: "Type", Type: constants.FieldTypeString},
			{
				APIName:       "WhatId",
				Label:         "Related To",
				Type:          constants.FieldTypeReference,
				ReferenceTo:   []string{"Account", "Opportunity"},
				IsPolymorphic: true,
			},
		},
	}
	if err := sm.Metadata.CreateSchema(ctx, taskMeta); err != nil {
		t.Logf("Task schema already exists or create error (non-fatal): %v", err)
	}
	require.NoError(t, sm.Metadata.RefreshCache(ctx))

	opportunity, err := sm.Persistence.Insert(ctx, "Opportunity", models.SObject{
		"Name":      "Issue 332 Integration Opportunity",
		"StageName": "Prospecting",
		"CloseDate": "2026-12-31",
	}, GetTestUser("test-admin", constants.ProfileSystemAdmin))
	require.NoError(t, err)

	payload := map[string]interface{}{
		"Subject":      "Weekly Update",
		"Status":       "Completed",
		"Type":         "Other",
		"ActivityDate": "2026-04-02",
		"WhatId":       opportunity[constants.FieldID],
	}
	body, err := json.Marshal(payload)
	require.NoError(t, err)

	req, _ := http.NewRequest(http.MethodPost, "/services/data/v63.0/sobjects/Task", bytes.NewBuffer(body))
	req.Header.Set("Content-Type", "application/json")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusCreated, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal(t, true, resp["success"])
	taskID, ok := resp["id"].(string)
	require.True(t, ok)
	assert.NotEmpty(t, taskID)

	savedTask, err := sm.Persistence.GetRaw(ctx, "Task", taskID)
	require.NoError(t, err)
	require.NotNil(t, savedTask)
	assert.Equal(t, opportunity[constants.FieldID], savedTask["WhatId"])

	reqGet, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/Opportunity/%s", opportunity[constants.FieldID]), nil)
	wGet := httptest.NewRecorder()
	r.ServeHTTP(wGet, reqGet)

	assert.Equal(t, http.StatusOK, wGet.Code)

	var getResp map[string]interface{}
	require.NoError(t, json.Unmarshal(wGet.Body.Bytes(), &getResp))
	assert.Equal(t, "2026-12-31", getResp["CloseDate"])
}

func TestSystemHandler_CreateRecord_ValidationError(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.POST("/services/data/v63.0/sobjects/:sobject", handlers.SObject.CreateRecord)

	// Use Group (Queue) which has validation
	payload := map[string]interface{}{
		"InvalidField": "ShouldFail",
	}
	body, _ := json.Marshal(payload)

	req, _ := http.NewRequest(http.MethodPost, "/services/data/v63.0/sobjects/"+constants.TableGroup, bytes.NewBuffer(body))
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusBadRequest, w.Code)
	assertSalesforceError(t, w.Body.Bytes(), "INVALID_FIELD")
}

func TestSystemHandler_GetRecord(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/:id", handlers.SObject.GetRecord)

	// Pre-seed record
	ctx := context.Background()
	objName := constants.TableGroup
	unix := time.Now().UnixNano()
	name := fmt.Sprintf("GetTest_%d", unix)
	rec := models.SObject{
		"Name":  name,
		"Label": fmt.Sprintf("Get Test %d", unix),
		"Type":  "Queue",
		"Email": fmt.Sprintf("get_%d@test.com", unix),
	}
	saved, err := sm.Persistence.Insert(ctx, objName, rec, GetTestUser("test-admin", constants.ProfileSystemAdmin))
	require.NoError(t, err)
	id := saved[constants.FieldID].(string)

	// Execute
	req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/%s/%s", objName, id), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)
	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal(t, name, resp["Name"])
	assert.Equal(t, id, resp["Id"]) // Salesforce uses capital Id

	// Verify Attributes - SF compatibility
	assertRecordAttributes(t, resp, objName)
}

func TestSystemHandler_GetRecord_NotFound(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/:id", handlers.SObject.GetRecord)

	req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/%s/nonexistent_id_xyz", constants.TableGroup), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusNotFound, w.Code)
	assertSalesforceError(t, w.Body.Bytes(), "NOT_FOUND")
}

func TestSystemHandler_UpdateRecord(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.PATCH("/services/data/v63.0/sobjects/:sobject/:id", handlers.SObject.UpdateRecord)

	// Pre-seed record
	ctx := context.Background()
	objName := constants.TableGroup
	unix := time.Now().UnixNano()
	rec := models.SObject{
		"Name":  fmt.Sprintf("UpdateTest_%d", unix),
		"Label": fmt.Sprintf("Update Test Original %d", unix),
		"Type":  "Queue",
		"Email": fmt.Sprintf("update_%d@test.com", unix),
	}
	saved, err := sm.Persistence.Insert(ctx, objName, rec, GetTestUser("test-admin", constants.ProfileSystemAdmin))
	require.NoError(t, err)
	id := saved[constants.FieldID].(string)

	// Update payload
	updatePayload := map[string]interface{}{
		"Label": fmt.Sprintf("Update Test Modified %d", unix),
	}
	body, _ := json.Marshal(updatePayload)

	// Execute
	req, _ := http.NewRequest(http.MethodPatch, fmt.Sprintf("/services/data/v63.0/sobjects/%s/%s", objName, id), bytes.NewBuffer(body))
	req.Header.Set("Content-Type", "application/json")
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert - SF returns 204 No Content on success
	assert.Equal(t, http.StatusNoContent, w.Code)
	assert.Empty(t, w.Body.Bytes())
}

func TestSystemHandler_DeleteRecord(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.DELETE("/services/data/v63.0/sobjects/:sobject/:id", handlers.SObject.DeleteRecord)

	// Pre-seed record
	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("delete_test_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Delete Test %d", unix),
		Fields:  []models.FieldMetadata{{APIName: "Name", Type: constants.FieldTypeString, IsNameField: true}},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	rec := models.SObject{"Name": "ToDelete"}
	saved, err := sm.Persistence.Insert(ctx, objName, rec, GetTestUser("test-admin", constants.ProfileSystemAdmin))
	require.NoError(t, err)
	id := saved[constants.FieldID].(string)

	// Execute
	req, _ := http.NewRequest(http.MethodDelete, fmt.Sprintf("/services/data/v63.0/sobjects/%s/%s", objName, id), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert - SF returns 204 No Content on success
	assert.Equal(t, http.StatusNoContent, w.Code)
}

// =============================================================================
// Query API Tests
// =============================================================================

func TestSystemHandler_ExecuteQuery(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/query", handlers.Query.ExecuteQuery)

	// Pre-seed
	objName := constants.TableGroup
	unix := time.Now().UnixNano()
	name := fmt.Sprintf("QueryTarget_%d", unix)
	rec := models.SObject{
		"Name":  name,
		"Label": fmt.Sprintf("Query Target %d", unix),
		"Type":  "Regular",
		"Email": fmt.Sprintf("query_%d@test.com", unix),
	}
	saved, err := sm.Persistence.Insert(context.Background(), objName, rec, GetTestUser("test-admin", constants.ProfileSystemAdmin))
	require.NoError(t, err, "Setup Insert failed")
	targetID := saved[constants.FieldID].(string)

	// Query
	q := fmt.Sprintf("SELECT id, name FROM %s WHERE name = '%s'", objName, name)
	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/query?q="+q, nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)
	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))

	// Verify SF response structure
	assert.Equal(t, float64(1), resp["totalSize"])
	assert.NotNil(t, resp["done"])
	records := resp["records"].([]interface{})
	assert.Len(t, records, 1)
	rec0 := records[0].(map[string]interface{})
	assert.Equal(t, name, rec0["Name"])
	// Check Id (PascalCase) or id (lowercase)
	if val, ok := rec0["Id"]; ok {
		assert.Equal(t, targetID, val)
	} else if val, ok := rec0["id"]; ok {
		assert.Equal(t, targetID, val)
	} else {
		t.Logf("Query result keys: %v", rec0)
		assert.Fail(t, "Id not found in record")
	}

	// Verify record has attributes
	assertRecordAttributes(t, rec0, objName)
}

func TestSystemHandler_ExecuteQuery_MalformedSOQL(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/query", handlers.Query.ExecuteQuery)

	// Invalid SOQL
	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/query?q=INVALID SOQL SYNTAX", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusBadRequest, w.Code)
	assertSalesforceError(t, w.Body.Bytes(), "MALFORMED_QUERY")
}

func TestSystemHandler_ExecuteQuery_MissingQ(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/query", handlers.Query.ExecuteQuery)

	// No q parameter
	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/query", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusBadRequest, w.Code)
}

func TestSystemHandler_ExecuteQueryAll(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/queryAll", handlers.Query.ExecuteQueryAll)

	// Create and delete a record to test queryAll includes deleted
	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("queryall_test_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("QueryAll Test %d", unix),
		Fields:  []models.FieldMetadata{{APIName: "Name", Type: constants.FieldTypeString, IsNameField: true}},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	name := fmt.Sprintf("QueryAllTarget_%d", unix)
	rec := models.SObject{"Name": name}
	saved, err := sm.Persistence.Insert(ctx, objName, rec, GetTestUser("test-admin", constants.ProfileSystemAdmin))
	require.NoError(t, err)

	// Query with queryAll
	q := fmt.Sprintf("SELECT id, name FROM %s WHERE name = '%s'", objName, name)
	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/queryAll?q="+q, nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)
	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal(t, float64(1), resp["totalSize"])
	records := resp["records"].([]interface{})
	assert.Len(t, records, 1)
	record := records[0].(map[string]interface{})
	if val, ok := record["Id"]; ok {
		assert.Equal(t, saved[constants.FieldID], val)
	} else if val, ok := record["id"]; ok {
		assert.Equal(t, saved[constants.FieldID], val)
	} else {
		t.Logf("QueryAll result keys: %v", record)
		assert.Fail(t, "Id not found in record")
	}
}

// =============================================================================
// Identity API Tests
// =============================================================================

func TestSystemHandler_GetIdentity(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/id/:orgId/:userId", handlers.System.GetIdentity)

	// Execute with "me" to get current user identity
	req, _ := http.NewRequest(http.MethodGet, "/id/00D000000000001/me", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))

	// Verify SF Identity response structure
	assert.NotEmpty(t, resp["id"])
	assert.Equal(t, true, resp["asserted_user"])
	assert.NotEmpty(t, resp["user_id"])
	assert.Equal(t, "00D000000000001", resp["organization_id"])
	assert.NotEmpty(t, resp["username"])
	assert.NotEmpty(t, resp["display_name"])
	assert.NotEmpty(t, resp["email"])
	assert.Equal(t, true, resp["active"])

	// Verify URLs
	urls, ok := resp["urls"].(map[string]interface{})
	require.True(t, ok)
	assert.NotEmpty(t, urls["sobjects"])
	assert.NotEmpty(t, urls["query"])
	assert.NotEmpty(t, urls["search"])
	assert.NotEmpty(t, urls["rest"])
}

func TestSystemHandler_GetIdentity_SpecificUser(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/id/:orgId/:userId", handlers.System.GetIdentity)

	// As admin, can access own identity
	req, _ := http.NewRequest(http.MethodGet, "/id/00D000000000001/test-admin", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
	assert.Equal(t, "test-admin", resp["user_id"])
}

// =============================================================================
// ListResources API Test
// =============================================================================

func TestSystemHandler_ListResources(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/:version/", handlers.System.ListResources)

	req, _ := http.NewRequest(http.MethodGet, "/services/data/v63.0/", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))

	// Verify SF resource list
	assert.Contains(t, resp["sobjects"].(string), "sobjects")
	assert.Contains(t, resp["query"].(string), "query")
	assert.Contains(t, resp["search"].(string), "search")
	assert.NotEmpty(t, resp["identity"])
}

// =============================================================================
// Response Format Consistency Tests
// =============================================================================

func TestSystemHandler_ErrorFormat_Consistency(t *testing.T) {
	_, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe", handlers.SObject.DescribeObject)
	r.GET("/services/data/v63.0/sobjects/:sobject/:id", handlers.SObject.GetRecord)

	testCases := []struct {
		name         string
		url          string
		expectedCode string
	}{
		{"DescribeNotFound", "/services/data/v63.0/sobjects/nonexistent/describe", "NOT_FOUND"},
		{"GetRecordNotFound", "/services/data/v63.0/sobjects/_System_Group/bad_id", "NOT_FOUND"},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			req, _ := http.NewRequest(http.MethodGet, tc.url, nil)
			w := httptest.NewRecorder()
			r.ServeHTTP(w, req)

			var resp []map[string]interface{}
			require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
			require.NotEmpty(t, resp, "Error response should not be empty")

			// All errors should have errorCode and message
			assert.Equal(t, tc.expectedCode, resp[0]["errorCode"], "Should have correct errorCode")
			assert.NotEmpty(t, resp[0]["message"], "Should have message")
		})
	}
}

// =============================================================================
// Multi-Record-Type Layout Tests (Issue #193)
// =============================================================================

// TestSystemHandler_DescribeLayouts_MultiRecordType verifies that custom record types
// appear in recordTypeMappings alongside the Master type.
func TestSystemHandler_DescribeLayouts_MultiRecordType(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe/layouts", handlers.SObject.DescribeLayouts)

	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("layout_mrt_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Layout MRT %d", unix),
		Fields: []models.FieldMetadata{
			{APIName: "Name", Type: constants.FieldTypeString, Label: "Name", IsNameField: true},
			{APIName: "Status", Type: constants.FieldTypeString, Label: "Status"},
		},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	// Look up the object ID that CreateSchema assigned
	conn, err := database.GetInstance()
	require.NoError(t, err)
	db := conn.DB()

	var objectID string
	err = db.QueryRowContext(ctx,
		fmt.Sprintf("SELECT `%s` FROM `%s` WHERE `%s` = ?", constants.FieldID, constants.TableObject, constants.FieldSysObject_APIName),
		objName,
	).Scan(&objectID)
	require.NoError(t, err, "Object must exist after CreateSchema")

	// Insert two custom record types
	rtIDA := fmt.Sprintf("012_rt_a_%d", unix)
	rtIDB := fmt.Sprintf("012_rt_b_%d", unix)
	insertRT := fmt.Sprintf("INSERT INTO `%s` (`%s`, `%s`, `%s`, `%s`, `%s`, `CreatedDate`, `LastModifiedDate`) VALUES (?, ?, ?, ?, ?, NOW(), NOW())",
		constants.TableRecordType, constants.FieldID, constants.FieldObjectID, constants.FieldSysRecordType_Name, constants.FieldSysRecordType_IsActive, constants.FieldSysRecordType_IsMaster)
	_, err = db.ExecContext(ctx, insertRT, rtIDA, objectID, "Type_A", 1, 0)
	require.NoError(t, err)
	_, err = db.ExecContext(ctx, insertRT, rtIDB, objectID, "Type_B", 1, 0)
	require.NoError(t, err)
	defer func() {
		db.ExecContext(ctx, fmt.Sprintf("DELETE FROM `%s` WHERE `%s` IN (?, ?)", constants.TableRecordType, constants.FieldID), rtIDA, rtIDB)
	}()

	// Execute
	req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/%s/describe/layouts", objName), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)

	var resp map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))

	assert.Nil(t, resp["layouts"], "Global describe/layouts should return null layouts")

	mappings, ok := resp["recordTypeMappings"].([]interface{})
	require.True(t, ok, "Should have recordTypeMappings array")
	require.Len(t, mappings, 3, "Should have 3 mappings: Master + Type_A + Type_B")

	// Master should be present but not default when custom types exist
	master := mappings[0].(map[string]interface{})
	assert.Equal(t, "012000000000000AAA", master["recordTypeId"])
	assert.Equal(t, true, master["master"])
	assert.Equal(t, false, master["defaultRecordTypeMapping"], "Master should not be default when custom types exist")

	// Exactly one mapping should be the default
	defaultCount := 0
	foundNames := map[string]bool{}
	for _, m := range mappings {
		mm := m.(map[string]interface{})
		assert.NotEmpty(t, mm["layoutId"], "Every mapping must have a layoutId")
		assert.Equal(t, true, mm["active"])
		if mm["defaultRecordTypeMapping"] == true {
			defaultCount++
		}
		foundNames[mm["name"].(string)] = true
	}
	assert.Equal(t, 1, defaultCount, "Exactly one mapping should be the default")
	assert.True(t, foundNames["Type_A"], "Type_A should be present")
	assert.True(t, foundNames["Type_B"], "Type_B should be present")

	// recordTypeSelectorRequired should be true when multiple record types exist
	assert.Equal(t, true, resp["recordTypeSelectorRequired"], "Should require selector with multiple record types")
}

// TestSystemHandler_DescribeLayoutByRecordType_StoredLayout verifies that a stored
// layout is returned instead of a schema-generated one.
func TestSystemHandler_DescribeLayoutByRecordType_StoredLayout(t *testing.T) {
	sm, handlers, r := SetupHandlerHelper(t)
	r.GET("/services/data/v63.0/sobjects/:sobject/describe/layouts/:recordTypeId", handlers.SObject.DescribeLayoutByRecordType)

	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("layout_stored_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Layout Stored %d", unix),
		Fields: []models.FieldMetadata{
			{APIName: "Name", Type: constants.FieldTypeString, Label: "Name", IsNameField: true},
			{APIName: "Status", Type: constants.FieldTypeString, Label: "Status"},
			{APIName: "Amount", Type: constants.FieldTypeCurrency, Label: "Amount"},
		},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	// Store a custom layout with specific sections
	layoutID := fmt.Sprintf("custom_layout_%d", unix)
	customLayout := &models.PageLayout{
		ID:            layoutID,
		ObjectAPIName: objName,
		LayoutName:    "Custom Test Layout",
		IsDefault:     true,
		IsCustomized:  true,
		Source:        "admin_created",
		LayoutVersion: 2,
		Sections: []models.PageSection{
			{ID: "s1", Label: "Key Information", Columns: 2, Fields: []string{"Name"}},
			{ID: "s2", Label: "Financial Details", Columns: 1, Fields: []string{"Amount"}},
		},
	}
	require.NoError(t, sm.Metadata.SaveLayout(ctx, customLayout))
	defer func() {
		sm.Metadata.DeleteLayout(ctx, layoutID)
	}()

	// Create a layout assignment so FindBestAssignment resolves to this layout
	routeSource := models.LayoutAssignmentRouteSourceAdminAuthored
	require.NoError(t, sm.Metadata.CreateAssignment(ctx, &models.LayoutAssignment{
		ObjectAPIName: objName,
		LayoutID:      layoutID,
		RouteSource:   &routeSource,
	}))

	// Execute
	req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/services/data/v63.0/sobjects/%s/describe/layouts/012000000000000AAA", objName), nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// Assert
	assert.Equal(t, http.StatusOK, w.Code)

	var layout map[string]interface{}
	require.NoError(t, json.Unmarshal(w.Body.Bytes(), &layout))

	// Verify the stored layout is returned (not generated)
	assert.Equal(t, layoutID, layout["id"], "Should return stored layout ID")
	assert.Equal(t, "Custom Test Layout", layout["name"], "Should return stored layout name")

	// Verify detailLayoutSections reflect stored layout structure
	detailSections, ok := layout["detailLayoutSections"].([]interface{})
	require.True(t, ok, "Should have detailLayoutSections")
	require.Len(t, detailSections, 2, "Should have 2 sections from stored layout")

	sec0 := detailSections[0].(map[string]interface{})
	assert.Equal(t, "Key Information", sec0["heading"])
	sec0Items := sec0["layoutRows"].([]interface{})[0].(map[string]interface{})["layoutItems"].([]interface{})
	require.Len(t, sec0Items, 1, "Key Information section should have 1 field")
	assert.Equal(t, "Name", sec0Items[0].(map[string]interface{})["field"])

	sec1 := detailSections[1].(map[string]interface{})
	assert.Equal(t, "Financial Details", sec1["heading"])

	// Verify sections (Nexus format)
	sections, ok := layout["sections"].([]interface{})
	require.True(t, ok, "Should have sections")
	require.Len(t, sections, 2)
	assert.Equal(t, "Key Information", sections[0].(map[string]interface{})["label"])
	assert.Equal(t, "Financial Details", sections[1].(map[string]interface{})["label"])

	// Verify relatedLists exists
	_, ok = layout["relatedLists"].([]interface{})
	require.True(t, ok, "Should have relatedLists")
}

// TestSystemHandler_GetLayoutIDForProfile_Integration verifies profile-to-layout
// assignment lookup including case-insensitive object name matching. Profile
// routing now persists in _System_LayoutAssignment rather than ProfileLayout.
func TestSystemHandler_GetLayoutIDForProfile_Integration(t *testing.T) {
	sm, _, _ := SetupHandlerHelper(t)

	ctx := context.Background()
	unix := time.Now().UnixNano()
	objName := fmt.Sprintf("layout_profile_%d", unix)
	meta := &models.ObjectMetadata{
		APIName: objName,
		Label:   fmt.Sprintf("Layout Profile %d", unix),
		Fields: []models.FieldMetadata{
			{APIName: "Name", Type: constants.FieldTypeString, Label: "Name", IsNameField: true},
		},
	}
	require.NoError(t, sm.Metadata.CreateSchema(ctx, meta))
	sm.Metadata.RefreshCache(ctx)

	// Create and save a layout
	layoutID := fmt.Sprintf("profile_layout_%d", unix)
	layout := &models.PageLayout{
		ID:            layoutID,
		ObjectAPIName: objName,
		LayoutName:    "Profile Test Layout",
		IsDefault:     true,
		LayoutVersion: 2,
		Sections: []models.PageSection{
			{ID: "s1", Label: "Info", Columns: 2, Fields: []string{"Name"}},
		},
	}
	require.NoError(t, sm.Metadata.SaveLayout(ctx, layout))
	defer func() {
		sm.Metadata.DeleteLayout(ctx, layoutID)
	}()

	// Assign layout to a profile
	testProfileID := constants.ProfileSystemAdmin
	require.NoError(t, sm.Metadata.AssignLayoutToProfile(ctx, testProfileID, objName, layoutID))
	defer func() {
		conn, _ := database.GetInstance()
		conn.DB().ExecContext(ctx, fmt.Sprintf("DELETE FROM `%s` WHERE `%s` = ? AND `%s` = ? AND `%s` IS NULL AND `%s` IS NULL",
			constants.TableLayoutAssignment, constants.FieldProfileID, constants.FieldObjectAPIName, constants.FieldSysLayoutAssignment_RoleID, constants.FieldSysLayoutAssignment_RecordTypeID),
			testProfileID, objName)
	}()

	t.Run("does not write legacy profilelayout storage", func(t *testing.T) {
		conn, err := database.GetInstance()
		require.NoError(t, err)
		var count int
		err = conn.DB().QueryRowContext(ctx, fmt.Sprintf("SELECT COUNT(*) FROM `%s` WHERE `%s` = ? AND `%s` = ?",
			constants.TableProfileLayout, constants.FieldProfileID, constants.FieldObjectAPIName),
			testProfileID, objName).Scan(&count)
		require.NoError(t, err)
		assert.Zero(t, count, "ProfileLayout should not receive new writes after the routing cutover")
	})

	t.Run("returns assigned layout ID", func(t *testing.T) {
		conn, err := database.GetInstance()
		require.NoError(t, err)
		repo := persistence.NewMetadataRepository(conn.DB())
		gotID, err := repo.GetLayoutIDForProfile(ctx, objName, testProfileID)
		require.NoError(t, err)
		assert.Equal(t, layoutID, gotID)
	})

	t.Run("returns empty for unassigned profile", func(t *testing.T) {
		conn, err := database.GetInstance()
		require.NoError(t, err)
		repo := persistence.NewMetadataRepository(conn.DB())
		gotID, err := repo.GetLayoutIDForProfile(ctx, objName, "nonexistent_profile")
		require.NoError(t, err)
		assert.Empty(t, gotID, "Should return empty for unassigned profile")
	})

	t.Run("case-insensitive object name match", func(t *testing.T) {
		conn, err := database.GetInstance()
		require.NoError(t, err)
		repo := persistence.NewMetadataRepository(conn.DB())
		// Query with uppercase object name
		upperName := fmt.Sprintf("LAYOUT_PROFILE_%d", unix)
		gotID, err := repo.GetLayoutIDForProfile(ctx, upperName, testProfileID)
		require.NoError(t, err)
		assert.Equal(t, layoutID, gotID, "Should match case-insensitively")
	})
}
