package com.lingniu.ingest.protocol.gb32960.model;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

/**
 * 通用报警标志位定义（GB/T 32960.3-2025 表 24）。4 字节 32 位位图中的每个位对应一种报警，
 * 2025 版将 2016 版 bit0-15 扩展到 bit0-27，新增了热事件、氢系统、超级电容等位定义。
 *
 * <p>"1" 表示报警，"0" 表示正常；标志维持到报警条件解除。
 */
public enum GeneralAlarmFlagBit {
    /** bit0：温度差异报警 */
    TEMP_DIFFERENCE(0),
    /** bit1：电池高温报警 */
    BATTERY_HIGH_TEMP(1),
    /** bit2：车载储能装置类型过压报警 */
    STORAGE_OVER_VOLTAGE(2),
    /** bit3：车载储能装置类型欠压报警 */
    STORAGE_UNDER_VOLTAGE(3),
    /** bit4：SOC 低报警 */
    SOC_LOW(4),
    /** bit5：最小并联单元过压报警 */
    MIN_PARALLEL_UNIT_OVER_VOLTAGE(5),
    /** bit6：最小并联单元欠压报警 */
    MIN_PARALLEL_UNIT_UNDER_VOLTAGE(6),
    /** bit7：SOC 过高报警 */
    SOC_HIGH(7),
    /** bit8：SOC 跳变报警 */
    SOC_JUMP(8),
    /** bit9：可充电储能系统不匹配报警 */
    STORAGE_MISMATCH(9),
    /** bit10：最小并联单元一致性差报警 */
    MIN_PARALLEL_UNIT_INCONSISTENT(10),
    /** bit11：绝缘电阻失效报警 */
    INSULATION_FAILURE(11),
    /** bit12：DC-DC 温度报警 */
    DCDC_TEMP(12),
    /** bit13：制动系统报警 */
    BRAKE_SYSTEM(13),
    /** bit14：DC-DC 状态报警 */
    DCDC_STATUS(14),
    /** bit15：驱动电机控制器温度报警 */
    MOTOR_CONTROLLER_TEMP(15),
    /** bit16：高压互锁状态报警 */
    HV_INTERLOCK(16),
    /** bit17：驱动电机温度报警 */
    MOTOR_TEMP(17),
    /** bit18：车载储能装置类型过充报警 */
    STORAGE_OVER_CHARGE(18),
    /** bit19：驱动电机超速报警（2025 版新增） */
    MOTOR_OVER_SPEED(19),
    /** bit20：驱动电机过流报警（2025 版新增） */
    MOTOR_OVER_CURRENT(20),
    /** bit21：超级电容过温报警（2025 版新增） */
    SUPER_CAP_OVER_TEMP(21),
    /** bit22：超级电容过压报警（2025 版新增） */
    SUPER_CAP_OVER_VOLTAGE(22),
    /** bit23：可充电储能装置热事件报警（2025 版新增，出现即为 4 级故障） */
    STORAGE_THERMAL_EVENT(23),
    /** bit24：氢气泄漏异常报警（2025 版新增） */
    HYDROGEN_LEAK(24),
    /** bit25：车载氢系统压力异常报警（2025 版新增） */
    HYDROGEN_PRESSURE_ABNORMAL(25),
    /** bit26：车载氢系统温度异常报警（2025 版新增） */
    HYDROGEN_TEMP_ABNORMAL(26),
    /** bit27：燃料电池电堆超温报警（2025 版新增） */
    FUEL_CELL_STACK_OVER_TEMP(27);

    private final int bitIndex;

    GeneralAlarmFlagBit(int bitIndex) {
        this.bitIndex = bitIndex;
    }

    public int bitIndex() {
        return bitIndex;
    }

    /** 当前位是否在 flag 中置位。 */
    public boolean isSet(long flag) {
        return (flag & (1L << bitIndex)) != 0;
    }

    /** 从 32 位标志解出所有置位的报警。 */
    public static Set<GeneralAlarmFlagBit> parse(long flag) {
        EnumSet<GeneralAlarmFlagBit> out = EnumSet.noneOf(GeneralAlarmFlagBit.class);
        for (GeneralAlarmFlagBit bit : values()) {
            if (bit.isSet(flag)) out.add(bit);
        }
        return out;
    }

    /** 作为可读 fault code 列表（形如 {@code SOC_LOW, MOTOR_TEMP}）。 */
    public static List<String> asCodeList(long flag) {
        List<String> out = new ArrayList<>();
        for (GeneralAlarmFlagBit bit : values()) {
            if (bit.isSet(flag)) out.add(bit.name());
        }
        return out;
    }
}
