package persistence

import (
	"database/sql/driver"
	"testing"

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

func TestPrepareFieldDBMap_PersistsFormulaStorageMode(t *testing.T) {
	repo := NewSchemaRepository(nil, nil)
	activeMode := "active"
	writeMaterialized := "write_materialized"
	returnType := models.FieldType(constants.FieldTypeString)

	values, err := repo.prepareFieldDBMap(&models.FieldMetadata{
		APIName:            "NameStored",
		Label:              "Name Stored",
		Type:               constants.FieldTypeFormula,
		Formula:            stringPtrSFST("Name"),
		FormulaMode:        &activeMode,
		FormulaStorageMode: &writeMaterialized,
		ReturnType:         &returnType,
	}, "obj_workitem", "fld_workitem_namestored")
	if err != nil {
		t.Fatalf("prepareFieldDBMap() error = %v", err)
	}
	if got := values[constants.FieldSysField_FormulaStorageMode]; got == nil {
		t.Fatal("prepareFieldDBMap() omitted FormulaStorageMode")
	}
}

func TestBuildFieldMetadataFromColumn_PreservesFormulaStorageMode(t *testing.T) {
	repo := NewSchemaRepository(nil, nil)
	field := repo.buildFieldMetadataFromColumn(domainschema.ColumnDefinition{
		Name:               "NameStored",
		Label:              "Name Stored",
		Type:               "VARCHAR(255)",
		LogicalType:        string(constants.FieldTypeFormula),
		Formula:            "Name",
		FormulaMode:        "active",
		FormulaStorageMode: "write_materialized",
		ReturnType:         string(constants.FieldTypeString),
	})
	if field.FormulaStorageMode == nil || *field.FormulaStorageMode != "write_materialized" {
		t.Fatalf("buildFieldMetadataFromColumn() FormulaStorageMode = %#v, want write_materialized", field.FormulaStorageMode)
	}
}

func systemFieldRowValuesWithFormulaStorageMode(objectID, apiName, fieldType string, referenceTo interface{}, formulaStorageMode interface{}) []driver.Value {
	values := systemFieldRowValues(objectID, apiName, fieldType, referenceTo)
	values[20] = formulaStorageMode
	return values
}

func stringPtrSFST(v string) *string { return &v }
