package com.supervision.utils;

import com.supervision.common.constant.IndexRuleConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.Set;

import static com.supervision.common.constant.IndexRuleConstants.LOGIC_AND;
import static com.supervision.common.constant.IndexRuleConstants.LOGIC_OR;

@Slf4j
public class CalculationUtil {

    /**
     * 计算表达式结果
     *
     * @param leftOperand  左操作数
     * @param operator     操作符
     * @param rightOperand 右操作数
     * @return 计算结果
     */
    public static boolean evaluateExpression(String leftOperand, String operator, String rightOperand) {
        String expression = switch (operator) {
            case IndexRuleConstants.OPERATOR_GT -> // ">"
                    "#leftOperand > #rightOperand";
            case IndexRuleConstants.OPERATOR_GE -> // ">="
                    "#leftOperand >= #rightOperand";
            case IndexRuleConstants.OPERATOR_LT -> // "<"
                    "#leftOperand < #rightOperand";
            case IndexRuleConstants.OPERATOR_LE -> // "<="
                    "#leftOperand <= #rightOperand";
            case IndexRuleConstants.OPERATOR_EQ -> // "="
                    "#leftOperand == #rightOperand";
            case IndexRuleConstants.OPERATOR_NE -> // "!="
                    "#leftOperand != #rightOperand";
            case IndexRuleConstants.OPERATOR_EARLY -> // "早于"
                    "#leftOperand < #rightOperand";
            case IndexRuleConstants.OPERATOR_LATE -> // "晚于"
                    "#leftOperand > #rightOperand";
            case IndexRuleConstants.OPERATOR_CONTAIN -> // "包含"
                    "#leftOperand.contains(#rightOperand)";
            default -> throw new UnsupportedOperationException("不支持的操作符: " + operator);
        };

        // 判断操作符并构造相应的SpEL表达式

        log.info("Expression: [{}]", expression);

        // 初始化SpEL解析器
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();
        // 判断并转换变量类型
        Object leftValue = parseOperand(leftOperand);
        Object rightValue = parseOperand(rightOperand);
        context.setVariable("leftOperand", leftValue);
        context.setVariable("rightOperand", rightValue);

        // 计算结果
        return Boolean.TRUE.equals(parser.parseExpression(expression).getValue(context, Boolean.class));
    }

    /**
     * 辅助方法:动态解析操作数类型
     *
     * @param operand 操作数
     * @return 解析结果
     */
    private static Object parseOperand(String operand) {
        if (operand == null) {
            return null;
        }
        try {
            // 尝试解析为数字(支持整数和小数)
            if (operand.contains(".")) {
                return Double.valueOf(operand);
            } else {
                return Integer.valueOf(operand);
            }
        } catch (NumberFormatException e) {
            // 如果解析失败,返回原始字符串
            return operand;
        }
    }

    /**
     * 计算布尔值集合的逻辑运算结果
     *
     * @param booleanSet 布尔值集合
     * @param logic      逻辑运算符
     * @return 计算结果
     */
    public static boolean calculateBooleanSet(Set<Boolean> booleanSet, String logic) {
        // 判断是否为空
        if (booleanSet == null || booleanSet.isEmpty()) {
            return false;
        }

        // 判断是"且"还是"或"
        String operator;
        if (LOGIC_AND.equals(logic)) {
            operator = " and ";
        } else if (LOGIC_OR.equals(logic)) {
            operator = " or ";
        } else {
            throw new IllegalArgumentException("Invalid logic value: [" + logic + "], use 1 for AND, 2 for OR.");
        }

        // 构建表达式
        StringBuilder expressionBuilder = new StringBuilder();
        boolean first = true;
        for (Boolean bool : booleanSet) {
            if (!first) {
                expressionBuilder.append(operator);
            }
            expressionBuilder.append(bool);
            first = false;
        }

        // 初始化SpEL解析器
        ExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();

        // 计算结果
        return Boolean.TRUE.equals(parser.parseExpression(expressionBuilder.toString()).getValue(context, Boolean.class));
    }
}