package com.njcn.advance.utils.assess;

/**
 * Description:
 * Date: 2025/05/30  下午 3:34【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
public class VoltageDeviationUtil {

    // Calculate voltage deviation for various conditions
    /** 
    * @Description: calculateVoltageDeviation
    * @Param: 
     * @param powerFactor 用户真功率因数默认取0.95
     * @param pccShortCircuitCapacity 评估用户参数表最小短路容量
     * @param capacitorCapacity 评估用户电容器组参数表单组容量
     * @param supplyCapacity 评估用户参数表供电设备容量
     * @param activeCapacity 评估用户参数表有功容量
     * @param transformerNoLoadCurrent 变压器字典表空载电流
     * @param transformerShortCircuitVoltage 变压器字典表短路阻抗
     * @param transformerRatedCapacity 变压器字典表额定容量
     * @param loadRate 用户100%，60%，0%三个档估算，系数分别为1.0,0.6,0
     * @param capacitorInService 电容器是否投入
     * @param outputPercentage  电网高峰和低谷负荷率，高峰默认为0.65,低谷默认为0.15
    * @return: double 
    * @Author: clam
    * @Date: 2025/06/10 
    */ 
    public static double calculateVoltageDeviation(
            double powerFactor, double pccShortCircuitCapacity,
            double capacitorCapacity, double supplyCapacity,
            double activeCapacity,
            double transformerNoLoadCurrent, double transformerShortCircuitVoltage,
            double transformerRatedCapacity, double loadRate,
            boolean capacitorInService, double outputPercentage) {

        // 1. Calculate substation transformer reactive capacity
        double qk3 = supplyCapacity * Math.sqrt(1 - Math.pow(powerFactor, 2)) * 1000;

        // 2. Calculate user's reactive power absorbed from grid
        // Transformer reactive loss
        double qt0 = transformerShortCircuitVoltage * Math.pow(activeCapacity, 2) /
                (100 * transformerRatedCapacity) +
                (transformerNoLoadCurrent * transformerRatedCapacity / 100);

        double qu;
        if (capacitorInService) {
            qu = activeCapacity * Math.sqrt(1/Math.pow(powerFactor, 2) - 1) * 1000 -
                    capacitorCapacity + qt0;
        } else {
            qu = activeCapacity * Math.sqrt(1/Math.pow(powerFactor, 2) - 1) * 1000 + qt0;
        }

        // 3. Calculate voltage deviation under each condition
        return ((qu * outputPercentage + qk3 * loadRate) / pccShortCircuitCapacity )* 0.001;
    }

    // Get voltage deviation limits
    public static VoltageDeviationLimits getVoltageDeviationLimits(double voltageLevel) {
        if (voltageLevel <= 0.38) {
            return new VoltageDeviationLimits(7.0, -10.0);
        } else if (voltageLevel <= 20) {
            return new VoltageDeviationLimits(7.0, -7.0);
        } else {
            return new VoltageDeviationLimits(7.0, -3.0);
        }
    }

    public static class VoltageDeviationLimits {
        private final double upperLimit;
        private final double lowerLimit;

        public VoltageDeviationLimits(double upperLimit, double lowerLimit) {
            this.upperLimit = upperLimit;
            this.lowerLimit = lowerLimit;
        }

        public double getUpperLimit() { return upperLimit; }
        public double getLowerLimit() { return lowerLimit; }
    }
}

