package automation

import (
	"context"
	"fmt"
	"strings"

	"github.com/nexuscrm/shared/pkg/models"
)

func (e *FlowExecutor) pushToConnectorPayloadSourceRecord(ctx context.Context, sourceObject string, record models.SObject, payloadSourceFields []string) (models.SObject, error) {
	if len(record) == 0 {
		return nil, fmt.Errorf("PushToConnector: triggering source snapshot is required for outbound payload")
	}
	payloadRecord := make(models.SObject, len(record)+len(payloadSourceFields))
	for key, value := range record {
		payloadRecord[key] = value
	}
	e.aliasPushToConnectorPayloadFields(ctx, sourceObject, payloadRecord, payloadSourceFields)
	return payloadRecord, nil
}

func (e *FlowExecutor) aliasPushToConnectorPayloadFields(ctx context.Context, sourceObject string, record models.SObject, payloadSourceFields []string) {
	if e == nil || len(record) == 0 || len(payloadSourceFields) == 0 {
		return
	}
	for _, sourceField := range payloadSourceFields {
		sourceField = strings.TrimSpace(sourceField)
		if sourceField == "" {
			continue
		}
		if _, ok := record[sourceField]; ok {
			continue
		}
		if value, ok := lookupRecordFieldValue(record, sourceField); ok {
			record[sourceField] = value
		}
	}
	schema := e.lookupObjectSchema(ctx, sourceObject)
	if schema == nil || len(schema.Fields) == 0 {
		return
	}
	fieldsByAPIName := make(map[string]models.FieldMetadata, len(schema.Fields))
	for _, field := range schema.Fields {
		if apiName := strings.TrimSpace(field.APIName); apiName != "" {
			fieldsByAPIName[strings.ToLower(apiName)] = field
		}
	}
	for _, sourceField := range payloadSourceFields {
		sourceField = strings.TrimSpace(sourceField)
		if sourceField == "" {
			continue
		}
		if _, ok := record[sourceField]; ok {
			continue
		}
		field, ok := fieldsByAPIName[strings.ToLower(sourceField)]
		if !ok {
			continue
		}
		apiName := strings.TrimSpace(field.APIName)
		physicalName := pushToConnectorPhysicalFieldName(apiName, field.PhysicalName)
		if physicalName == "" || strings.EqualFold(physicalName, apiName) {
			continue
		}
		if value, ok := lookupRecordFieldValue(record, physicalName); ok {
			record[sourceField] = value
		}
	}
}

func pushToConnectorPhysicalFieldName(apiName, physicalName string) string {
	physicalName = strings.TrimSpace(physicalName)
	if physicalName == "" {
		return strings.TrimSpace(apiName)
	}
	if strings.HasPrefix(physicalName, "`") && strings.HasSuffix(physicalName, "`") {
		return strings.TrimSpace(apiName)
	}
	return physicalName
}
