package com.lingniu.ingest.protocol.gb32960.codec.parser.v2025;

import com.lingniu.ingest.protocol.gb32960.codec.InfoBlockParser;
import com.lingniu.ingest.protocol.gb32960.codec.ValueDecoder;
import com.lingniu.ingest.protocol.gb32960.model.InfoBlock;
import com.lingniu.ingest.protocol.gb32960.model.ProtocolVersion;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * 动力蓄电池最小并联单元电压数据 (0x07) —— GB/T 32960.3-2025 §7.2.4.2。变长。
 * 2016 版 0x07 为报警，由 v2016 包处理。
 */
public final class MinParallelVoltageV2025BlockParser implements InfoBlockParser {

    @Override public ProtocolVersion version() { return ProtocolVersion.V2025; }
    @Override public int typeCode() { return 0x07; }
    @Override public int fixedLength() { return -1; }

    @Override
    public InfoBlock parse(ByteBuffer buf) {
        int subCount = buf.get() & 0xFF;
        List<InfoBlock.Gb32960V2025.MinParallelVoltage.Pack> packs = new ArrayList<>(subCount);
        for (int i = 0; i < subCount; i++) {
            int packNo = buf.get() & 0xFF;
            Double voltage = ValueDecoder.scaledU16(buf, 0.1);
            Double current = ValueDecoder.scaledU16WithOffset(buf, 0.1, -3000.0);
            int totalUnits = buf.getShort() & 0xFFFF;
            List<Double> frameVoltages = new ArrayList<>(totalUnits);
            // 每个最小并联单元电压占 2 字节；不足时只读完整单元，避免半个值污染后续解析。
            int safeCount = Math.min(totalUnits, buf.remaining() / 2);
            for (int k = 0; k < safeCount; k++) {
                frameVoltages.add((buf.getShort() & 0xFFFF) * 0.001);
            }
            packs.add(new InfoBlock.Gb32960V2025.MinParallelVoltage.Pack(
                    packNo, voltage, current, totalUnits, frameVoltages));
        }
        return new InfoBlock.Gb32960V2025.MinParallelVoltage(subCount, packs);
    }
}
