package automation

import (
	"strings"
	"testing"

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

func TestBuildFlowRecordLookupProfilePlanBatchableDynamicEquality(t *testing.T) {
	interview := &models.FlowInterview{
		ContextData: map[string]interface{}{
			"$Record": models.SObject{models.ObjectTypeMetadataKey: "Contact"},
		},
	}
	lookup := &models.FlowRecordLookup{
		Object:             "Lead",
		FilterLogic:        "and",
		GetFirstRecordOnly: false,
		Filters: []models.FlowRecordFilter{
			{
				Field:    "HubSpot_Id__c",
				Operator: "EqualTo",
				Value:    map[string]interface{}{"elementReference": "sourceID"},
			},
			{
				Field:    "IsConverted",
				Operator: "NotEqualTo",
				Value:    true,
			},
		},
	}

	plan := buildFlowRecordLookupProfilePlan(interview, lookup)

	if !plan.batchable {
		t.Fatalf("batchable = false, reason = %q; want true", plan.reason)
	}
	if plan.reason != "ok" {
		t.Fatalf("reason = %q; want ok", plan.reason)
	}
	if plan.keyField != "HubSpot_Id__c" {
		t.Fatalf("keyField = %q; want HubSpot_Id__c", plan.keyField)
	}
	if !plan.crossObject {
		t.Fatal("crossObject = false; want true")
	}
	if !strings.Contains(plan.shape, "hubspot_id__c:EQUALTO:ref:sourceid") {
		t.Fatalf("shape = %q; missing dynamic reference shape", plan.shape)
	}
	if !strings.Contains(plan.shape, "isconverted:NOTEQUALTO:literal:bool:true") {
		t.Fatalf("shape = %q; missing static predicate shape", plan.shape)
	}
}

func TestBuildFlowRecordLookupProfilePlanRejectsDynamicNonEquality(t *testing.T) {
	lookup := &models.FlowRecordLookup{
		Object:      "Lead",
		FilterLogic: "and",
		Filters: []models.FlowRecordFilter{
			{
				Field:    "CreatedDate",
				Operator: "GreaterThan",
				Value:    map[string]interface{}{"elementReference": "cutoff"},
			},
		},
	}

	plan := buildFlowRecordLookupProfilePlan(nil, lookup)

	if plan.batchable {
		t.Fatal("batchable = true; want false")
	}
	if plan.reason != "dynamic_non_eq" {
		t.Fatalf("reason = %q; want dynamic_non_eq", plan.reason)
	}
}

func TestBuildFlowRecordLookupProfilePlanRejectsConstantOnlyLookup(t *testing.T) {
	lookup := &models.FlowRecordLookup{
		Object:             "User",
		FilterLogic:        "and",
		GetFirstRecordOnly: true,
		Filters: []models.FlowRecordFilter{
			{
				Field:    "Email",
				Operator: "EqualTo",
				Value:    "noreply@example.invalid",
			},
			{
				Field:    "IsActive",
				Operator: "EqualTo",
				Value:    true,
			},
		},
	}

	plan := buildFlowRecordLookupProfilePlan(nil, lookup)

	if plan.batchable {
		t.Fatal("batchable = true; want false")
	}
	if plan.reason != "no_dynamic_eq" {
		t.Fatalf("reason = %q; want no_dynamic_eq", plan.reason)
	}
	if strings.Contains(plan.shape, "noreply@example.invalid") {
		t.Fatalf("shape leaked literal value: %q", plan.shape)
	}
}
