from __future__ import annotations
import logging
import xml.etree.ElementTree as ET
from typing import Dict, Callable, Any, Optional
import os
from enum import Enum, auto
from equipment_calculation.expressioncalculator import ExpressionCalculator
import copy


# 配置logging
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[logging.FileHandler("bcl_calculator.log"), logging.StreamHandler()],
)


class BCLVariantType(Enum):
    TEXT = "文本"
    FLOAT = "浮点数"
    INTEGER = "整形"
    BOOLEAN = "布尔类型"
    DATASOURCE = "数据源"
    EXPRESSION = "表达式"
    # NULL = "NULL"


class BCLOperatorType(Enum):
    """
    BCL运算符类型枚举
    """

    ADD = "+"  # 加
    SUBTRACT = "-"  # 减
    MULTIPLY = "*"  # 乘
    DIVIDE = "/"  # 除
    AND = "&&"  # 与
    OR = "||"  # 或
    NOT = "!"  # 非
    EQUAL = "=="  # 等于
    NOT_EQUAL = "!="  # 不等于
    GREATER = ">"
    GREATER_EQUAL = ">="
    LESS = "<"
    LESS_EQUAL = "<="
    UNKNOWN = "unknown"  # 未知运算符


def str_to_operator(op_str: str) -> BCLOperatorType:
    """
    将字符串转换为BCLOperatorType枚举
    :param op_str: 运算符字符串
    :return: 对应的BCLOperatorType枚举值
    """
    op_map = {
        ">": BCLOperatorType.GREATER,
        ">=": BCLOperatorType.GREATER_EQUAL,
        "<": BCLOperatorType.LESS,
        "<=": BCLOperatorType.LESS_EQUAL,
        "+": BCLOperatorType.ADD,
        "-": BCLOperatorType.SUBTRACT,
        "*": BCLOperatorType.MULTIPLY,
        "/": BCLOperatorType.DIVIDE,
        "&&": BCLOperatorType.AND,
        "||": BCLOperatorType.OR,
        "!": BCLOperatorType.NOT,
        "==": BCLOperatorType.EQUAL,
        "!=": BCLOperatorType.NOT_EQUAL,
        "加": BCLOperatorType.ADD,
        "减": BCLOperatorType.SUBTRACT,
        "乘": BCLOperatorType.MULTIPLY,
        "除": BCLOperatorType.DIVIDE,
        "与": BCLOperatorType.AND,
        "或": BCLOperatorType.OR,
        "非": BCLOperatorType.NOT,
        "等于": BCLOperatorType.EQUAL,
        "不等于": BCLOperatorType.NOT_EQUAL,
    }

    if op_str is None:
        return BCLOperatorType.UNKNOWN

    return op_map.get(op_str.strip(), BCLOperatorType.UNKNOWN)


class BCLVariant:
    def _setobject(self, var_type: BCLVariantType, value):
        self.type = var_type
        self.value = value

    def __init__(self, value: Any):
        """
        根据value的类型自动确定变量类型
        :param value: 变量值，可以是str, ET.Element, float, int, bool或list类型
        """
        if isinstance(value, BCLVariant):
            return self._setobject(value.type, value.value)
        if isinstance(value, str):
            return self._setobject(BCLVariantType.TEXT, value)
        elif isinstance(value, ET.Element):
            return self._setobject(BCLVariantType.EXPRESSION, value)
        elif isinstance(value, list):
            return self._setobject(BCLVariantType.DATASOURCE, value)
        elif isinstance(value, bool):
            return self._setobject(BCLVariantType.BOOLEAN, value)
        elif isinstance(value, float):
            return self._setobject(BCLVariantType.FLOAT, value)
        elif isinstance(value, int):
            return self._setobject(BCLVariantType.INTEGER, value)
        elif value == None:
            # return self._setobject(BCLVariantType.NULL, "")
            return self._setobject(BCLVariantType.TEXT, "")
        else:
            raise ValueError(f"不支持的类型: {type(value)}")

    def get_value(self) -> Any:
        """
        获取变量值
        :return: 变量值，转换为浮点数
        """
        try:
            if self.type == BCLVariantType.TEXT:
                return self.value
            elif self.type == BCLVariantType.DATASOURCE:
                return self.value.get_value()
            elif self.type == BCLVariantType.FLOAT:
                return float(self.value)
            elif self.type == BCLVariantType.INTEGER:
                return int(self.value)
            elif self.type == BCLVariantType.EXPRESSION:
                return self.value
            elif self.type == BCLVariantType.BOOLEAN:
                return bool(self.value)
            else:
                raise ValueError(f"未知的变量类型: {self.type}")
        except (ValueError, TypeError) as e:
            raise ValueError(f"获取变量的值发生错误: {str(e)}\n")

    def __str__(self) -> str:
        """
        返回变量的字符串表示
        :return: 变量的字符串表示
        """
        return f"Variant({self.type}, {self.value})"


# BCL上下文类（用于供计算过程中从该类中获取变量值）
class BCLContext:
    def __init__(self, valueDict: Dict[str, Any] = None, **kwargs):
        self.variables = {}  # 变量字典，键为变量名，值为BCLVariant对象
        self.params = {}  # 参数字典，键为字符串，单独存储参数

        if valueDict:
            for key, value in valueDict.items():
                if isinstance(value, BCLVariant):
                    self.variables[key] = value
                else:
                    self.variables[key] = BCLVariant(value.__dict__)

    def _get_variable_value(self, var_name: str) -> BCLVariant:
        """
        获取变量值
        :param var_name: 变量名，格式为'对象.属性'
        :return: 变量值,如果变量不存在则返回None，请勿抛出异常
        """
        return self.variables.get(var_name)

    def get_variable_value(self, var_name: str) -> BCLVariant:
        """
        获取变量值
        :param var_name: 变量名，格式为'对象.属性'
        :return: 变量值,如果变量不存在则返回None，请勿抛出异常
        """
        var = self._get_variable_value(var_name)
        if var:
            return var
        else:
            return None

    def set_param(self, key: str, value):
        """
        设置参数到参数字典
        :param key: 参数键，必须为字符串
        :param value: 参数值
        """
        if not isinstance(key, str):
            raise TypeError("参数键必须是字符串类型")
        self.params[key] = value

    def get_param(self, key: str, default=None):
        """
        从参数字典获取参数
        :param key: 参数键，必须为字符串
        :param default: 默认值，如果参数不存在则返回
        :return: 参数值或默认值
        """
        if not isinstance(key, str):
            raise TypeError("参数键必须是字符串类型")
        return self.params.get(key, default)


