package formula

import (
	"strings"

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

// WriteMaterializedFormulaRef captures the metadata needed to statically
// validate a formula whose resolved storage path writes to a physical column.
type WriteMaterializedFormulaRef struct {
	FormulaMode            string
	FormulaStorageMode     string
	Formula                string
	HasProjectionConfig    bool
	Schema                 *models.ObjectMetadata
	SchemasByObjectAPIName map[string]*models.ObjectMetadata
	ExpectedType           *models.FieldType
}

// ValidateWriteMaterializedFormulaRef runs the frozen-formula static syntax and
// schema checks only when formulastorage.Resolve says the field writes to
// physical storage. View-backed active formulas stay on the existing
// formula-view validation path.
func ValidateWriteMaterializedFormulaRef(ref WriteMaterializedFormulaRef, engine *Engine) error {
	if engine == nil {
		return nil
	}

	resolved, err := formulastorage.Resolve(formulastorage.Spec{
		FormulaMode:         strings.TrimSpace(ref.FormulaMode),
		FormulaStorageMode:  strings.TrimSpace(ref.FormulaStorageMode),
		Formula:             ref.Formula,
		HasProjectionConfig: ref.HasProjectionConfig,
	})
	if err != nil {
		return err
	}
	if !resolved.IsWriteMaterialized() || strings.TrimSpace(ref.Formula) == "" {
		return nil
	}
	return engine.validateSyntaxWithSchema(ref.Formula, ref.Schema, ref.SchemasByObjectAPIName, ref.ExpectedType)
}
