package packs

import (
	"strings"

	"github.com/nexuscrm/kernel/pkg/formula"
)

func (p *SourceBackedPack) runtimeFormulaFunctionBundlesForValidation() []formula.FunctionBundle {
	if p == nil {
		return nil
	}
	if p.hasFormulaFunctionBundlesForValidation {
		bundles := formulaFunctionBundlesExcludingSourceFunctions(p.formulaFunctionBundlesForValidation, p.formulaFunctionBundles)
		bundles = append(bundles, formula.CloneFunctionBundles(p.formulaFunctionBundles)...)
		return formula.CloneFunctionBundles(bundles)
	}
	return formula.CloneFunctionBundles(p.formulaFunctionBundles)
}

func formulaFunctionBundlesExcludingSourceFunctions(bundles []formula.FunctionBundle, sourceBundles []formula.FunctionBundle) []formula.FunctionBundle {
	sourceFunctionNames := map[string]bool{}
	for _, bundle := range sourceBundles {
		for _, fn := range bundle.Functions {
			name := strings.TrimSpace(fn.Name)
			if name != "" {
				sourceFunctionNames[name] = true
			}
		}
	}
	if len(sourceFunctionNames) == 0 {
		return formula.CloneFunctionBundles(bundles)
	}

	out := make([]formula.FunctionBundle, 0, len(bundles))
	for _, bundle := range bundles {
		filtered := formula.FunctionBundle{}
		for _, fn := range bundle.Functions {
			name := strings.TrimSpace(fn.Name)
			if name != "" && sourceFunctionNames[name] {
				continue
			}
			filtered.Functions = append(filtered.Functions, fn)
		}
		if len(filtered.Functions) > 0 {
			out = append(out, filtered)
		}
	}
	return formula.CloneFunctionBundles(out)
}

// VerifySourceBackedPackWriteMaterializedFormulaPayload statically validates
// every pack-owned formula whose resolved storage mode writes to a physical
// column. View-backed active formulas stay on the formula-view compile path.
func VerifySourceBackedPackWriteMaterializedFormulaPayload(pack *SourceBackedPack) error {
	if pack == nil {
		return nil
	}
	for _, component := range pack.components {
		objectComponent, ok := component.(*sourceBackedObjectSpecComponent)
		if !ok {
			continue
		}
		if err := verifyWriteMaterializedFormulaPayloadForObjectSpecComponent(objectComponent, pack.runtimeFormulaFunctionBundlesForValidation()); err != nil {
			return err
		}
	}
	return nil
}