# 链式BCL上下文类，用于将两个上下文对象穿成一个链表，从而实现依次从两个上下文中获取变量值（该类是抽象类，不支持直接使用）
class BCLPrevContext(BCLContext):
    def __init__(self, prevContext: BCLContext = None):
        super().__init__()
        self._prevContext = prevContext

    def _get_variable_value(self, var_name: str) -> BCLVariant:
        """
        获取变量值，支持点号分隔的变量名查询
        :param var_name: 变量名，可以是简单变量名或'对象.属性'格式
        :return: 找到的变量或None
        """
        result = super()._get_variable_value(var_name)
        if result == None and self._prevContext:
            # 如果当前对象没有找到变量，尝试在前一个上下文中查找
            try:
                result = self._prevContext._get_variable_value(var_name)
            except ValueError:
                pass

        return result

    def set_param(self, key: str, value):
        """
        设置参数到参数字典
        :param key: 参数键，必须为字符串
        :param value: 参数值
        """
        if not isinstance(key, str):
            raise TypeError("参数键必须是字符串类型")
        if self._prevContext:
            self._prevContext.set_param(key, value)
        else:
            super().set_param(key, value)

    def get_param(self, key: str, default=None):
        """
        从参数字典获取参数
        :param key: 参数键，必须为字符串
        :param default: 默认值，如果参数不存在则返回
        :return: 参数值或默认值
        """
        if not isinstance(key, str):
            raise TypeError("参数键必须是字符串类型")
        result = super().get_param(key, default)
        if result == None and self._prevContext:
            result = self._prevContext.get_param(key, default)
        return result


# 前缀BCL上下文类，用于将一个上下文对象与一个前缀绑定，从而实现从该上下文中获取变量值
class BCLPrefixContext(BCLContext):
    def __init__(self, prefix: str, childContext: BCLContext):
        self._childContext = childContext
        self._prefix = prefix

    def __init__(self, prefix: str, valueDict: Dict[str, Any] = None):
        self._childContext = BCLContext(valueDict)
        self._prefix = prefix

    def _get_variable_value(self, var_name: str) -> BCLVariant:
        """
        获取变量值，支持点号分隔的变量名查询
        :param var_name: 变量名，可以是简单变量名或'对象.属性'格式
        :return: 找到的变量或None
        """
        result = None
        # 检查是否是点号分隔的两段式变量名
        if "." in var_name:
            parts = var_name.split(".", maxsplit=1)
            if len(parts) >= 2 and parts[0] == self._prefix:
                # 如果是当前数据对象的属性，则查询对应的变量
                try:
                    result = self._childContext._get_variable_value(parts[1])
                except ValueError:
                    pass
        return result


# 前缀链式BCL上下文类，用于将一个上下文对象与一个前缀绑定，从而实现从该上下文中获取变量值
class BCLPrefixPrevContext(BCLPrefixContext, BCLPrevContext):
    def __init__(self, prefix: str, childContext: BCLContext, prevContext: BCLContext = None):
        BCLPrefixContext.__init__(self, prefix, childContext)
        BCLPrevContext.__init__(self, prevContext)

    def __init__(self, prefix: str, valueDict: Dict[str, Any], prevContext: BCLContext = None):
        BCLPrefixContext.__init__(self, prefix, valueDict)
        BCLPrevContext.__init__(self, prevContext)

    def _get_variable_value(self, var_name: str) -> BCLVariant:
        """
        获取变量值，支持点号分隔的变量名查询
        :param var_name: 变量名，可以是简单变量名或'对象.属性'格式
        :return: 找到的变量或None
        """
        result = BCLPrefixContext._get_variable_value(self, var_name)
        if result == None:
            # 如果当前对象没有找到变量，尝试在前一个上下文中查找
            try:
                result = BCLPrevContext._get_variable_value(self, var_name)
            except ValueError:
                pass

        return result


class BCLDataSourceItem:

    def __init__(self, valueDict: Any, parent: BCLDataSourceItem = None, data_name: str = ""):
        self.variables = {}  # 变量字典，键为变量名，值为BCLVariant对象
        self._parent = parent
        self._childs = []
        self._dataname: str = data_name

        # 处理值字典
        if valueDict:
            items = valueDict if isinstance(valueDict, Dict) else valueDict.__dict__

            # 将所有属性添加到变量字典中
            for key, value in items.items():
                if isinstance(value, BCLVariant):
                    self.variables[key] = value
                else:
                    self.variables[key] = BCLVariant(value)

            # 检查是否有子节点列表（children 或其他名称）
            if "children" in items:
                child_nodes = items["children"]
                if isinstance(child_nodes, list):
                    # 为每个子节点创建 BCLDataSourceItem 对象
                    self._childs = [BCLDataSourceItem(child, self) for child in child_nodes]

    def get_dataname(self) -> str:
        return self._dataname

    def get_value(self, var_name: str) -> BCLVariant:

        return self.variables.get(var_name)

    def get_parent(self):
        if self._parent:
            return self._parent
        else:
            return None
        # return self._parent

    def get_items(self) -> list:
        return self._childs

    def set_parent(self, parent: BCLDataSourceItem):
        self._parent = parent

    def set_childs(self, childs: list):
        self._childs = childs


class BCLDataSourceContext(BCLPrevContext):
    def __init__(self, data_source: list[BCLDataSourceItem], prevContext: BCLContext = None):
        super().__init__(prevContext)
        self._data_source = data_source

    def _get_variable_value(self, var_name: str) -> BCLVariant:
        result = None
        if var_name == "source":
            return BCLVariant(self._data_source)
        else:
            return super()._get_variable_value(var_name)


class BCLCalcItemContext(BCLPrevContext):
    def __init__(self, data_name: str, data_source: list[BCLDataSourceItem], prevContext: BCLContext = None):
        super().__init__(prevContext)
        self._index = 0
        self._data_name = data_name
        self._data_source = data_source

    def _get_variable_value(self, var_name: str) -> BCLVariant:
        """
        获取变量值，支持点号分隔的变量名查询
        :param var_name: 变量名，可以是简单变量名或'对象.属性'格式
        :return: 找到的变量或None
        """
        result = None
        # 检查是否是点号分隔的两段式变量名
        if "." in var_name:
            parts = var_name.split(".", maxsplit=1)
            prefix_name = parts[0]
            # 如果是当前数据对象的属性，则查询对应的变量
            try:
                if prefix_name == "parent":
                    value_name = parts[1]
                    child_pairt = parts[1]
                    item = self._data_source[self._index - 1].get_parent()
                    # 处理可能的多级属性访问
                    while "." in child_pairt and item:
                        child_parts = child_pairt.split(".", maxsplit=1)
                        if child_parts[0] == "parent":
                            item = item.get_parent()
                            value_name = child_parts[1]
                            child_pairt = child_parts[1]
                        else:
                            break

                    if item:
                        result = BCLVariant(item.get_value(value_name))
                    else:
                        result = BCLVariant("")

                elif prefix_name == self._data_name or prefix_name == "curnode":
                    result = BCLVariant(self._data_source[self._index - 1].get_value(parts[1]))
                elif (
                    self._data_source[self._index - 1].get_parent()
                    and prefix_name == self._data_source[self._index - 1].get_parent().get_dataname()
                ):
                    result = BCLVariant(self._data_source[self._index - 1].get_parent().get_value(parts[1]))
            except ValueError:
                pass

        if result == None:
            try:
                if var_name == "curnode":
                    result = BCLVariant(self._data_source[self._index - 1])
                elif var_name == "parent":
                    result = BCLVariant(self._data_source[self._index - 1].get_parent())
                elif var_name == "items":
                    result = BCLVariant(self._data_source[self._index - 1].get_items())
                elif (
                    self._data_source[self._index - 1].get_parent()
                    and var_name == self._data_source[self._index - 1].get_parent().get_dataname()
                ):
                    result = BCLVariant(self._data_source[self._index - 1].get_parent())
                else:
                    result = super()._get_variable_value(var_name)
            except ValueError:
                pass

        return result

    def __iter__(self):
        return self

    def __next__(self):
        if self._index >= len(self._data_source):
            raise StopIteration
        value = self._data_source[self._index]
        self._index += 1
        return value


