package com.usky.cdi.service.vo.info;

import com.usky.cdi.service.vo.base.BaseEnvMonitorPushVO;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 人防用电负荷推送VO（兼容2021版）
 * 用途：每半小时上报配电箱监测数据（电压、电流、功率等）
 * MQTT Topic：iotInfo/electricityLoad
 * @author fyc
 * @email yuchuan.fu@chinausky.com
 * @date 2025/11/20
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ElectricityLoadVO extends BaseEnvMonitorPushVO {

    private static final long serialVersionUID = 1L;

    // ====================== 专属字段（严格映射数据包定义）======================

    /**
     * A相电压（必填）
     * 类型：Float(3,2)，单位：伏(V)（范围：0.00 ~ 999.99V）
     */
    private Float aVoltage;

    /**
     * B相电压（必填）
     * 类型：Float(3,2)，单位：伏(V)
     */
    private Float bVoltage;

    /**
     * C相电压（必填）
     * 类型：Float(3,2)，单位：伏(V)
     */
    private Float cVoltage;

    /**
     * A相电流（必填）
     * 类型：Float(3,2)，单位：安(A)
     */
    private Float aElectricity;

    /**
     * B相电流（必填）
     * 类型：Float(3,2)，单位：安(A)
     */
    private Float bElectricity;

    /**
     * C相电流（必填）
     * 类型：Float(3,2)，单位：安(A)
     */
    private Float cElectricity;

    /**
     * 总功率（必填）
     * 类型：Float(4,2)，单位：千瓦(kW)（范围：0.00 ~ 9999.99kW）
     */
    private Float totalPower;

    /**
     * 线温1（非必填）
     * 类型：Float(2,2)，单位：℃（范围：-99.99 ~ 99.99℃）
     */
    private Float line1TEMP;

    /**
     * 线温2（非必填）
     * 类型：Float(2,2)，单位：℃
     */
    private Float line2TEMP;

    /**
     * 线温3（非必填）
     * 类型：Float(2,2)，单位：℃
     */
    private Float line3TEMP;

    /**
     * 线温4（非必填）
     * 类型：Float(2,2)，单位：℃
     */
    private Float line4TEMP;

    /**
     * 剩余电流（非必填）
     * 类型：Float(4,2)，单位：mA（范围：0.00 ~ 9999.99mA）
     */
    private Float leakageCurrent;

    // ====================== 重写父类方法（适配多字段校验）======================

    /**
     * 父类抽象方法：返回核心监测值（取总功率作为代表）
     */
    @Override
    public Number getSensorValue() {
        return totalPower;
    }

    /**
     * 个性化校验：校验所有用电负荷字段的合法性
     */
    @Override
    protected void validateSensorValue() {
        // 1. 必填字段非空校验（父类已校验公共字段，此处校验专属必填字段）
        if (aVoltage == null) throw new IllegalArgumentException("A相电压（aVoltage）为必填项");
        if (bVoltage == null) throw new IllegalArgumentException("B相电压（bVoltage）为必填项");
        if (cVoltage == null) throw new IllegalArgumentException("C相电压（cVoltage）为必填项");
        if (aElectricity == null) throw new IllegalArgumentException("A相电流（aElectricity）为必填项");
        if (bElectricity == null) throw new IllegalArgumentException("B相电流（bElectricity）为必填项");
        if (cElectricity == null) throw new IllegalArgumentException("C相电流（cElectricity）为必填项");
        if (totalPower == null) throw new IllegalArgumentException("总功率（totalPower）为必填项");

        // 2. 字段长度/范围校验（Float(3,2)：总3位+2位小数；Float(4,2)：总4位+2位小数）
        validateFloatRange(aVoltage, 0.00f, 999.99f, "A相电压", 2);
        validateFloatRange(bVoltage, 0.00f, 999.99f, "B相电压", 2);
        validateFloatRange(cVoltage, 0.00f, 999.99f, "C相电压", 2);
        validateFloatRange(aElectricity, 0.00f, 999.99f, "A相电流", 2);
        validateFloatRange(bElectricity, 0.00f, 999.99f, "B相电流", 2);
        validateFloatRange(cElectricity, 0.00f, 999.99f, "C相电流", 2);
        validateFloatRange(totalPower, 0.00f, 9999.99f, "总功率", 2);

        // 3. 非必填字段校验（存在时才校验）
        if (line1TEMP != null) validateFloatRange(line1TEMP, -99.99f, 99.99f, "线温1", 2);
        if (line2TEMP != null) validateFloatRange(line2TEMP, -99.99f, 99.99f, "线温2", 2);
        if (line3TEMP != null) validateFloatRange(line3TEMP, -99.99f, 99.99f, "线温3", 2);
        if (line4TEMP != null) validateFloatRange(line4TEMP, -99.99f, 99.99f, "线温4", 2);
        if (leakageCurrent != null) validateFloatRange(leakageCurrent, 0.00f, 9999.99f, "剩余电流", 2);
    }

    /**
     * 辅助方法：校验Float类型的范围和小数位
     * @param value 字段值
     * @param min 最小值
     * @param max 最大值
     * @param fieldName 字段名称
     * @param maxDecimal 最大小数位数
     */
    private void validateFloatRange(Float value, float min, float max, String fieldName, int maxDecimal) {
        // 范围校验
        if (value < min || value > max) {
            throw new IllegalArgumentException(fieldName + "（" + fieldName.toLowerCase() + "）超出范围[" + min + "~" + max + "]，当前值：" + value);
        }
        // 小数位校验
        String str = String.valueOf(value);
        if (str.contains(".")) {
            int decimalLen = str.split("\\.")[1].length();
            if (decimalLen > maxDecimal) {
                throw new IllegalArgumentException(fieldName + "（" + fieldName.toLowerCase() + "）小数位不能超过" + maxDecimal + "位，当前值：" + value);
            }
        }
    }
}
