package metadata

import (
	"context"
	"strings"
	"testing"

	"github.com/nexuscrm/kernel/pkg/formula"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

func TestValidateRecordRejectsInvalidStaticPicklistOption(t *testing.T) {
	vs := NewValidationService(formula.NewEngine())
	schema := &models.ObjectMetadata{
		APIName: "WorkItem",
		Fields: []models.FieldMetadata{
			{
				APIName: "Status__c",
				Type:    constants.FieldTypePicklist,
				Options: models.PicklistOptionsFromStrings([]string{
					"Open",
					"Closed",
				}),
			},
		},
	}

	err := vs.ValidateRecord(context.Background(), models.SObject{"Status__c": "Blocked"}, schema, nil, nil, nil)
	if err == nil {
		t.Fatal("ValidateRecord() error = nil, want invalid static picklist option rejection")
	}
	if !strings.Contains(err.Error(), "active picklist option") {
		t.Fatalf("ValidateRecord() error = %v, want active picklist option rejection", err)
	}
}

func TestValidateRecordSkipsStaticOptionsForRuntimeScopedPicklist(t *testing.T) {
	vs := NewValidationService(formula.NewEngine())
	validatorName := " Runtime_Scoped_Picklist "
	controllerField := "ParentId"
	schema := &models.ObjectMetadata{
		APIName: "WorkItem",
		Fields: []models.FieldMetadata{
			{
				APIName:     controllerField,
				Type:        constants.FieldTypeReference,
				ReferenceTo: []string{"Parent"},
			},
			{
				APIName:          "Status__c",
				Type:             constants.FieldTypePicklist,
				Options:          models.PicklistOptionsFromStrings([]string{"Open", "Closed"}),
				Validator:        &validatorName,
				ControllingField: &controllerField,
				ReferenceTo:      []string{"StatusCatalog"},
			},
		},
	}

	err := vs.ValidateRecord(context.Background(), models.SObject{
		"ParentId":  "001000000000001",
		"Status__c": "Blocked",
	}, schema, nil, nil, nil)
	if err != nil {
		t.Fatalf("ValidateRecord() error = %v, want nil", err)
	}
}

func TestValidateRecordDefersRuntimeScopedPicklistRequiredness(t *testing.T) {
	vs := NewValidationService(formula.NewEngine())
	validatorName := models.RuntimeScopedPicklistValidator
	controllerField := "ParentId"
	schema := &models.ObjectMetadata{
		APIName: "WorkItem",
		Fields: []models.FieldMetadata{
			{
				APIName: controllerField,
				Type:    constants.FieldTypeReference,
			},
			{
				APIName:          "Status__c",
				Type:             constants.FieldTypePicklist,
				Required:         true,
				Validator:        &validatorName,
				ControllingField: &controllerField,
				ReferenceTo:      []string{"StatusCatalog"},
			},
		},
	}

	if err := vs.ValidateRecord(context.Background(), models.SObject{}, schema, nil, nil, nil); err != nil {
		t.Fatalf("ValidateRecord() error = %v, want runtime-scoped requiredness deferred to records", err)
	}
}

func TestValidateRecordTrimsWhitespaceOnStaticPicklistOption(t *testing.T) {
	vs := NewValidationService(formula.NewEngine())
	schema := &models.ObjectMetadata{
		APIName: "Account",
		Fields: []models.FieldMetadata{
			{
				APIName: "Sales_Territory_NA_Only__c",
				Type:    constants.FieldTypePicklist,
				Options: models.PicklistOptionsFromStrings([]string{
					"Northwest (AK, WA, OR, ID, BC, AB)",
					"California (NorCal - Bay Area south)",
					"  Whitespace Sensitive  ",
				}),
			},
		},
	}

	accepted := map[string]interface{}{
		"carriage-return only":              "\r",
		"whitespace only":                   "   ",
		"exact whitespace-sensitive option": "  Whitespace Sensitive  ",
		"trailing CR on option":             "California (NorCal - Bay Area south)\r",
		"surrounding space on option":       "  Northwest (AK, WA, OR, ID, BC, AB)  ",
		"nil value":                         nil,
		"non-string value":                  123,
	}
	for name, value := range accepted {
		t.Run("accepts/"+name, func(t *testing.T) {
			err := vs.ValidateRecord(context.Background(), models.SObject{"Sales_Territory_NA_Only__c": value}, schema, nil, nil, nil)
			if err != nil {
				t.Fatalf("ValidateRecord(%#v) error = %v, want nil", value, err)
			}
		})
	}

	t.Run("rejects genuine non-member after trimming", func(t *testing.T) {
		err := vs.ValidateRecord(context.Background(), models.SObject{"Sales_Territory_NA_Only__c": "Atlantis\r"}, schema, nil, nil, nil)
		if err == nil || !strings.Contains(err.Error(), "active picklist option") {
			t.Fatalf("ValidateRecord() error = %v, want active picklist option rejection", err)
		}
	})
}
