#ifndef EDITSCENE_GOAP_EXPRESSION_HPP
#define EDITSCENE_GOAP_EXPRESSION_HPP
#pragma once

#include "GoapBlackboard.hpp"
#include <string>

/**
 * Simple expression evaluator for GOAP goal conditions.
 *
 * Supports:
 *   - Variable names (looked up in blackboard values, default 0)
 *   - Integer literals
 *   - Comparisons: ==, !=, <, >, <=, >=
 *   - Boolean operators: &&, ||
 *   - Parentheses for grouping
 *   - Unary negation: !
 *
 * Example: "health > 20 && (hunger > 50 || have_food == 1)"
 */
class GoapExpression {
public:
	GoapExpression() = default;

	// Parse an expression string. Returns true on success.
	bool parse(const char *expr);

	// Evaluate the parsed expression against a blackboard.
	// Returns false if expression was not parsed successfully.
	bool evaluate(const GoapBlackboard &blackboard) const;

	// Get last error message
	const std::string &getError() const { return m_error; }

private:
	struct Node {
		enum Type {
			Value,     // integer literal
			Variable,  // blackboard variable name
			Equal,
			NotEqual,
			Less,
			Greater,
			LessEqual,
			GreaterEqual,
			And,
			Or,
			Not
		} type;
		int value = 0;           // for Value
		std::string name;        // for Variable
		Node *left = nullptr;
		Node *right = nullptr;

		Node(Type t)
			: type(t)
		{
		}
		~Node()
		{
			delete left;
			delete right;
		}
	};

	const char *m_expr = nullptr;
	const char *m_pos = nullptr;
	std::string m_error;
	Node *m_root = nullptr;

	void skipWhitespace();
	bool match(const char *s);
	Node *parseExpression(); // ||
	Node *parseAnd();        // &&
	Node *parseNot();        // !
	Node *parseComparison(); // ==, !=, <, >, <=, >=
	Node *parsePrimary();    // value, variable, (expr)

	int evalNode(Node *node, const GoapBlackboard &bb) const;

	void setError(const char *msg);
	void clear();
};

#endif // EDITSCENE_GOAP_EXPRESSION_HPP
