package com.syjy.calculate.function;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.type.AviatorDecimal;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.Sequence;
import com.syjy.calculate.entity.FormulaParam;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 计算偏差电量：Σ|实际-预测*(1±偏差允许值)|/4
 *
 * @author zcl
 * @version 1.0
 * @since 2022/10/8 9:30
 */
public class DevianceElectric extends AbstractFunction {
    @Override
    public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3, AviatorObject arg4) {
        // 获取参数
        FormulaParam formulaParam = CommonUtil.getFormulaParam(env, arg1, arg2, arg3, arg4, null);
        // 将参数转为集合
        Sequence seq = CommonUtil.getSeq(formulaParam.getFirst(), env);
        BigDecimal sum =BigDecimal.ZERO;
        // 循环集合获取实际功率、预测功率信息并计算
        for (Object obj : seq) {
            Map<String, Object> map = (Map<String, Object>) obj;
            map.put("rate",new BigDecimal(formulaParam.getFourth()));
            // 默认getSecond是预测功率，getThird是实际功率
            BigDecimal errorBandwidth = new BigDecimal(String.valueOf(AviatorEvaluator.execute("errorBandwidth("+formulaParam.getSecond()+","+formulaParam.getThird()+")",map)));
            // 如果单侧误差带宽>误差带宽允许值
            if(errorBandwidth.compareTo(new BigDecimal(formulaParam.getFourth()))== 1){
                String exp = "let devianceElectric = 0; \n" +
                        "                if (ableValue > forecastAbleValue) { \n" +
                        "                    devianceElectric = math.abs((ableValue - (forecastAbleValue * (1 + rate))) / 4); \n" +
                        "                } else { \n" +
                        "                    devianceElectric = math.abs((ableValue - (forecastAbleValue * (1 - rate))) / 4); \n" +
                        "                } \n" +
                        "                return devianceElectric; \n";
                // 计算短期偏差电量
                BigDecimal devianceElectric = new BigDecimal(String.valueOf(AviatorEvaluator.execute(exp,map)));
                // 求和
                sum = sum.add(devianceElectric);
            }
        }
        return new AviatorDecimal(sum);
    }
    @Override
    public String getName() {
        return "devianceElectric";
    }
}