# 定义test函数
def test_func(funcname: str, claculate, context: BCLContext, *args):
    logging.debug(f"call function : {funcname}")
    return 0


def round_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 2:
        raise ValueError(f"{funcname}函数需要2个参数，但提供了{len(args)}个参数")

    # 检查第一个参数类型（浮点数或表达式）
    if not isinstance(args[0], BCLVariant) or args[0].type not in (BCLVariantType.FLOAT, BCLVariantType.EXPRESSION):
        raise ValueError(f"{funcname}函数的第一个参数必须是浮点数或表达式类型")

    # 检查第二个参数类型（整数或表达式）
    if not isinstance(args[1], BCLVariant) or args[1].type not in (BCLVariantType.INTEGER, BCLVariantType.EXPRESSION):
        raise ValueError(f"{funcname}函数的第二个参数必须是整数或表达式类型")

    # 获取参数值
    value = args[0].value
    decimal_places = args[1].value

    # print(f"call function : {funcname}\n")
    logging.debug(f"四舍五入值: {value}, 小数位数: {decimal_places}")

    # 执行四舍五入计算
    return BCLVariant(round(float(value), int(decimal_places)))


def calc_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 1:
        raise ValueError(f"{funcname}函数需要1个参数，但提供了{len(args)}个参数")

    # 检查参数类型（表达式）
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.EXPRESSION:
        raise ValueError(f"{funcname}函数的参数必须是表达式类型")

    # 获取参数值
    expression = args[0].value

    # print(f"call function : {funcname}\n")
    logging.debug(f"计算表达式: {expression}")

    # 执行表达式计算并返回结果
    return BCLVariant(expression)


