package dialectsfcrm

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"regexp"
	"strings"

	"github.com/nexuscrm/dialect-sf-crm/wire"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/dialect"
	sharederrors "github.com/nexuscrm/shared/pkg/errors"
	"github.com/nexuscrm/shared/pkg/fieldprovenance"
	"github.com/nexuscrm/shared/pkg/models"
)

var safeRecordIDForSOQL = regexp.MustCompile(`^[a-zA-Z0-9-]+$`)
var safeSOQLFieldName = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$`)

type relevantItemAttributesV63 struct {
	Type string `json:"type"`
	URL  string `json:"url"`
}

type relevantItemV63 struct {
	Attributes relevantItemAttributesV63 `json:"attributes"`
	Id         string                    `json:"Id"`
	Name       string                    `json:"Name"`
}

// GetRecordNeutralHandler handles GET /sobjects/:sobject/:id.
func GetRecordNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	return getRecordNeutralHandler(ctx, req, deps, nil, nil)
}

func (p CompositeTreePartition) GetRecordNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	return getRecordNeutralHandler(ctx, req, deps, p.recordDecorator, p.recordAttachmentLookup)
}

func getRecordNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps, decorator recordReadDecorator, lookup contract.RecordAttachmentSourceLookup) (*dialect.Response, error) {
	records := deps.Contracts.Records
	metadata := deps.Contracts.Metadata
	if records == nil || metadata == nil {
		return internalErrorResponse("records contract unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	recordID := strings.TrimSpace(req.Params["id"])
	schema, resp := describeRecordObject(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}

	neutralRecord, err := records.Retrieve(ctx, objectName, recordID, req.User)
	if err != nil {
		return recordRetrieveErrorResponse(req, err), nil
	}
	if neutralRecord == nil {
		return notFoundResponse("Record not found"), nil
	}

	record := projectRecordToV63(neutralRecord, v63RecordProjectionFull)
	access := fieldAccessMap(ctx, deps.Contracts.Policy, req.User, objectName)
	synthesizeVirtualCompoundFields(schema, record, func(fieldAPIName string) bool {
		if access == nil {
			return true
		}
		field, ok := access[fieldAPIName]
		return ok && field.Readable
	})
	hydrateLookups(ctx, deps.Contracts, objectName, record, req.User)
	nestRelationshipFields(schema, record)

	if decorator != nil {
		if derr := decorator.DecorateRecordRead(ctx, objectName, recordID, contract.Record(record), recordReadDecorationRequest{
			FileURLPrefix:                versionedFilesBasePath(req.Version),
			User:                         req.User,
			RecordAttachmentSource:       deps.Contracts.Files,
			RecordAttachmentSourceLookup: lookup,
		}); derr != nil {
			// Legacy REST logged and served the raw value. Preserve the best-effort
			// contract: read decoration must never fail the record response.
			log.Printf("record read decorator: serving raw values for %s/%s: %v", objectName, recordID, derr)
		}
	}

	stampSObjectRecordResponseAttributes(record, objectName, recordID, req.Version)
	trackRecordAccess(deps.Contracts.Activity, req.User, objectName, recordID)
	return &dialect.Response{Status: http.StatusOK, Body: record}, nil
}

// GetByExternalIDNeutralHandler handles GET /sobjects/:sobject/:fieldName/:fieldValue.
func GetByExternalIDNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	records := deps.Contracts.Records
	metadata := deps.Contracts.Metadata
	if records == nil || metadata == nil {
		return internalErrorResponse("records contract unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	fieldName := externalIDFieldName(req)
	fieldValue := req.Params["fieldValue"]

	schema, resp := describeRecordObject(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	if !schemaHasField(schema, fieldName) {
		return &dialect.Response{
			Status: http.StatusBadRequest,
			Body:   wire.SFErrorResponse(wire.SFCodeInvalidField, fmt.Sprintf("Field '%s' does not exist on object '%s'", fieldName, objectName)),
		}, nil
	}

	neutralRecord, err := records.RetrieveByField(ctx, objectName, fieldName, fieldValue, req.User)
	if err != nil {
		if resp := respondServiceError(req, err); resp != nil {
			return resp, nil
		}
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeQueryFailed, err.Error())}, nil
	}
	if neutralRecord == nil {
		return notFoundResponse("Record not found"), nil
	}
	record := sObjectRecordResponseFromNeutralRecord(neutralRecord, objectName, req.Version)
	if recordID, ok := record[constants.FieldID].(string); ok {
		trackRecordAccess(deps.Contracts.Activity, req.User, objectName, recordID)
	}
	return &dialect.Response{Status: http.StatusOK, Body: record}, nil
}

// UpsertByExternalIDNeutralHandler handles PATCH /sobjects/:sobject/:fieldName/:fieldValue.
func UpsertByExternalIDNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	records := deps.Contracts.Records
	metadata := deps.Contracts.Metadata
	if records == nil || metadata == nil {
		return internalErrorResponse("records contract unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	fieldName := externalIDFieldName(req)
	fieldValue := req.Params["fieldValue"]

	var body map[string]interface{}
	if err := json.NewDecoder(bytes.NewReader(req.Body)).Decode(&body); err != nil {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidRequest, err.Error())}, nil
	}
	schema, resp := describeRecordObject(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	body = canonicalizeRecordInputFields(schema, body)
	denial, err := recordMutationDenialForExistingExternalID(ctx, records, deps.Contracts.Query, schema, models.RecordMutationSurfaceExternalIDUpsert, fieldName, fieldValue, models.SObject(body), req.User)
	if err != nil {
		return writeErrorResponse(req, err, wire.SFCodeUpsertFailed), nil
	}
	if resp := recordMutationDenialResponse(denial, wire.SFCodeUpsertFailed); resp != nil {
		return resp, nil
	}
	if err := validateInput(schema, body); err != nil {
		return validationErrorResponse(err, wire.SFCodeInvalidField), nil
	}

	result, created, err := records.UpsertByExternalID(ctx, objectName, fieldName, fieldValue, contract.Record(body), req.User)
	if err != nil {
		return writeErrorResponse(req, err, wire.SFCodeUpsertFailed), nil
	}
	if created {
		return &dialect.Response{Status: http.StatusCreated, Body: map[string]interface{}{
			"id":      result[constants.FieldID],
			"success": true,
			"created": true,
			"errors":  []map[string]interface{}{},
		}}, nil
	}
	return &dialect.Response{Status: http.StatusNoContent, Body: nil}, nil
}

// CreateRecordNeutralHandler handles POST /sobjects/:sobject.
func CreateRecordNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	records := deps.Contracts.Records
	metadata := deps.Contracts.Metadata
	if records == nil || metadata == nil {
		return internalErrorResponse("records and metadata contracts unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	var body map[string]interface{}
	if err := json.NewDecoder(bytes.NewReader(req.Body)).Decode(&body); err != nil {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeJSONParserError, "Invalid JSON")}, nil
	}
	schema, resp := resolveRecordMutationSchema(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	body = canonicalizeRecordInputFields(schema, body)
	if resp := recordMutationDenialResponse(recordMutationDenial(schema, models.RecordMutationSurfaceSingleCreate, models.SObject(body)), wire.SFCodeInsertFailed); resp != nil {
		return resp, nil
	}
	if err := validateInput(schema, body); err != nil {
		return validationErrorResponse(err, wire.SFCodeInvalidField), nil
	}
	if err := validateRequiredForCreate(schema, body); err != nil {
		return validationErrorResponse(err, wire.SFCodeRequiredFieldMissing), nil
	}

	result, err := records.Insert(ctx, objectName, contract.Record(body), req.User)
	if err != nil {
		return writeErrorResponse(req, err, wire.SFCodeInsertFailed), nil
	}
	if recordID, ok := insertedRecordID(result); ok {
		trackRecordAccess(deps.Contracts.Activity, req.User, objectName, recordID)
	}
	return &dialect.Response{Status: http.StatusCreated, Body: map[string]interface{}{
		"id":      result[constants.FieldID],
		"success": true,
		"errors":  []map[string]interface{}{},
	}}, nil
}

// UpdateRecordNeutralHandler handles PATCH /sobjects/:sobject/:id.
func UpdateRecordNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	records := deps.Contracts.Records
	metadata := deps.Contracts.Metadata
	if records == nil || metadata == nil {
		return internalErrorResponse("records and metadata contracts unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	recordID := strings.TrimSpace(req.Params["id"])
	var body map[string]interface{}
	if err := json.NewDecoder(bytes.NewReader(req.Body)).Decode(&body); err != nil {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeJSONParserError, err.Error())}, nil
	}
	schema, resp := resolveRecordMutationSchema(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	body = canonicalizeRecordInputFields(schema, body)
	denial, err := recordMutationDenialForExistingID(ctx, records, deps.Contracts.Query, schema, models.RecordMutationSurfaceSingleUpdate, recordID, models.SObject(body), req.User)
	if err != nil {
		return writeErrorResponse(req, err, wire.SFCodeUpdateFailed), nil
	}
	if resp := recordMutationDenialResponse(denial, wire.SFCodeUpdateFailed); resp != nil {
		return resp, nil
	}
	if err := validateInput(schema, body); err != nil {
		return validationErrorResponse(err, wire.SFCodeInvalidField), nil
	}

	if err := records.Update(ctx, objectName, recordID, contract.Record(body), req.User); err != nil {
		return writeErrorResponse(req, err, wire.SFCodeUpdateFailed), nil
	}
	trackRecordAccess(deps.Contracts.Activity, req.User, objectName, recordID)
	return &dialect.Response{Status: http.StatusNoContent}, nil
}

// DeleteRecordNeutralHandler handles DELETE /sobjects/:sobject/:id.
func DeleteRecordNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	records := deps.Contracts.Records
	metadata := deps.Contracts.Metadata
	if records == nil || metadata == nil {
		return internalErrorResponse("records and metadata contracts unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	recordID := strings.TrimSpace(req.Params["id"])
	schema, resp := resolveRecordMutationSchema(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	if resp := recordMutationDenialResponse(recordMutationDenial(schema, models.RecordMutationSurfaceSingleDelete, nil), wire.SFCodeDeleteFailed); resp != nil {
		return resp, nil
	}

	if err := records.Delete(ctx, objectName, recordID, req.User); err != nil {
		return writeErrorResponse(req, err, wire.SFCodeDeleteFailed), nil
	}
	return &dialect.Response{Status: http.StatusNoContent}, nil
}

// ListViewsNeutralHandler handles GET /sobjects/:sobject/listviews.
func ListViewsNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	metadata := deps.Contracts.Metadata
	if metadata == nil {
		return internalErrorResponse("metadata contract unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	if !canReadObject(ctx, deps.Contracts.Policy, req.User, objectName) {
		return forbiddenResponse("Insufficient access"), nil
	}
	schema, resp := describeRecordObject(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	visibleViews, resp := callerVisibleListViews(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}

	listViewsBase := fmt.Sprintf("%s/%s/listviews", versionedSObjectsBasePath(req.Version), objectName)
	listViews := make([]map[string]interface{}, 0, len(visibleViews))
	for _, view := range visibleViews {
		summary, ok := listViewSummaryFromMetadata(view, objectName, schema, listViewsBase)
		if ok {
			listViews = append(listViews, summary)
		}
	}
	return &dialect.Response{Status: http.StatusOK, Body: map[string]interface{}{
		"done":           true,
		"listviews":      listViews,
		"nextRecordsUrl": nil,
		"size":           len(listViews),
		"sobjectType":    objectName,
	}}, nil
}

// CreatePrivateListViewNeutralHandler handles POST /sobjects/:sobject/listviews.
func CreatePrivateListViewNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	metadata := deps.Contracts.Metadata
	authoring := deps.Contracts.ListViewAuthoring
	if metadata == nil || authoring == nil {
		return internalErrorResponse("metadata and list view authoring contracts unavailable"), nil
	}

	objectName := strings.TrimSpace(req.Params["sobject"])
	if objectName == "" {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidRequest, "sObject is required")}, nil
	}
	if !canReadObject(ctx, deps.Contracts.Policy, req.User, objectName) {
		return forbiddenResponse("Insufficient access"), nil
	}
	if _, resp := describeRecordObject(ctx, req, metadata, objectName); resp != nil {
		return resp, nil
	}

	var body listViewCreateRequest
	if err := json.NewDecoder(bytes.NewReader(req.Body)).Decode(&body); err != nil {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeJSONParserError, "Invalid JSON")}, nil
	}
	bodyObjectName := strings.TrimSpace(body.ObjectAPIName)
	if bodyObjectName != "" && bodyObjectName != objectName {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidRequest, "ObjectApiName must match the list view route object")}, nil
	}

	visibility := "Private"
	if body.Visibility != nil {
		visibility = strings.TrimSpace(*body.Visibility)
		if !strings.EqualFold(visibility, "Private") {
			return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorWithFields(wire.SFCodeInvalidField, "Only Private list view visibility is supported", "Visibility")}, nil
		}
		visibility = "Private"
	}

	label := strings.TrimSpace(body.Name)
	if label == "" {
		label = strings.TrimSpace(body.Label)
	}
	input := &models.ListView{
		ObjectAPIName: objectName,
		Label:         label,
		FilterExpr:    body.FilterExpr,
		FilterLogic:   body.FilterLogic,
		SortField:     body.SortField,
		SortDirection: body.SortDirection,
		Fields:        body.Fields.names(),
		Visibility:    &visibility,
		DeveloperName: trimStringPointer(body.DeveloperName),
	}

	created, err := authoring.CreatePrivate(ctx, req.User, input)
	if err != nil {
		return writeErrorResponse(req, err, wire.SFCodeInsertFailed), nil
	}
	if created == nil || strings.TrimSpace(created.ID) == "" {
		return internalErrorResponse("list view authoring returned no id"), nil
	}
	return &dialect.Response{Status: http.StatusCreated, Body: map[string]interface{}{
		"id":      created.ID,
		"success": true,
		"errors":  []map[string]interface{}{},
	}}, nil
}

// DeletePrivateListViewNeutralHandler handles DELETE /sobjects/:sobject/listviews/:listViewId.
func DeletePrivateListViewNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	metadata := deps.Contracts.Metadata
	authoring := deps.Contracts.ListViewAuthoring
	if metadata == nil || authoring == nil {
		return internalErrorResponse("metadata and list view authoring contracts unavailable"), nil
	}

	objectName := strings.TrimSpace(req.Params["sobject"])
	listViewID := strings.TrimSpace(req.Params["listViewId"])
	if objectName == "" {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidRequest, "sObject is required")}, nil
	}
	if listViewID == "" {
		return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidRequest, "List view ID is required")}, nil
	}
	if !canReadObject(ctx, deps.Contracts.Policy, req.User, objectName) {
		return forbiddenResponse("Insufficient access"), nil
	}
	if _, resp := describeRecordObject(ctx, req, metadata, objectName); resp != nil {
		return resp, nil
	}
	visibleViews, resp := callerVisibleListViews(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}

	var target *models.ListView
	for _, view := range visibleViews {
		if view != nil && strings.TrimSpace(view.ID) == listViewID && deletablePrivateListView(view, objectName, req.User) {
			target = view
			break
		}
	}
	if target == nil {
		return notFoundResponse("List view not found: " + listViewID), nil
	}

	if err := authoring.DeletePrivate(ctx, req.User, listViewID); err != nil {
		return writeErrorResponse(req, err, wire.SFCodeDeleteFailed), nil
	}
	return &dialect.Response{Status: http.StatusNoContent}, nil
}

// ListViewDescribeNeutralHandler handles GET /sobjects/:sobject/listviews/:listViewId/describe.
func ListViewDescribeNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	metadata := deps.Contracts.Metadata
	if metadata == nil {
		return internalErrorResponse("metadata contract unavailable"), nil
	}
	objectName := strings.TrimSpace(req.Params["sobject"])
	listViewID := strings.TrimSpace(req.Params["listViewId"])
	if !canReadObject(ctx, deps.Contracts.Policy, req.User, objectName) {
		return forbiddenResponse("Insufficient access"), nil
	}
	_, resp := describeRecordObject(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	visibleViews, resp := callerVisibleListViews(ctx, req, metadata, objectName)
	if resp != nil {
		return resp, nil
	}
	var listView *models.ListView
	for _, view := range visibleViews {
		if view != nil && strings.TrimSpace(view.ID) == listViewID {
			listView = view
			break
		}
	}
	if listView == nil {
		return notFoundResponse("List view not found: " + listViewID), nil
	}

	selectFields := "Id, Name"
	allID := fmt.Sprintf("%s-all-view", objectName)
	myID := fmt.Sprintf("%s-my-view", objectName)
	recentID := fmt.Sprintf("%s-recent-view", objectName)
	switch {
	case listViewID == allID || listViewDeveloperName(listView, objectName) == "All":
		return &dialect.Response{Status: http.StatusOK, Body: map[string]interface{}{
			"id":          listViewID,
			"query":       fmt.Sprintf("SELECT %s FROM %s", selectFields, objectName),
			"sobjectType": objectName,
		}}, nil
	case listViewID == myID || listViewDeveloperName(listView, objectName) == "My":
		userID := ""
		if req.User != nil {
			userID = req.User.ID
		}
		return &dialect.Response{Status: http.StatusOK, Body: map[string]interface{}{
			"id":          listViewID,
			"query":       fmt.Sprintf("SELECT %s FROM %s WHERE OwnerId = '%s'", selectFields, objectName, userID),
			"sobjectType": objectName,
		}}, nil
	case listViewID == recentID || listViewDeveloperName(listView, objectName) == constants.ListViewDefaultDeveloperName:
		soqlQuery := fmt.Sprintf("SELECT %s FROM %s", selectFields, objectName)
		if deps.Contracts.Activity != nil && req.User != nil {
			recentIDs, rerr := recentRecordIDs(ctx, deps.Contracts.Activity, req.User.ID, objectName)
			if rerr != nil {
				return internalErrorResponse("Failed to retrieve recent items"), nil
			}
			if len(recentIDs) > 0 {
				quoted := make([]string, 0, len(recentIDs))
				for _, id := range recentIDs {
					if safeRecordIDForSOQL.MatchString(id) {
						quoted = append(quoted, "'"+id+"'")
					}
				}
				if len(quoted) > 0 {
					soqlQuery += fmt.Sprintf(" WHERE Id IN (%s)", strings.Join(quoted, ", "))
				} else {
					soqlQuery += " WHERE Id = 'none'"
				}
			} else {
				soqlQuery += " WHERE Id = 'none'"
			}
		} else {
			soqlQuery += " WHERE Id = 'none'"
		}
		soqlQuery += " ORDER BY xMruAccessedAt DESC"
		return &dialect.Response{Status: http.StatusOK, Body: map[string]interface{}{
			"id":          listViewID,
			"query":       soqlQuery,
			"sobjectType": objectName,
			"orderBy":     []map[string]interface{}{{"field": "xMruAccessedAt", "direction": "DESC"}},
		}}, nil
	}

	soqlQuery := fmt.Sprintf("SELECT %s FROM %s", listViewSelectFields(listView), objectName)
	if filterExpr := listViewFilterExpr(listView, req.User); filterExpr != "" {
		soqlQuery += " WHERE " + filterExpr
	}
	body := map[string]interface{}{
		"id":          listViewID,
		"query":       soqlQuery,
		"sobjectType": objectName,
	}
	if orderBy := listViewOrderBy(listView); len(orderBy) > 0 {
		primary := orderBy[0]
		soqlQuery += fmt.Sprintf(" ORDER BY %s %s", primary["field"], primary["direction"])
		body["query"] = soqlQuery
		body["orderBy"] = orderBy
	}
	return &dialect.Response{Status: http.StatusOK, Body: body}, nil
}

// RelevantItemsNeutralHandler handles GET /sobjects/relevantItems.
func RelevantItemsNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	if deps.Contracts.Activity == nil {
		return internalErrorResponse("activity contract unavailable"), nil
	}
	userID := ""
	if req.User != nil {
		userID = req.User.ID
	}
	var sobjects []string
	if raw := queryValue(req, "sobjects"); raw != "" {
		for _, obj := range strings.Split(raw, ",") {
			obj = strings.TrimSpace(obj)
			if obj != "" {
				sobjects = append(sobjects, obj)
			}
		}
	}
	result, newLastUpdatedID, err := deps.Contracts.Activity.RelevantItems(ctx, userID, sobjects, queryValue(req, "lastUpdatedId"))
	if err != nil {
		return internalErrorResponse("Failed to retrieve relevant items"), nil
	}
	headers := map[string]string{"lastUpdatedId": newLastUpdatedID}
	if queryValue(req, "lastUpdatedId") != "" && queryValue(req, "lastUpdatedId") != newLastUpdatedID {
		headers["newResultSetSinceLastQuery"] = "true"
	}
	return &dialect.Response{Status: http.StatusOK, Headers: headers, Body: relevantItemsToV63(result, req.Version)}, nil
}

type listViewCreateRequest struct {
	ObjectAPIName string               `json:"ObjectApiName"`
	Name          string               `json:"Name"`
	Label         string               `json:"Label"`
	DeveloperName *string              `json:"DeveloperName"`
	Visibility    *string              `json:"Visibility"`
	FilterExpr    string               `json:"FilterExpr"`
	FilterLogic   string               `json:"FilterLogic"`
	SortField     string               `json:"SortField"`
	SortDirection string               `json:"SortDirection"`
	Fields        listViewCreateFields `json:"Fields"`
}

type listViewCreateFields []listViewCreateField

func (fields listViewCreateFields) names() []string {
	out := make([]string, 0, len(fields))
	for _, field := range fields {
		if name := strings.TrimSpace(field.Name); name != "" {
			out = append(out, name)
		}
	}
	return out
}

type listViewCreateField struct {
	Name string
}

func (field *listViewCreateField) UnmarshalJSON(data []byte) error {
	var name string
	if err := json.Unmarshal(data, &name); err == nil {
		field.Name = strings.TrimSpace(name)
		return nil
	}

	var shape struct {
		Name         string `json:"name"`
		APIName      string `json:"apiName"`
		FieldAPIName string `json:"fieldApiName"`
	}
	if err := json.Unmarshal(data, &shape); err != nil {
		return err
	}
	switch {
	case strings.TrimSpace(shape.Name) != "":
		field.Name = strings.TrimSpace(shape.Name)
	case strings.TrimSpace(shape.APIName) != "":
		field.Name = strings.TrimSpace(shape.APIName)
	default:
		field.Name = strings.TrimSpace(shape.FieldAPIName)
	}
	return nil
}

func trimStringPointer(value *string) *string {
	if value == nil {
		return nil
	}
	trimmed := strings.TrimSpace(*value)
	return &trimmed
}

func listViewSummary(id, label, developerName, base string) map[string]interface{} {
	return map[string]interface{}{
		"id":             id,
		"label":          label,
		"developerName":  developerName,
		"isDefault":      developerName == constants.ListViewDefaultDeveloperName,
		"describeUrl":    fmt.Sprintf("%s/%s/describe", base, id),
		"resultsUrl":     fmt.Sprintf("%s/%s/results", base, id),
		"soqlCompatible": true,
		"url":            fmt.Sprintf("%s/%s", base, id),
	}
}

func callerVisibleListViews(ctx context.Context, req *dialect.Request, metadata contract.Metadata, objectName string) ([]*models.ListView, *dialect.Response) {
	catalog, ok := metadata.(contract.ObjectMetadataCatalogReader)
	if !ok {
		return nil, internalErrorResponse("metadata catalog contract unavailable")
	}
	views, err := catalog.ListViews(ctx, objectName, req.User)
	if err != nil {
		return nil, internalErrorResponse("Failed to retrieve list views")
	}
	return views, nil
}

func listViewSummaryFromMetadata(view *models.ListView, objectName string, schema *models.ObjectMetadata, base string) (map[string]interface{}, bool) {
	if view == nil {
		return nil, false
	}
	id := strings.TrimSpace(view.ID)
	if id == "" {
		return nil, false
	}
	developerName := listViewDeveloperName(view, objectName)
	label := listViewWireLabel(view, objectName, schema, developerName)
	return listViewSummary(id, label, developerName, base), true
}

func deletablePrivateListView(view *models.ListView, objectName string, user *models.UserSession) bool {
	if view == nil || user == nil || strings.TrimSpace(user.ID) == "" {
		return false
	}
	if strings.TrimSpace(view.ObjectAPIName) != objectName {
		return false
	}
	if isSyntheticListView(view, objectName) {
		return false
	}
	if view.OwnerID == nil || strings.TrimSpace(*view.OwnerID) != strings.TrimSpace(user.ID) {
		return false
	}
	return view.Visibility != nil && strings.EqualFold(strings.TrimSpace(*view.Visibility), "Private")
}

func isSyntheticListView(view *models.ListView, objectName string) bool {
	if view == nil {
		return false
	}
	switch strings.TrimSpace(view.ID) {
	case fmt.Sprintf("%s-all-view", objectName), fmt.Sprintf("%s-my-view", objectName), fmt.Sprintf("%s-recent-view", objectName):
		return true
	}
	switch listViewDeveloperName(view, objectName) {
	case "All", "My", constants.ListViewDefaultDeveloperName:
		return true
	}
	return false
}

func listViewDeveloperName(view *models.ListView, objectName string) string {
	if view == nil {
		return ""
	}
	if view.DeveloperName != nil {
		if developerName := strings.TrimSpace(*view.DeveloperName); developerName != "" {
			return developerName
		}
	}
	switch strings.TrimSpace(view.ID) {
	case fmt.Sprintf("%s-all-view", objectName):
		return "All"
	case fmt.Sprintf("%s-my-view", objectName):
		return "My"
	case fmt.Sprintf("%s-recent-view", objectName):
		return constants.ListViewDefaultDeveloperName
	}
	if label := strings.TrimSpace(view.Label); label != "" {
		return label
	}
	return strings.TrimSpace(view.ID)
}

func listViewWireLabel(view *models.ListView, objectName string, schema *models.ObjectMetadata, developerName string) string {
	pluralLabel := objectName
	if schema != nil && strings.TrimSpace(schema.PluralLabel) != "" {
		pluralLabel = strings.TrimSpace(schema.PluralLabel)
	}
	switch developerName {
	case "All":
		return "All " + pluralLabel
	case "My":
		return "My " + pluralLabel
	case constants.ListViewDefaultDeveloperName:
		return "Recently Viewed"
	}
	if view != nil {
		if label := strings.TrimSpace(view.Label); label != "" {
			return label
		}
	}
	if developerName != "" {
		return developerName
	}
	return objectName
}

func listViewSelectFields(view *models.ListView) string {
	if view == nil {
		return "Id, Name"
	}
	fields := make([]string, 0, len(view.Fields))
	seen := map[string]struct{}{}
	for _, field := range view.Fields {
		field = strings.TrimSpace(field)
		if field == "" || !safeSOQLFieldName.MatchString(field) {
			continue
		}
		key := strings.ToLower(field)
		if _, ok := seen[key]; ok {
			continue
		}
		seen[key] = struct{}{}
		fields = append(fields, field)
	}
	if len(fields) == 0 {
		return "Id, Name"
	}
	return strings.Join(fields, ", ")
}

func listViewFilterExpr(view *models.ListView, user *models.UserSession) string {
	if view == nil {
		return ""
	}
	filterExpr := strings.TrimSpace(view.FilterExpr)
	if filterExpr == "" {
		return ""
	}
	if strings.Contains(filterExpr, "@user_id") {
		userID := ""
		if user != nil {
			userID = strings.ReplaceAll(user.ID, "'", "\\'")
		}
		filterExpr = strings.ReplaceAll(filterExpr, "@user_id", "'"+userID+"'")
	}
	return filterExpr
}

func listViewOrderBy(view *models.ListView) []map[string]interface{} {
	if view == nil {
		return nil
	}
	field := strings.TrimSpace(view.SortField)
	if field == "" || !safeSOQLFieldName.MatchString(field) {
		return nil
	}
	direction := strings.ToUpper(strings.TrimSpace(view.SortDirection))
	if direction != "DESC" {
		direction = "ASC"
	}
	return []map[string]interface{}{{"field": field, "direction": direction}}
}

func externalIDFieldName(req *dialect.Request) string {
	if req == nil || req.Params == nil {
		return ""
	}
	if value := strings.TrimSpace(req.Params["fieldName"]); value != "" {
		return value
	}
	return strings.TrimSpace(req.Params["id"])
}

func recentRecordIDs(ctx context.Context, activity contract.Activity, userID, objectAPIName string) ([]string, error) {
	items, _, err := activity.RelevantItems(ctx, userID, []string{objectAPIName}, "")
	if err != nil {
		return nil, err
	}
	ids := make([]string, 0, len(items))
	for _, item := range items {
		ids = append(ids, item.RecordID)
	}
	if len(ids) > 200 {
		ids = ids[:200]
	}
	return ids, nil
}

func relevantItemsToV63(items []contract.RelevantItem, apiVersion string) []relevantItemV63 {
	apiVersion = apiVersionOrDefault(apiVersion)
	out := make([]relevantItemV63, 0, len(items))
	for _, item := range items {
		out = append(out, relevantItemV63{
			Attributes: relevantItemAttributesV63{
				Type: item.ObjectAPIName,
				URL:  fmt.Sprintf("/services/data/%s/sobjects/%s/%s", apiVersion, item.ObjectAPIName, item.RecordID),
			},
			Id:   item.RecordID,
			Name: item.Name,
		})
	}
	return out
}

func trackRecordAccess(activity contract.Activity, user *models.UserSession, objectName, recordID string) {
	if activity == nil || user == nil || strings.TrimSpace(recordID) == "" {
		return
	}
	activity.TrackRecordAccess(context.Background(), user.ID, objectName, recordID)
}

func fieldAccessMap(ctx context.Context, policy contract.Policy, user *models.UserSession, objectName string) map[string]contract.FieldAccess {
	if policy == nil {
		return nil
	}
	access, err := policy.Access(ctx, user, objectName, contract.AccessRequest{IncludeFields: true})
	if err != nil || access == nil {
		return nil
	}
	return access.Fields
}

func canReadObject(ctx context.Context, policy contract.Policy, user *models.UserSession, objectName string) bool {
	if policy == nil {
		return true
	}
	access, err := policy.Access(ctx, user, objectName, contract.AccessRequest{})
	if err != nil || access == nil {
		return false
	}
	return access.Object.Read
}

func sObjectRecordResponseFromNeutralRecord(record contract.Record, objectName string, apiVersion string) models.SObject {
	response := projectRecordToV63(record, v63RecordProjectionFull)
	recordID, _ := response[constants.FieldID].(string)
	stampSObjectRecordResponseAttributes(response, objectName, recordID, apiVersion)
	return response
}

func stampSObjectRecordResponseAttributes(record models.SObject, objectName string, recordID string, apiVersion string) {
	record["attributes"] = map[string]interface{}{
		"type": objectName,
		"url":  fmt.Sprintf("%s/%s/%s", versionedSObjectsBasePath(apiVersion), objectName, recordID),
	}
	record[constants.FieldID] = recordID
}

func hydrateLookups(ctx context.Context, deps contract.Deps, objectName string, record models.SObject, user *models.UserSession) {
	if deps.Metadata == nil || deps.Records == nil {
		return
	}
	schema, err := deps.Metadata.Describe(ctx, objectName)
	if err != nil || schema == nil {
		return
	}
	type lookupRef struct {
		fieldAPIName string
		targetObj    string
		targetID     string
	}
	idsByObj := make(map[string]map[string]struct{})
	var refs []lookupRef
	for _, f := range schema.Fields {
		if !constants.IsReferenceType(f.Type) {
			continue
		}
		if _, ok := record[f.APIName+"_Name"]; ok {
			continue
		}
		idStr, ok := record[f.APIName].(string)
		if !ok || idStr == "" {
			continue
		}
		targetObj := lookupHydrationTargetObject(f)
		if targetObj == "" {
			continue
		}
		refs = append(refs, lookupRef{fieldAPIName: f.APIName, targetObj: targetObj, targetID: idStr})
		if idsByObj[targetObj] == nil {
			idsByObj[targetObj] = make(map[string]struct{})
		}
		idsByObj[targetObj][idStr] = struct{}{}
	}
	if len(refs) == 0 {
		return
	}
	cache := make(map[string]map[string]models.SObject, len(idsByObj))
	for objName, idSet := range idsByObj {
		ids := make([]string, 0, len(idSet))
		for id := range idSet {
			ids = append(ids, id)
		}
		if targetSchema, err := deps.Metadata.Describe(ctx, objName); err != nil || targetSchema == nil {
			continue
		}
		records, err := deps.Records.RetrieveMany(ctx, objName, ids, user)
		if err != nil {
			continue
		}
		cache[objName] = recordsMapToV63SObjects(records)
	}
	for _, ref := range refs {
		objCache, ok := cache[ref.targetObj]
		if !ok {
			continue
		}
		targetRecord, ok := objCache[ref.targetID]
		if !ok {
			continue
		}
		targetSchema, err := deps.Metadata.Describe(ctx, ref.targetObj)
		if err != nil || targetSchema == nil {
			continue
		}
		if displayName := resolveLookupDisplayName(targetSchema, targetRecord); displayName != "" {
			record[ref.fieldAPIName+"_Name"] = displayName
		}
	}
}

func lookupHydrationTargetObject(field models.FieldMetadata) string {
	if field.IsPolymorphic {
		if field.APIName == constants.FieldOwnerID {
			return constants.TableUser
		}
		return ""
	}
	if len(field.ReferenceTo) > 0 && strings.TrimSpace(field.ReferenceTo[0]) != "" {
		return field.ReferenceTo[0]
	}
	target, _ := constants.PlatformReferenceTargetForField(field.APIName)
	return target
}

func recordsMapToV63SObjects(records map[string]contract.Record) map[string]models.SObject {
	if records == nil {
		return nil
	}
	out := make(map[string]models.SObject, len(records))
	for id, record := range records {
		out[id] = projectRecordToV63(record, v63RecordProjectionFull)
	}
	return out
}

func resolveLookupDisplayName(schema *models.ObjectMetadata, record models.SObject) string {
	if schema == nil || record == nil {
		return ""
	}
	if strings.EqualFold(schema.APIName, constants.TableUser) {
		displayName := constructDisplayName(
			recordString(record, constants.FieldUsername),
			recordString(record, constants.FieldFirstName),
			recordString(record, constants.FieldLastName),
		)
		if displayName != "" {
			return displayName
		}
	}
	for _, f := range schema.Fields {
		if f.IsNameField {
			return recordString(record, f.APIName)
		}
	}
	for _, fieldName := range []string{constants.FieldName, "DeveloperName", constants.FieldUsername} {
		if value := recordString(record, fieldName); value != "" {
			return value
		}
	}
	return ""
}

func constructDisplayName(username, firstName, lastName string) string {
	fullName := strings.TrimSpace(strings.TrimSpace(firstName) + " " + strings.TrimSpace(lastName))
	if fullName != "" {
		return fullName
	}
	return strings.TrimSpace(username)
}

func recordString(record models.SObject, field string) string {
	if record == nil {
		return ""
	}
	value, ok := record[field]
	if !ok || value == nil {
		return ""
	}
	switch v := value.(type) {
	case string:
		return strings.TrimSpace(v)
	default:
		return strings.TrimSpace(fmt.Sprint(v))
	}
}
func versionedFilesBasePath(version string) string {
	return fmt.Sprintf("/services/data/%s/sobjects/_System_File", apiVersionOrDefault(version))
}

func describeRecordObject(ctx context.Context, req *dialect.Request, metadata contract.Metadata, objectName string) (*models.ObjectMetadata, *dialect.Response) {
	schema, err := metadata.Describe(ctx, objectName)
	if err != nil {
		if sharederrors.IsNotFound(err) {
			return nil, notFoundResponse("Object not found")
		}
		if resp := respondServiceError(req, err); resp != nil {
			return nil, resp
		}
		return nil, internalErrorResponse(err.Error())
	}
	if schema == nil {
		return nil, notFoundResponse("Object not found")
	}
	return schema, nil
}

func recordRetrieveErrorResponse(req *dialect.Request, err error) *dialect.Response {
	if err == nil {
		return nil
	}
	if resp := respondServiceError(req, err); resp != nil {
		if resp.Status == http.StatusNotFound {
			resp.Body = wire.SFErrorResponse(wire.SFCodeNotFound, "Record not found")
		}
		return resp
	}
	return &dialect.Response{Status: http.StatusInternalServerError, Body: wire.SFErrorResponse(wire.SFCodeUnknownException, err.Error())}
}

func writeErrorResponse(req *dialect.Request, err error, fallbackCode string) *dialect.Response {
	if err == nil {
		return nil
	}
	if resp := respondServiceError(req, err); resp != nil {
		return resp
	}
	if fields, message, ok := sharederrors.FieldWriteDeniedDetails(err); ok {
		return &dialect.Response{
			Status: http.StatusBadRequest,
			Body:   wire.SFErrorWithFields(wire.SFCodeInvalidFieldForInsertUpdate, message, fields...),
		}
	}
	if failures, ok := sharederrors.ValidationRuleFailures(err); ok {
		body := make([]wire.SFError, 0, len(failures))
		for _, failure := range failures {
			fields := []string(nil)
			if field := strings.TrimSpace(failure.Field); field != "" {
				fields = []string{field}
			}
			body = append(body, wire.SFError{
				ErrorCode: wire.SFCodeFieldCustomValidationException,
				Message:   failure.Message,
				Fields:    fields,
			})
		}
		return &dialect.Response{Status: http.StatusBadRequest, Body: body}
	}
	if message, ok := sharederrors.ValidationRuleMessage(err); ok {
		return &dialect.Response{
			Status: http.StatusBadRequest,
			Body:   wire.SFErrorResponse(wire.SFCodeFieldCustomValidationException, message),
		}
	}
	if resp := validationErrorMaybe(err, fallbackCode); resp != nil {
		return resp
	}
	if sfErr, status, ok := wire.SFErrorFromDomainForVersion(err, apiVersionOrDefault(req.Version)); ok {
		return &dialect.Response{Status: status, Body: []wire.SFError{sfErr}}
	}
	return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(fallbackCode, err.Error())}
}

type validationErrorShape interface {
	error
	ValidationField() string
	ValidationMessage() string
}

func validationErrorMaybe(err error, fallbackCode string) *dialect.Response {
	var validationErr validationErrorShape
	if errors.As(err, &validationErr) {
		status, body := wire.ValidationErrorEnvelope(validationErr.ValidationField(), validationErr.ValidationMessage(), fallbackCode)
		return &dialect.Response{Status: status, Body: body}
	}
	return nil
}

func validationErrorResponse(err error, fallbackCode string) *dialect.Response {
	if resp := validationErrorMaybe(err, fallbackCode); resp != nil {
		return resp
	}
	return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(fallbackCode, err.Error())}
}

func internalErrorResponse(message string) *dialect.Response {
	return &dialect.Response{Status: http.StatusInternalServerError, Body: wire.SFErrorResponse(wire.SFCodeInternalError, message)}
}

func forbiddenResponse(message string) *dialect.Response {
	return &dialect.Response{Status: http.StatusForbidden, Body: wire.SFErrorResponse(wire.SFCodeForbidden, message)}
}

func validateInput(schema *models.ObjectMetadata, data map[string]interface{}) error {
	fieldDefs := make(map[string]models.FieldMetadata)
	for _, f := range schema.Fields {
		fieldDefs[f.APIName] = f
	}
	for key := range data {
		if key == "attributes" || key == "RecordTypeId" {
			continue
		}
		if _, exists := fieldDefs[key]; !exists {
			return NewValidationError(key, fmt.Sprintf("field '%s' does not exist on object '%s'", key, schema.APIName))
		}
		if isAuditField(key) {
			return NewValidationError(key, fmt.Sprintf("field '%s' is a read-only system field", key))
		}
	}
	return nil
}

func canonicalizeRecordInputFields(schema *models.ObjectMetadata, data map[string]interface{}) map[string]interface{} {
	if schema == nil || data == nil {
		return data
	}
	fieldNames := make(map[string]string, len(schema.Fields))
	for _, f := range schema.Fields {
		fieldNames[strings.ToLower(f.APIName)] = f.APIName
	}
	if len(fieldNames) == 0 {
		return data
	}
	out := make(map[string]interface{}, len(data))
	for key, value := range data {
		if key == "attributes" {
			out[key] = value
			continue
		}
		if actual, ok := fieldNames[strings.ToLower(key)]; ok {
			out[actual] = value
			continue
		}
		out[key] = value
	}
	return out
}

// fieldRequiresUserInputOnCreate reports whether the public create path will
// demand a value for this field from the caller, independent of any particular
// request payload.
//
// It exists so the layout projection can ask the same question the validator
// asks. A layout may author a field hidden on create; hiding one the validator
// will then demand produces a save failure naming a field the user cannot see,
// so the projection clamps that case. Sharing one implementation is what keeps
// the clamp and the validator from drifting — a field newly exempted here is
// exempted in both places at once.
//
// The payload-dependent half of the skip chain stays in the validator:
// fieldSatisfiedByNameComponents asks whether THIS request supplied the parts
// of a compound name, which the projection has no request to inspect.
func fieldRequiresUserInputOnCreate(schema *models.ObjectMetadata, f *models.FieldMetadata) bool {
	if schema == nil || f == nil || !f.Required {
		return false
	}
	if isCompound, _ := fieldprovenance.ClassifyCompound(schema.APIName, f.APIName); isCompound {
		return false
	}
	if f.DefaultValue != nil && *f.DefaultValue != "" {
		return false
	}
	if f.DefaultedOnCreate {
		return false
	}
	if isAuditField(f.APIName) {
		return false
	}
	switch f.Type {
	case constants.FieldTypeAutonumber,
		constants.FieldTypeFormula,
		constants.FieldTypeRollupSummary:
		return false
	}
	return true
}

func validateRequiredForCreate(schema *models.ObjectMetadata, data map[string]interface{}) error {
	var missing []string
	for i := range schema.Fields {
		f := schema.Fields[i]
		if !fieldRequiresUserInputOnCreate(schema, &f) {
			continue
		}
		if fieldSatisfiedByNameComponents(schema, f, data) {
			continue
		}
		v, present := data[f.APIName]
		if !present || isEmptyFieldValue(v) {
			missing = append(missing, f.APIName)
		}
	}
	if len(missing) == 0 {
		return nil
	}
	return NewValidationError(
		strings.Join(missing, ","),
		fmt.Sprintf("required field(s) missing: %s", strings.Join(missing, ", ")),
	)
}

func fieldSatisfiedByNameComponents(schema *models.ObjectMetadata, field models.FieldMetadata, data map[string]interface{}) bool {
	if schema == nil || !strings.EqualFold(field.APIName, constants.FieldName) {
		return false
	}
	if !schemaHasField(schema, constants.FieldName) {
		return false
	}
	for _, component := range compoundMemberNames(schema, field.APIName) {
		if !isEmptyFieldValue(data[component]) {
			return true
		}
	}
	return false
}

func isEmptyFieldValue(v interface{}) bool {
	if v == nil {
		return true
	}
	if s, ok := v.(string); ok {
		return strings.TrimSpace(s) == ""
	}
	return false
}

func isAuditField(fieldName string) bool {
	switch fieldName {
	case constants.FieldID,
		constants.FieldCreatedDate,
		constants.FieldCreatedByID,
		constants.FieldLastModifiedDate,
		constants.FieldLastModifiedByID,
		constants.FieldIsDeleted,
		"SystemModstamp":
		return true
	}
	return false
}

func insertedRecordID(result map[string]interface{}) (string, bool) {
	if id, ok := result[constants.FieldID].(string); ok && id != "" {
		return id, true
	}
	if id, ok := result["id"].(string); ok && id != "" {
		return id, true
	}
	return "", false
}

func schemaHasField(schema *models.ObjectMetadata, apiName string) bool {
	if schema == nil {
		return false
	}
	for _, field := range schema.Fields {
		if strings.EqualFold(field.APIName, apiName) {
			return true
		}
	}
	return false
}

func synthesizeVirtualCompoundFields(schema *models.ObjectMetadata, record models.SObject, fieldVisible func(fieldAPIName string) bool) {
	if schema == nil || record == nil {
		return
	}
	for i := range schema.Fields {
		f := &schema.Fields[i]
		if !f.IsVirtual || f.VirtualKind != constants.VirtualFieldCompound {
			continue
		}
		if fieldVisible != nil && !fieldVisible(f.APIName) {
			continue
		}
		if !compoundMembersFullyReadable(schema, record, f.APIName, fieldVisible) {
			continue
		}
		if existing, ok := record[f.APIName]; ok && !isBlankCompoundValue(existing) {
			continue
		}
		if value, ok := compoundFieldValue(schema, f.APIName, record); ok {
			record[f.APIName] = value
		}
	}
}

func compoundMembersFullyReadable(schema *models.ObjectMetadata, record models.SObject, parentAPIName string, fieldVisible func(fieldAPIName string) bool) bool {
	members := compoundMemberNames(schema, parentAPIName)
	if len(members) == 0 {
		return false
	}
	for _, member := range members {
		if fieldVisible != nil && !fieldVisible(member) {
			return false
		}
		if _, present := lookupCaseInsensitive(record, member); !present {
			return false
		}
	}
	return true
}

func lookupCaseInsensitive(data map[string]interface{}, key string) (interface{}, bool) {
	if data == nil {
		return nil, false
	}
	if value, ok := data[key]; ok {
		return value, true
	}
	for existingKey, value := range data {
		if strings.EqualFold(existingKey, key) {
			return value, true
		}
	}
	return nil, false
}

func isBlankCompoundValue(value interface{}) bool {
	if value == nil {
		return true
	}
	if s, ok := value.(string); ok {
		return strings.TrimSpace(s) == ""
	}
	return false
}

func isNotFoundError(err error) bool {
	if err == nil {
		return false
	}
	if sharederrors.IsNotFound(err) {
		return true
	}
	var statusErr httpStatusError
	return errors.As(err, &statusErr) && statusErr.HTTPStatus() == http.StatusNotFound
}
