package analytics

// Node is the interface for all AST nodes in the formula DSL.
type Node interface {
	nodeType() string
}

// --- Literal nodes ---

// NumberLit represents a numeric literal (e.g. 3.14).
type NumberLit struct {
	Value string
}

func (n *NumberLit) nodeType() string { return "NumberLit" }

// StringLit represents a string literal (e.g. 'hello').
type StringLit struct {
	Value string
}

func (n *StringLit) nodeType() string { return "StringLit" }

// BoolLit represents TRUE or FALSE.
type BoolLit struct {
	Value bool
}

func (n *BoolLit) nodeType() string { return "BoolLit" }

// NullLit represents NULL.
type NullLit struct{}

func (n *NullLit) nodeType() string { return "NullLit" }

// --- Reference nodes ---

// FieldRef is a simple field reference (e.g. Amount, Name).
type FieldRef struct {
	Name string
}

func (n *FieldRef) nodeType() string { return "FieldRef" }

// CrossRef is a cross-table field reference (e.g. Parent__r.Name, Owner.Name).
type CrossRef struct {
	Object string // "Parent__r", "Owner"
	Field  string // "Name"
}

func (n *CrossRef) nodeType() string { return "CrossRef" }

// DeepCrossRef is a multi-level cross-table reference (e.g. Parent.Manager.Name).
// Parts contains all segments: ["Parent", "Manager", "Name"].
type DeepCrossRef struct {
	Parts []string // e.g. ["Parent", "Manager", "Name"]
}

func (n *DeepCrossRef) nodeType() string { return "DeepCrossRef" }

// --- Expression nodes ---

// BinaryOp represents a binary operation (e.g. a + b, a = b).
type BinaryOp struct {
	Op    string // "+", "-", "*", "/", "^", "=", "!=", "<", "<=", ">", ">=", "&"
	Left  Node
	Right Node
}

func (n *BinaryOp) nodeType() string { return "BinaryOp" }

// UnaryOp represents a unary operation (e.g. -x, NOT x).
type UnaryOp struct {
	Op      string // "-", "NOT"
	Operand Node
}

func (n *UnaryOp) nodeType() string { return "UnaryOp" }

// LogicalOp represents AND / OR with multiple operands.
type LogicalOp struct {
	Op       string // "AND", "OR"
	Operands []Node
}

func (n *LogicalOp) nodeType() string { return "LogicalOp" }

// --- Function call nodes ---

// FuncCall represents a function call: FUNC(arg1, arg2, ...).
type FuncCall struct {
	Name string
	Args []Node
}

func (n *FuncCall) nodeType() string { return "FuncCall" }

// --- Conditional nodes ---

// IfExpr represents IF(condition, thenVal, elseVal).
type IfExpr struct {
	Condition Node
	Then      Node
	Else      Node
}

func (n *IfExpr) nodeType() string { return "IfExpr" }

// CaseExpr represents CASE(expr, val1, result1, val2, result2, ..., elseResult).
// This is the SF-style CASE, not SQL CASE WHEN.
type CaseExpr struct {
	Expr     Node         // The expression being compared
	Branches []CaseBranch // val → result pairs
	Default  Node         // else result
}

type CaseBranch struct {
	Value  Node
	Result Node
}

func (n *CaseExpr) nodeType() string { return "CaseExpr" }

// --- Aggregate node (for rollup formulas) ---

// AggregateExpr represents SUM(Object.Field), COUNT(Object.Field), etc.
type AggregateExpr struct {
	Func        string // SUM, COUNT, MIN, MAX, AVG
	ChildObject string // e.g. "Child__c"
	ChildField  string // e.g. "Amount" (empty for COUNT)
	ForeignKey  string // e.g. "Parent__c" — FK on child pointing to parent
}

func (n *AggregateExpr) nodeType() string { return "AggregateExpr" }