def sort_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 4:
        raise ValueError(f"{funcname}函数需要4个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.DATASOURCE:
        raise ValueError(f"{funcname}函数的第一个参数必须是数据源类型")
    if not isinstance(args[1], BCLVariant) or args[1].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第二个参数必须是文本类型")
    if not isinstance(args[2], BCLVariant) or args[2].type != BCLVariantType.EXPRESSION:
        raise ValueError(f"{funcname}函数的第三个参数必须是表达式类型")
    if not isinstance(args[3], BCLVariant) or args[3].type != BCLVariantType.STRING:
        raise ValueError(f"{funcname}函数的第四个参数必须是字符串类型")

    # 获取参数值
    data_source = args[0].value
    text_param = args[1].value
    expression = args[2].value
    string_param = args[3].value

    logging.debug(f"call function : {funcname}\n")
    logging.debug(f"数据源: {data_source}")
    logging.debug(f"文本参数: {text_param}")
    logging.debug(f"表达式: {expression}")
    logging.debug(f"字符串参数: {string_param}")

    temp_calculator = copy.copy(claculate)
    # 计算排序键并存储原始索引
    sorted_items = []
    temp_context = BCLCalcItemContext(text_param, data_source, context)
    for index, item in enumerate(temp_context):
        try:
            # 计算排序表达式的值
            result = temp_calculator.evaluate_node(expression, temp_context)
            if not isinstance(result, BCLVariant):
                raise TypeError("排序表达式计算结果必须是BCLVariant类型")
            if result.type not in (BCLVariantType.INTEGER, BCLVariantType.FLOAT):
                raise TypeError(f"排序表达式计算结果类型必须是数字，实际是{result.type}")
            sorted_items.append((float(result.value if result.value else "0"), index, item))
        except Exception as e:
            logging.error(f"计算排序键时出错: {e}", exc_info=True)
            # 出错项放在最后
            sorted_items.append((float("inf"), index, item))

    # 根据排序键和方向排序
    reverse_order = string_param.lower() == "desc"
    sorted_items.sort(key=lambda x: (x[0], x[1]), reverse=reverse_order)

    # 提取排序后的数据源
    sorted_data = [item for (key, index, item) in sorted_items]

    # 返回排序后的结果
    return BCLVariant(sorted_data)


def isempty_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 1:
        raise ValueError(f"{funcname}函数需要1个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.DATASOURCE:
        raise ValueError(f"{funcname}函数的第一个参数必须是数据源类型")

    # 获取参数值
    data_source = args[0].value

    logging.debug(f"call function : {funcname}\n")
    logging.debug(f"数据源: {data_source}\n")

    # 检查数据源是否为空
    is_empty = len(data_source) == 0
    # 返回检查结果
    return BCLVariant(is_empty)


def setparam_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 2:
        raise ValueError(f"{funcname}函数需要2个参数，但提供了{len(args)}个参数")

    # 检查第一个参数类型 (文本或表达式)
    if not isinstance(args[0], BCLVariant) or args[0].type not in (BCLVariantType.TEXT, BCLVariantType.EXPRESSION):
        raise ValueError(f"{funcname}函数的第一个参数必须是文本或表达式类型")

    # 检查第二个参数类型 (BCLVariant)
    if not isinstance(args[1], BCLVariant):
        raise ValueError(f"{funcname}函数的第二个参数必须是BCLVariant类型")

    # 获取参数值
    param_name_var = args[0]
    param_value = args[1]

    if param_name_var.type == BCLVariantType.EXPRESSION:
        # 计算参数名 (如果是表达式则求值)
        calculator = BCLCalculator()
        param_name_result = calculator._evaluate_node(param_name_var.value, context)
        if param_name_result.type != BCLVariantType.TEXT:
            raise TypeError(f"{funcname}函数的第一个参数表达式必须返回文本类型")
        param_name = param_name_result.value
    else:
        param_name = param_name_var.value

    if param_value.type == BCLVariantType.EXPRESSION:
        # 计算参数名 (如果是表达式则求值)
        calculator = BCLCalculator()
        param_value_result = calculator._evaluate_node(param_value.value, context)
        if param_value_result.type != BCLVariantType.TEXT:
            raise TypeError(f"{funcname}函数的第二个参数表达式必须返回文本类型")
        param_value = param_value_result.value

    # 设置参数到上下文
    context.set_param(param_name, param_value)

    # 返回设置的参数值
    return param_value


def getparam_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 1:
        raise ValueError(f"{funcname}函数需要1个参数，但提供了{len(args)}个参数")

    # 检查参数类型 (文本或表达式)
    if not isinstance(args[0], BCLVariant) or args[0].type not in (BCLVariantType.TEXT, BCLVariantType.EXPRESSION):
        raise ValueError(f"{funcname}函数的参数必须是文本或表达式类型")

    # 获取参数值
    param_name_var = args[0]

    # 计算参数名 (如果是表达式则求值)
    calculator = BCLCalculator()
    if param_name_var.type == BCLVariantType.EXPRESSION:
        param_name_result = calculator._evaluate_node(param_name_var.value, context)
        if param_name_result.type != BCLVariantType.TEXT:
            raise TypeError(f"{funcname}函数的参数表达式必须返回文本类型")
        param_name = param_name_result.value
    else:
        param_name = param_name_var.value

    # 从上下文获取参数
    param_value = context.get_param(param_name)

    # 返回参数值，如果不存在则返回NULL类型
    if param_value is None:
        return BCLVariant(None, BCLVariantType.NULL)
    return param_value


def groupby_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 4:
        raise ValueError(f"{funcname}函数需要4个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.DATASOURCE:
        raise ValueError(f"{funcname}函数的第一个参数必须是数据源类型")
    if not isinstance(args[1], BCLVariant) or args[1].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第二个参数必须是文本类型")
    if not isinstance(args[2], BCLVariant) or args[2].type not in (BCLVariantType.TEXT, BCLVariantType.EXPRESSION):
        raise ValueError(f"{funcname}函数的第三个参数必须是文本或表达式类型")
    if not isinstance(args[3], BCLVariant) or args[3].type != BCLVariantType.EXPRESSION:
        raise ValueError(f"{funcname}函数的第四个参数必须是表达式类型")

    # 获取参数值
    data_source = args[0].value
    text_param = args[1].value
    group_param = args[2].value
    calc_expression = args[3].value

    logging.debug(f"call function : {funcname}\n")
    logging.debug(f"分组参数: {group_param}")
    logging.debug(f"计算表达式: {calc_expression}")

    temp_calculator = copy.copy(claculate)
    groups = {}

    # 遍历数据源进行分组
    temp_context = BCLCalcItemContext(text_param, data_source, context)
    for index, item in enumerate(temp_context):
        try:
            # 根据第三个参数类型获取分组键
            if args[2].type == BCLVariantType.TEXT:
                # 文本类型直接作为键
                group_key = group_param
            else:
                # 表达式类型计算结果作为键
                result = temp_calculator.evaluate_node(group_param, temp_context)
                if not isinstance(result, BCLVariant):
                    raise TypeError("分组表达式计算结果必须是BCLVariant类型")
                group_key = str(result.value)

            # 添加到对应分组
            if group_key not in groups:
                groups[group_key] = []
            groups[group_key].append(item)
        except Exception as e:
            logging.error(f"分组处理出错: {e}", exc_info=True)
            # 错误项放入'error'分组
            if "error" not in groups:
                groups["error"] = []
            groups["error"].append(item)

    # 对每个分组执行第四个表达式计算
    group_results = {}
    group_context = BCLCalcItemContext(text_param, groups.items(), context)
    for index, (key, items) in enumerate(group_context):
        try:
            # 计算表达式结果
            result = temp_calculator.evaluate_node(calc_expression, group_context)
            group_results[key] = {"items": items, "result": result.value if isinstance(result, BCLVariant) else None}
        except Exception as e:
            logging.error(f"分组计算出错: {e}", exc_info=True)
            group_results[key] = {"items": items, "result": None}

    # 返回分组计算结果
    return BCLVariant(group_results)


def strfind_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 2:
        raise ValueError(f"{funcname}函数需要2个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第一个参数必须是文本类型")
    if not isinstance(args[1], BCLVariant) or args[1].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第二个参数必须是文本类型")

    # 获取参数值
    text1 = args[0].value
    text2 = args[1].value

    # print(f"call function : {funcname}\n")
    logging.debug(f"文本1: {text1}")
    logging.debug(f"文本2: {text2}")

    # 查找子字符串位置
    position = text1.find(text2)

    # 返回查找结果
    return BCLVariant(position)


def in_func(funcname: str, claculate, context: BCLContext, *args):
    # 参数数量校验
    if len(args) != 2:
        raise ValueError(f"函数 {funcname} 需要传入2个参数，实际传入了{len(args)}个参数")

    # 参数类型校验
    param1 = args[0]
    param2 = args[1]

    # 验证参数1：文本或表达式类型
    if not (isinstance(param1, BCLVariant) and param1.type in (BCLVariantType.TEXT, BCLVariantType.EXPRESSION)):
        raise TypeError(f"函数 {funcname} 的第1个参数必须是文本或表达式类型，实际类型为{type(param1).__name__}")

    # 验证参数2：文本或表达式类型
    if not (isinstance(param2, BCLVariant) and param2.type in (BCLVariantType.TEXT, BCLVariantType.EXPRESSION)):
        raise TypeError(f"函数 {funcname} 的第2个参数必须是文本或表达式类型，实际类型为{type(param2).__name__}")

    # 调试信息
    logging.debug(f"调用 {funcname} 函数，参数1: {param1}, 参数2: {param2}")

    # 创建计算器实例
    temp_calculator = copy.copy(claculate)

    try:
        # 计算两个表达式的值
        value1 = (
            temp_calculator.calculate_expression(param1.value)
            if param1.type == BCLVariantType.EXPRESSION
            else param1.value
        )
        value2 = (
            temp_calculator.calculate_expression(param2.value)
            if param2.type == BCLVariantType.EXPRESSION
            else param2.value
        )

        # 判断value1是否在value2中
        result = value1 in value2

        # 返回布尔类型的BCLVariant对象
        return BCLVariant(result)
    except Exception as e:
        logging.error(f"{funcname} 函数执行错误: {str(e)}", exc_info=True)
        raise


def iif_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 3:
        raise ValueError(f"{funcname}函数需要3个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type not in (BCLVariantType.BOOLEAN, BCLVariantType.EXPRESSION):
        raise ValueError(f"{funcname}函数的第一个参数必须是布尔或表达式类型")
    if not isinstance(args[1], BCLVariant) or args[1].type not in (
        BCLVariantType.INTEGER,
        BCLVariantType.FLOAT,
        BCLVariantType.EXPRESSION,
    ):
        raise ValueError(f"{funcname}函数的第二个参数必须是表达式类型")
    if not isinstance(args[2], BCLVariant) or args[2].type not in (
        BCLVariantType.INTEGER,
        BCLVariantType.FLOAT,
        BCLVariantType.EXPRESSION,
    ):
        raise ValueError(f"{funcname}函数的第三个参数必须是表达式类型")

    # 获取参数值
    condition_param = args[0]
    true_expr = args[1]
    false_expr = args[2]

    # print(f"call function : {funcname}\n")

    temp_calculator = copy.copy(claculate)

    try:
        # 计算条件结果
        if condition_param.type == BCLVariantType.EXPRESSION:
            condition_result = temp_calculator.evaluate_node(condition_param.value, context)
            if condition_result.type != BCLVariantType.BOOLEAN:
                raise TypeError("条件表达式必须返回布尔值")
            condition_value = condition_result.value
        else:
            condition_value = condition_param.value

        # 根据条件计算结果
        if condition_value:
            if true_expr.type == BCLVariantType.EXPRESSION:
                result = temp_calculator.evaluate_node(true_expr.value, context)
            else:
                result = true_expr
        else:
            if false_expr.type == BCLVariantType.EXPRESSION:
                result = temp_calculator.evaluate_node(false_expr.value, context)
            else:
                result = false_expr

        return result
    except Exception as e:
        print(f"iif函数计算出错: {e}")
        raise e


def for_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 4:
        raise ValueError(f"{funcname}函数需要4个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.DATASOURCE:
        raise ValueError(f"{funcname}函数的第一个参数必须是数据源类型")
    if not isinstance(args[1], BCLVariant) or args[1].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第二个参数必须是文本类型")
    if not isinstance(args[2], BCLVariant) or args[2].type != BCLVariantType.EXPRESSION:
        raise ValueError(f"{funcname}函数的第三个参数必须是表达式类型")
    if not isinstance(args[3], BCLVariant) or args[3].type != BCLVariantType.EXPRESSION:
        raise ValueError(f"{funcname}函数的第四个参数必须是表达式类型")

    # 获取参数值
    data_source = args[0].value
    loop_var_name = args[1].value
    expr1 = args[2].value
    expr2 = args[3].value

    logging.debug(f"call function : {funcname}\n")
    logging.debug(f"数据源: {data_source}\n")
    logging.debug(f"循环变量名: {loop_var_name}")
    logging.debug(f"表达式1: {expr1}")
    logging.debug(f"表达式2: {expr2}")

    temp_calculator = copy.copy(claculate)
    result = None

    temp_context = BCLCalcItemContext(loop_var_name, data_source, context)
    for index, item in enumerate(temp_context):
        try:
            # 执行第一个表达式
            result1 = temp_calculator.evaluate_node(expr1, temp_context)
        except Exception as e:
            logging.error(f"循环处理出错: {e}", exc_info=True)
            continue

    if args[3].type == BCLVariantType.EXPRESSION:
        result = claculate.evaluate_node(expr2, context)
    # 返回循环结果
    return BCLVariant(result)


def group_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 3:
        raise ValueError(f"{funcname}函数需要3个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.DATASOURCE:
        raise ValueError(f"{funcname}函数的第一个参数必须是数据源类型")
    if not isinstance(args[1], BCLVariant) or args[1].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第二个参数必须是文本类型")
    if not isinstance(args[2], BCLVariant) or args[2].type not in (BCLVariantType.TEXT, BCLVariantType.EXPRESSION):
        raise ValueError(f"{funcname}函数的第三个参数必须是文本或表达式类型")

    # 获取参数值
    data_source = args[0].value
    text_param = args[1].value
    third_param = args[2].value

    logging.debug(f"call function : {funcname}\n")
    logging.debug(f"数据源: {data_source}\n")
    logging.debug(f"文本参数: {text_param}\n")
    logging.debug(f"第三个参数: {third_param}")

    temp_calculator = copy.copy(claculate)
    groups = {}

    # 遍历数据源进行分组
    temp_context = BCLCalcItemContext(text_param, data_source, context)
    for index, item in enumerate(temp_context):
        try:
            # 根据第三个参数类型获取分组键
            if args[2].type == BCLVariantType.TEXT:
                # 文本类型直接作为键
                group_key = third_param
            else:
                result = temp_calculator.evaluate_node(third_param, temp_context)
                if not isinstance(result, BCLVariant):
                    raise TypeError("分组表达式计算结果必须是BCLVariant类型")
                group_key = str(result.value)

            # 添加到对应分组
            if group_key not in groups:
                groups[group_key] = []
            groups[group_key].append(item)
        except Exception as e:
            print(f"分组处理出错: {e}")
            # 错误项放入'error'分组
            if "error" not in groups:
                groups["error"] = []
            groups["error"].append(item)

    # 返回分组后的结果
    return BCLVariant(groups)


def sum_func(funcname: str, claculate, context: BCLContext, *args):
    # 检查参数数量
    if len(args) != 3:
        raise ValueError(f"{funcname}函数需要3个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.DATASOURCE:
        raise ValueError(f"{funcname}函数的第一个参数必须是数据源类型")
    if not isinstance(args[1], BCLVariant) or args[1].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第二个参数必须是文本类型")
    if not isinstance(args[2], BCLVariant) or args[2].type != BCLVariantType.EXPRESSION:
        raise ValueError(f"{funcname}函数的第三个参数必须是表达式类型")

    # 获取并存储三个参数
    data_source = args[0].value
    data_name = args[1].value
    expression = args[2].value

    logging.debug(f"call function : {funcname}\n")
    logging.debug(f"数据源: {data_source}\n")
    logging.debug(f"数据变量名称: {data_name}")
    logging.debug(f"表达式: {expression}\n")

    temp_calculator = copy.copy(claculate)
    # 遍历数据源并累加结果
    total = 0.0
    temp_context = BCLCalcItemContext(data_name, data_source, context)
    for index, item in enumerate(temp_context):
        try:
            result = temp_calculator.evaluate_node(expression, temp_context)
            # 验证结果类型必须是BCLVariant且类型为数字
            if not isinstance(result, BCLVariant):
                raise TypeError("表达式计算结果必须是BCLVariant类型")
            if result.type not in (BCLVariantType.INTEGER, BCLVariantType.FLOAT):
                raise TypeError(f"表达式计算结果类型必须是数字，实际是{result.type}")
            total += float(result.value)
        except Exception as e:
            logging.error(f"表达式计算错误: {str(e)}", exc_info=True)
            continue

    return BCLVariant(total)


def filter_func(funcname: str, claculate, context: BCLContext, *args):
    """
    过滤函数，检查参数并执行过滤操作
    :param funcname: 函数名
    :param args: 参数列表，必须包含3个BCLVariant参数
    :return: 过滤结果
    """
    # 检查参数数量
    if len(args) != 3:
        raise ValueError(f"{funcname}函数需要3个参数，但提供了{len(args)}个参数")

    # 检查参数类型
    if not isinstance(args[0], BCLVariant) or args[0].type != BCLVariantType.DATASOURCE:
        raise ValueError(f"{funcname}函数的第一个参数必须是数据源类型")
    if not isinstance(args[1], BCLVariant) or args[1].type != BCLVariantType.TEXT:
        raise ValueError(f"{funcname}函数的第二个参数必须是文本类型")
    if not isinstance(args[2], BCLVariant) or args[2].type != BCLVariantType.EXPRESSION:
        raise ValueError(f"{funcname}函数的第三个参数必须是表达式类型")

    # 获取并存储三个参数
    data_source = args[0].value
    data_name = args[1].value
    expression = args[2].value

    logging.debug(f"call function : {funcname}\n")
    logging.debug(f"数据源: {data_source}\n")
    logging.debug(f"数据变量名称: {data_name}\n")
    logging.debug(f"表达式: {expression}\n")

    temp_calculator = copy.copy(claculate)

    # 遍历数据源并应用过滤条件
    filtered_results = []
    temp_context = BCLCalcItemContext(data_name, data_source, context)
    for index, item in enumerate(temp_context):
        # 调用计算器的evaluate_node方法计算表达式
        try:
            result = temp_calculator.evaluate_node(expression, temp_context)
            # 验证结果类型必须是BCLVariant且类型为布尔或整数
            if not isinstance(result, BCLVariant):
                raise TypeError("表达式计算结果必须是BCLVariant类型")
            if result.type not in (BCLVariantType.BOOLEAN, BCLVariantType.INTEGER):
                raise TypeError(f"表达式计算结果类型必须是布尔或整数，实际是{result.type}")
            # 判别其值为true才添加到filtered_results
            if result.value:
                filtered_results.append(item)
        except Exception as e:
            logging.error(f"表达式计算错误: {str(e)}", exc_info=True)
            continue

    return BCLVariant(filtered_results)


def recursion_counter(func):
    def wrapper(self, node, *args, **kwargs):
        if not hasattr(self, "_recursion_depth"):
            self._recursion_depth = 0
        if not hasattr(self, "_total_count"):
            self._total_count = 0

        self._total_count += 1
        self._recursion_depth += 1
        try:
            result = func(self, node, *args, **kwargs)
            return result
        finally:
            self._recursion_depth -= 1

    return wrapper


class BCLCalculator:
    def __init__(self):
        self.expressions: Dict[str, ET.Element] = {}
        self.functions: Dict[str, Callable] = {}
        self.last_error: Optional[str] = None
        self.loaded_scripts = []  # 存储已加载的脚本相对路径

        # 注册sum函数
        self.register_function("sum", sum_func)
        self.register_function("calc", calc_func)
        self.register_function("round", round_func)
        self.register_function("filter", filter_func)
        self.register_function("iif", iif_func)
        self.register_function("sort", sort_func)
        self.register_function("group", group_func)
        self.register_function("groupby", groupby_func)
        self.register_function("for", for_func)
        self.register_function("in", in_func)
        self.register_function("isEmpty", isempty_func)
        self.register_function("setparam", setparam_func)
        self.register_function("getparam", getparam_func)
        self.register_function("strFind", strfind_func)

    def __copy__(self):
        # 创建新实例，复制基本属性
        new_instance = self.__class__()
        new_instance.loaded_scripts = self.loaded_scripts  # 直接引用
        new_instance.expressions = self.expressions  # 直接引用
        new_instance.functions = self.functions  # 直接引用
        return new_instance

    def load_scripts_dir(self, dir_path: str) -> bool:
        """
        加载目录下所有XML脚本文件
        :param dir_path: 包含XML文件的目录路径
        :return: 是否全部加载成功
        """
        if not os.path.isdir(dir_path):
            self.last_error = f"目录'{dir_path}'不存在或不是目录\n"
            return False

        success = True
        for filename in os.listdir(dir_path):
            if filename.lower().endswith(".xml"):
                xml_path = os.path.join(dir_path, filename)
                if not self.load_script(xml_path):
                    success = False

        return success

    def load_script(self, xml_path: str) -> bool:
        """
        加载XML脚本文件并验证其结构
        :param xml_path: XML文件路径
        :return: 是否加载成功
        """
        try:
            # 检查文件是否存在
            if not os.path.exists(xml_path):
                self.last_error = f"文件'{xml_path}'不存在\n"
                return False

            # 读取并清理XML文件内容
            import chardet

            # 检测文件编码
            with open(xml_path, "rb") as f:
                raw_data = f.read()
                encoding = chardet.detect(raw_data)["encoding"]

            # 使用检测到的编码读取文件内容，并转换为UTF-8
            with open(xml_path, "r", encoding=encoding, errors="replace") as f:
                content = f.read()

            # 确保内容是UTF-8编码
            if encoding.lower() != "utf-8":
                content = content.encode("utf-8", errors="replace").decode("utf-8")

            # 清理重复的Type属性
            content = self._clean_xml_attributes(content)

            # 解析清理后的XML
            root = ET.fromstring(content)

            # 记录已加载的脚本相对路径
            relative_path = os.path.relpath(xml_path, start=os.getcwd())
            self.loaded_scripts.append(relative_path)

            # 验证根节点 - 兼容BclDocument作为根节点或在Document-DataDefs下
            if root.tag == "Document":
                data_defs = root.find("DataDefs")
                if data_defs is not None:
                    bcl_doc = data_defs.find("BclDocument")
                    if bcl_doc is not None:
                        root = bcl_doc
                    else:
                        self.last_error = "在Document/DataDefs下未找到BclDocument节点\n"
                        return False
                else:
                    self.last_error = "Document节点缺少DataDefs子节点\n"
                    return False
            elif root.tag != "BclDocument":
                self.last_error = "根节点必须是BclDocument或Document\n"
                return True

            # 验证所有BCLExpression节点
            for expr in root.findall("BCLExpression"):
                if not self._validate_expression_node(expr):
                    return False

                name = expr.get("name")
                self.expressions[name] = expr

            return True
        except ET.ParseError as e:
            self.last_error = f"XML解析错误: {str(e)}\n"
            return False
        except Exception as e:
            self.last_error = f"加载脚本失败: {str(e)}\n"
            return False

    def _clean_xml_attributes(self, xml_content: str) -> str:
        """
        清理XML中的重复属性，保留最后一个出现的属性值
        :param xml_content: XML内容字符串
        :return: 清理后的XML内容
        """
        # 使用正则表达式匹配并清理重复的Type属性
        import re

        # xml_content = '''<ELNode type="函数" Type="TextW" text="_过滤取费定额" Type="TextW" valtype="5" Type="Int" />'''

        # 正则表达式删除所有 Type="*" 属性
        xml_content = re.sub(r'Type="[^"]*"', "", xml_content)
        return xml_content

    def _validate_expression_node(self, node: ET.Element) -> bool:
        """
        验证表达式节点结构
        :param node: ELNode节点
        :return: 是否验证通过
        """
        # 检查必须包含ELNode子节点
        el_node = node.find("ELNode")
        if el_node is None:
            self.last_error = f"表达式节点'{node.get('name')}'缺少ELNode子节点"
            return False

        # 检查ELNode类型
        if el_node.get("type") != "表达式序列":
            self.last_error = f"表达式节点'{node.get('name')}'的ELNode类型必须是'表达式序列'"
            return False

        return True

    def register_function(self, name: str, func: Callable) -> None:
        self.functions[name] = func

    def calculate(self, expr_name: str, context: BCLContext) -> float:
        self.last_error = None
        if expr_name not in self.expressions:
            self.last_error = f"表达式'{expr_name}'未找到"
            logging.error(f"错误: {self.last_error}")
            return None

        try:
            expr_node = self.expressions[expr_name]
            result = self._evaluate_node(expr_node, context)
            if result is None:
                logging.error(f"错误: {self.last_error}")
                return None

            return result.value
        except Exception as e:
            self.last_error = f"计算错误: {str(e)}"
            print(f"错误: {self.last_error}")
            return None

    def evaluate_node(self, node: ET.Element, context: BCLContext) -> BCLVariant:
        self.last_error = None

        try:
            result = self._evaluate_node(node, context)
            if result is None:
                logging.error(f"错误: {self.last_error}")

            return result
        except Exception as e:
            self.last_error = f"计算错误: {str(e)}"
            print(f"错误: {self.last_error}")
            return None

    def _get_variable_value(self, var_name: str, context: BCLContext) -> BCLVariant:
        try:
            var = context.get_variable_value(var_name)
            if var is not None:
                logging.debug(f"找到变量: {var_name}, 值: {var.value}, 类型: {var.type}")
                return var
            else:
                logging.warning(f"未找到变量: {var_name}")
                raise ValueError(f"变量'{var_name}'不存在")
        except (AttributeError, ValueError) as e:
            raise e

    @recursion_counter
    def _evaluate_node(self, node: ET.Element, context: BCLContext) -> BCLVariant:
        node_type = node.get("type")
        if node_type is not None:
            node_type = node_type.strip()

        indent = "  " * self._recursion_depth
        if node_type is None:
            logging.debug(f"{indent} {node.tag}  {node.get('name')}")
        else:
            logging.debug(f"{indent} {node.tag}  {node_type}  {node.get('text')}")

        if node_type == "变量":
            var_name = node.get("text").strip()
            return self._get_variable_value(var_name, context)
        elif node_type == "数值":
            return BCLVariant(float(node.get("text").strip()))
        elif node_type == "字符串":
            return BCLVariant(str(node.get("text") if node.get("text") else "").strip())
        elif node_type == "函数":
            func_name = node.get("text").strip()
            return self._call_function(func_name, node, context)
        elif str_to_operator(node_type) != BCLOperatorType.UNKNOWN:
            return self._evaluate_logical_expression(node, context)
        elif node_type == "条件运算符":
            return self._evaluate_flow_expression(node[0], context)
        elif node_type == "简单计算式":
            return self._evaluate_expression(node, context)
        elif node_type == "表达式序列":
            # 处理表达式序列节点
            result = None
            for child in node:
                result = self._evaluate_node(child, context)

            return result
        elif node_type == "参数起始符号":
            # 处理参数起始符号节点
            result = None
            for child in node:
                result = self._evaluate_node(child, context)

            return result
        elif node.tag == "BCLExpression" or node.tag == "LeftNode" or node.tag == "RightNode":
            # 处理BCLExpression节点
            child = node[0]
            if child.tag == "ELNode" and child.get("type") == "表达式序列":
                return self._evaluate_node(node[0], context)
        else:
            logging.warning(f"{indent} 未知的计算节点类型: {node_type}")
            raise ValueError(f"未知的计算节点类型: {node_type}")

    def _evaluate_logical_expression(self, node: ET.Element, context: BCLContext) -> BCLVariant:
        """
        计算逻辑表达式
        :param node: XML节点
        :param context: 上下文对象
        :return: 逻辑运算结果
        """
        node_type = node.get("type").strip()
        operator_type = str_to_operator(node_type)

        left = self._evaluate_node(node.find("LeftNode"), context)
        if left is None:
            left = BCLVariant(False)

        if operator_type == BCLOperatorType.NOT:
            if not isinstance(left, BCLVariant):
                raise ValueError(f"NOT运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}")
            if left.type in [BCLVariantType.BOOLEAN, BCLVariantType.INTEGER]:
                return BCLVariant(not bool(left.value))

            raise ValueError(f"运算符 '{node_type}' 参数类型为 {left.type}  ,不支持的\n")

        right = self._evaluate_node(node.find("RightNode"), context)
        if left is None:
            left = BCLVariant(False)

        if operator_type == BCLOperatorType.AND:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'与'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type in [BCLVariantType.BOOLEAN, BCLVariantType.INTEGER] and right.type in [
                BCLVariantType.BOOLEAN,
                BCLVariantType.INTEGER,
            ]:
                return BCLVariant(bool(left.value) and bool(right.value))

            raise ValueError(f"运算符 '{node_type}' 两边参数类型分别为 {left.type}  {right.type} ,不支持的\n")

        elif operator_type == BCLOperatorType.OR:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'或'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type in [BCLVariantType.BOOLEAN, BCLVariantType.INTEGER] and right.type in [
                BCLVariantType.BOOLEAN,
                BCLVariantType.INTEGER,
            ]:
                return BCLVariant(bool(left.value) or bool(right.value))

            raise ValueError(f"运算符 '{node_type}' 两边参数类型分别为 {left.type}  {right.type} ,不支持的\n")

        elif operator_type == BCLOperatorType.EQUAL:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'等于'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            # 类型转换逻辑
            if BCLVariantType.BOOLEAN in [left.type, right.type]:
                left_value = bool(left.value if left.value else "0")
                right_value = bool(right.value if right.value else "0")
            elif BCLVariantType.FLOAT in [left.type, right.type]:
                left_value = float(left.value if left.value else "0")
                right_value = float(right.value if right.value else "0")
            elif BCLVariantType.INTEGER in [left.type, right.type]:
                left_value = float(left.value if left.value else "0")
                right_value = float(right.value if right.value else "0")
            else:
                left_value = left.value
                right_value = right.value

            return BCLVariant(left_value == right_value)

        elif operator_type == BCLOperatorType.NOT_EQUAL:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'不等于'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            return BCLVariant(left.value != right.value)

        elif operator_type == BCLOperatorType.GREATER:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'>'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")

            # 支持 FLOAT 和 INTEGER 类型的比较
            if left.type in [BCLVariantType.FLOAT, BCLVariantType.INTEGER] and right.type in [
                BCLVariantType.FLOAT,
                BCLVariantType.INTEGER,
            ]:
                return BCLVariant(float(left.value if left.value else "0") > float(right.value if right.value else "0"))

            raise ValueError(f"运算符 '{node_type}' 两边参数类型分别为 {left.type}  {right.type} ,不支持的\n")

        elif operator_type == BCLOperatorType.GREATER_EQUAL:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'>='运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type in [BCLVariantType.INTEGER] and right.type in [BCLVariantType.INTEGER]:
                return BCLVariant(
                    float(left.value if left.value else "0") >= float(right.value if right.value else "0")
                )
            raise ValueError(f"运算符 '{node_type}' 两边参数类型分别为 {left.type}  {right.type} ,不支持的\n")

        elif operator_type == BCLOperatorType.LESS:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'<'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type in [BCLVariantType.INTEGER] and right.type in [BCLVariantType.INTEGER]:
                return BCLVariant(float(left.value if left.value else "0") < float(right.value if right.value else "0"))
            raise ValueError(f"运算符 '{node_type}' 两边参数类型分别为 {left.type}  {right.type} ,不支持的\n")

        elif operator_type == BCLOperatorType.LESS_EQUAL:
            if not isinstance(left, BCLVariant) or not isinstance(right, BCLVariant):
                raise ValueError(f"'<='运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type in [BCLVariantType.INTEGER] and right.type in [BCLVariantType.INTEGER]:
                return BCLVariant(
                    float(left.value if left.value else "0") <= float(right.value if right.value else "0")
                )
            raise ValueError(f"运算符 '{node_type}' 两边参数类型分别为 {left.type}  {right.type} ,不支持的\n")

        # 四则运算符处理
        elif operator_type == BCLOperatorType.ADD:
            if not (isinstance(left, BCLVariant) and isinstance(right, BCLVariant)):
                raise ValueError(f"'加'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ) or right.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ):
                raise ValueError(
                    f"'加'运算符的操作数类型必须为数值、浮点数、布尔或文本，实际为: {left.type}和{right.type}"
                )
            return BCLVariant(float(left.value if left.value else "0") + float(right.value if right.value else "0"))

        elif operator_type == BCLOperatorType.SUBTRACT:
            if not (isinstance(left, BCLVariant) and isinstance(right, BCLVariant)):
                raise ValueError(f"'减'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ) or right.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ):
                raise ValueError(
                    f"'减'运算符的操作数类型必须为数值、浮点数、布尔或文本，实际为: {left.type}和{right.type}"
                )
            return BCLVariant(float(left.value if left.value else "0") - float(right.value if right.value else "0"))

        elif operator_type == BCLOperatorType.MULTIPLY:
            if not (isinstance(left, BCLVariant) and isinstance(right, BCLVariant)):
                raise ValueError(f"'乘'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ) or right.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ):
                raise ValueError(
                    f"'乘'运算符的操作数类型必须为数值、浮点数、布尔或文本，实际为: {left.type}和{right.type}"
                )
            try:
                left_val = float(left.value) if left.value and str(left.value).strip() not in ("", "None") else 0.0
                right_val = float(right.value) if right.value and str(right.value).strip() not in ("", "None") else 0.0
                result = left_val * right_val
            except (TypeError, ValueError, AttributeError):
                result = 0.0

            return BCLVariant(result)

        elif operator_type == BCLOperatorType.DIVIDE:
            if not (isinstance(left, BCLVariant) and isinstance(right, BCLVariant)):
                raise ValueError(f"'除'运算符的操作数必须是BCLVariant类型，实际得到: {type(left)}和{type(right)}")
            if left.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ) or right.type not in (
                BCLVariantType.INTEGER,
                BCLVariantType.FLOAT,
                BCLVariantType.BOOLEAN,
                BCLVariantType.TEXT,
            ):
                raise ValueError(
                    f"'除'运算符的操作数类型必须为数值、浮点数、布尔或文本，实际为: {left.type}和{right.type}"
                )
            if float(right.value) == 0:
                raise ZeroDivisionError("除数不能为零")
            return BCLVariant(float(left.value if left.value else "0") / float(right.value if right.value else "0"))

        raise ValueError(f"运算符 '{node_type}' 类型不支持的\n")

    def _evaluate_expression(self, expr_node: ET.Element, context: BCLContext) -> BCLVariant:
        try:
            # 收集所有变量值
            variables = {}
            for var_node in expr_node:
                if var_node.get("type") != "变量":
                    continue

                var_name = var_node.get("text")
                variables[var_name] = self._get_variable_value(var_name, context)

            # 构建表达式字符串
            expr_str = expr_node.get("text")

            symbols = {}
            for var_name, var_value in variables.items():
                symbols[var_name] = float("0" if not var_value.get_value() else var_value.get_value())

            calculator = ExpressionCalculator()
            parse_success = calculator.parse_expression(expr_str)
            if not parse_success:
                logging.error(f"表达式解析失败: {calculator.get_last_error()}")
                raise ValueError(f"表达式解析失败: {calculator.get_last_error()}")

            # 执行四则运算并返回结果
            result, value = calculator.evaluate(symbols)
            if not result:
                logging.error(f"表达式计算失败: {calculator.get_last_error()}")
                raise ValueError(f"表达式计算失败: {calculator.get_last_error()}")

            return BCLVariant(value)
        except Exception as e:
            raise e

    def _call_function(self, func_name: str, node: ET.Element, context: BCLContext) -> BCLVariant:

        if func_name in self.expressions:
            expr_node = self.expressions[func_name]
            result = self._evaluate_node(expr_node, context)
            return result

        if func_name not in self.functions:
            raise ValueError(f"函数'{func_name}'未注册\n")

        args = []
        for child in node:
            if child.get("type") == "参数起始符号":
                current_node = child
                while True:
                    # 验证子节点数量必须为1
                    if len(current_node) != 1:
                        raise ValueError(f"函数'{func_name}'参数节点数量错误，预期1个实际{len(current_node)}个\n")
                    child_node = current_node[0]
                    # 检查是否存在type属性
                    if child_node.get("type") != None:
                        break
                    # 继续遍历子节点
                    current_node = child_node
                args.append(BCLVariant(child_node))
                continue

            args.append(self._evaluate_node(child, context))

        return self.functions[func_name](func_name, self, context, *args)

    def get_last_error(self) -> Optional[str]:
        return self.last_error

    def _evaluate_flow_expression(self, node: ET.Element, context: BCLContext) -> BCLVariant:
        """
        处理流程表达式（如ConditionNode/ConListElm/ConNode条件分支结构）
        :param node: ConListElm节点
        :param context: 上下文对象
        :return: 满足条件的ValueNode的计算结果
        """
        defval = None
        # 只处理当前ConListElm节点，不递归遍历所有ConListElm
        for block in node:
            if block.tag == "ConListElm":
                con_node = None
                value_node = None
                for sub in block:
                    if sub.tag == "ConNode":
                        con_node = sub
                    elif sub.tag == "ValueNode":
                        value_node = sub
                if con_node is not None and value_node is not None:
                    cond_result = self._evaluate_node(con_node, context)
                    if cond_result and bool(cond_result.value):
                        return self._evaluate_node(
                            value_node if value_node.get("type") != None else value_node[0], context
                        )
            elif block.tag == "DefVal":
                defval = block

        if defval is not None:
            return self._evaluate_node(defval, context)
        else:
            # 没有条件成立，返回0.0
            return BCLVariant(0.0)
