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

import java.util.List;

/**
 * 已解析的信息体基接口。按 {@code <协议+版本>.<数据类型>} 严格分组：
 *
 * <ul>
 *   <li>{@link Gb32960V2016} —— GB/T 32960.3-2016 附录 B 表 B.10~B.20
 *   <li>{@link Gb32960V2025} —— GB/T 32960.3-2025 §7.2.4 表 10~27
 *   <li>{@link GuangdongFc} —— 广东燃料电池汽车示范应用城市群综合监管平台规范 v1.0
 *   <li>{@link Raw} —— 未实现 parser 的原始字节兜底
 * </ul>
 *
 * <p>哪怕同一个数据类型在两个版本字段一致（如 Engine 5 字节固定布局），也按规则
 * 复制成两份 record，绝不跨版本共用 record 类型，以便消费方在 instanceof / switch
 * 时能严格区分数据来源。
 *
 * <p>异常值约定：
 * <ul>
 *   <li>单字节：{@code 0xFE} 异常 / {@code 0xFF} 无效
 *   <li>双字节：{@code 0xFFFE} 异常 / {@code 0xFFFF} 无效
 *   <li>四字节：{@code 0xFFFFFFFE} 异常 / {@code 0xFFFFFFFF} 无效
 * </ul>
 * 对外 record 使用 {@link Double} / {@link Integer} 等装箱类型，异常或无效时设为
 * {@code null}。
 */
public sealed interface InfoBlock
        permits InfoBlock.Gb32960V2016,
                InfoBlock.Gb32960V2025,
                InfoBlock.GuangdongFc,
                InfoBlock.Raw {

    InfoBlockType type();

    // ========================================================================
    // GB/T 32960.3-2016
    // ========================================================================

    /** GB/T 32960.3-2016 附录 B 定义的全部信息体类型。 */
    sealed interface Gb32960V2016 extends InfoBlock
            permits Gb32960V2016.Vehicle,
                    Gb32960V2016.DriveMotor,
                    Gb32960V2016.FuelCell,
                    Gb32960V2016.Engine,
                    Gb32960V2016.Position,
                    Gb32960V2016.Extreme,
                    Gb32960V2016.Alarm,
                    Gb32960V2016.Voltage,
                    Gb32960V2016.Temperature {

        /** 0x01 整车数据。固定 20 字节（含加速/制动踏板）。 */
        record Vehicle(
                Integer vehicleState,
                Integer chargingState,
                Integer runningMode,
                Double speedKmh,
                Double totalMileageKm,
                Double totalVoltageV,
                Double totalCurrentA,
                Integer socPercent,
                Integer dcDcStatus,
                Integer gearRaw,
                Integer insulationResistanceKohm,
                Integer acceleratorPedal,
                Integer brakePedal
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.VEHICLE; }
        }

        /** 0x02 驱动电机数据。变长。每电机 12 字节（rpm 偏移 20000，torque 2 字节偏移 20000）。 */
        record DriveMotor(List<Motor> motors) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.DRIVE_MOTOR; }

            public record Motor(
                    Integer serialNo,
                    Integer state,
                    Integer controllerTempC,
                    Integer rpm,
                    Double torqueNm,
                    Integer motorTempC,
                    Double controllerInputVoltageV,
                    Double controllerDcCurrentA
            ) {}
        }

        /** 0x03 燃料电池数据（2016 版字段顺序，含 N×探针温度 1B）。变长。 */
        record FuelCell(
                Double fcVoltageV,
                Double fcCurrentA,
                Double hydrogenConsumptionKgPer100km,
                List<Integer> probeTempC,
                Double maxHydrogenSystemTempC,
                Integer maxHydrogenSystemTempProbeId,
                Double maxHydrogenConcentrationPercent,
                Integer maxHydrogenConcentrationProbeId,
                Double maxHydrogenPressureMpa,
                Integer maxHydrogenPressureProbeId,
                Integer hvDcDcStatus
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.FUEL_CELL_V2016; }
        }

        /** 0x04 发动机数据。固定 5 字节。 */
        record Engine(
                Integer engineState,
                Integer crankshaftRpm,
                Double fuelConsumptionRate
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.ENGINE; }
        }

        /** 0x05 车辆位置数据。固定 9 字节。 */
        record Position(
                int statusFlag,
                double longitude,
                double latitude
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.POSITION_V2016; }
        }

        /** 0x06 动力蓄电池极值数据。固定 14 字节。 */
        record Extreme(
                Integer maxCellVoltageSubSysNo,
                Integer maxCellVoltageCellId,
                Double maxCellVoltageV,
                Integer minCellVoltageSubSysNo,
                Integer minCellVoltageCellId,
                Double minCellVoltageV,
                Integer maxTempSubSysNo,
                Integer maxTempProbeId,
                Integer maxTempC,
                Integer minTempSubSysNo,
                Integer minTempProbeId,
                Integer minTempC
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.EXTREME_V2016; }
        }

        /** 0x07 报警数据。变长（4 个故障代码列表）。 */
        record Alarm(
                Integer maxLevel,
                long generalAlarmFlag,
                List<Long> batteryFaults,
                List<Long> motorFaults,
                List<Long> engineFaults,
                List<Long> otherFaults
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.ALARM_V2016; }
        }

        /** 0x08 可充电储能装置电压数据。变长。PoC 仅保留汇总。 */
        record Voltage(
                int subSystemCount,
                double maxCellVoltageV,
                double minCellVoltageV,
                double totalVoltageV
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.VOLTAGE_V2016; }
        }

        /** 0x09 可充电储能装置温度数据。变长。 */
        record Temperature(
                int subSystemCount,
                int maxTempC,
                int minTempC
        ) implements Gb32960V2016 {
            @Override public InfoBlockType type() { return InfoBlockType.TEMPERATURE_V2016; }
        }
    }

    // ========================================================================
    // GB/T 32960.3-2025
    // ========================================================================

    /** GB/T 32960.3-2025 §7.2.4 定义的全部信息体类型。 */
    sealed interface Gb32960V2025 extends InfoBlock
            permits Gb32960V2025.Vehicle,
                    Gb32960V2025.DriveMotor,
                    Gb32960V2025.FuelCell,
                    Gb32960V2025.Engine,
                    Gb32960V2025.Position,
                    Gb32960V2025.Alarm,
                    Gb32960V2025.MinParallelVoltage,
                    Gb32960V2025.BatteryTemperature,
                    Gb32960V2025.FuelCellStack,
                    Gb32960V2025.SuperCapacitor,
                    Gb32960V2025.SuperCapacitorExtreme {

        /** 0x01 整车数据。固定 18 字节（删除加速/制动踏板）。 */
        record Vehicle(
                Integer vehicleState,
                Integer chargingState,
                Integer runningMode,
                Double speedKmh,
                Double totalMileageKm,
                Double totalVoltageV,
                Double totalCurrentA,
                Integer socPercent,
                Integer dcDcStatus,
                Integer gearRaw,
                Integer insulationResistanceKohm
        ) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.VEHICLE; }
        }

        /** 0x02 驱动电机数据。变长。每电机 14 字节（rpm 偏移 32000，torque 4 字节偏移 20000）。 */
        record DriveMotor(List<Motor> motors) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.DRIVE_MOTOR; }

            public record Motor(
                    Integer serialNo,
                    Integer state,
                    Integer controllerTempC,
                    Integer rpm,
                    Double torqueNm,
                    Integer motorTempC,
                    Double controllerInputVoltageV,
                    Double controllerDcCurrentA
            ) {}
        }

        /** 0x03 燃料电池发动机及车载氢系统数据。固定 13 字节。 */
        record FuelCell(
                Double maxHydrogenSystemTempC,
                Integer maxHydrogenSystemTempProbeId,
                Double maxHydrogenConcentrationPercent,
                Integer maxHydrogenConcentrationProbeId,
                Double maxHydrogenPressureMpa,
                Integer maxHydrogenPressureProbeId,
                Integer hvDcDcStatus,
                Integer remainingHydrogenPercent,
                Integer hvDcDcControllerTempC
        ) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.FUEL_CELL_V2025; }
        }

        /** 0x04 发动机数据。固定 5 字节。字段同 2016 版。 */
        record Engine(
                Integer engineState,
                Integer crankshaftRpm,
                Double fuelConsumptionRate
        ) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.ENGINE; }
        }

        /** 0x05 车辆位置数据。固定 10 字节（多坐标系字节）。 */
        record Position(
                int statusFlag,
                int coordSystem,
                double longitude,
                double latitude
        ) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.POSITION_V2025; }
        }

        /** 0x06 报警数据。变长（4 个故障代码列表 + 通用报警故障等级列表）。 */
        record Alarm(
                Integer maxLevel,
                long generalAlarmFlag,
                List<Long> batteryFaults,
                List<Long> motorFaults,
                List<Long> engineFaults,
                List<Long> otherFaults,
                List<GeneralAlarmEntry> generalAlarmLevels
        ) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.ALARM_V2025; }

            /** 通用报警故障等级列表项（2 字节）：bit 对应表 24 位序号，level 为故障等级。 */
            public record GeneralAlarmEntry(int bit, int level) {}
        }

        /** 0x07 动力蓄电池最小并联单元电压数据。变长。 */
        record MinParallelVoltage(int subSystemCount, List<Pack> packs) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.MIN_PARALLEL_VOLTAGE_V2025; }

            /** totalUnits 是车端声明数量；frameVoltages 是本帧实际解析出的完整电压值。 */
            public record Pack(
                    int packNo,
                    Double packVoltageV,
                    Double packCurrentA,
                    int totalUnits,
                    List<Double> frameVoltages
            ) {}
        }

        /** 0x08 动力蓄电池温度数据。变长。 */
        record BatteryTemperature(int subSystemCount, List<Pack> packs) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.BATTERY_TEMPERATURE_V2025; }

            /** probeCount 是车端声明数量；probeTempsC 是本帧实际解析出的温度值。 */
            public record Pack(int packNo, int probeCount, List<Integer> probeTempsC) {}
        }

        /** 0x30 燃料电池电堆数据。变长（2025 标准）。 */
        record FuelCellStack(int stackCount, List<Stack> stacks) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.FUEL_CELL_STACK; }

            public record Stack(
                    int stackNo,
                    Double voltageV,
                    Double currentA,
                    // 标准字段名写 pressure，协议比例按 kPa 命名，避免与 2016 Mpa 字段混淆。
                    Double hydrogenInletPressureKpa,
                    Double airInletPressureKpa,
                    Integer airInletTempC,
                    List<Integer> coolantOutletProbeTempsC
            ) {}
        }

        /** 0x31 超级电容器数据。变长。 */
        record SuperCapacitor(
                int systemNo,
                Double totalVoltageV,
                Double totalCurrentA,
                List<Double> cellVoltages,
                List<Integer> probeTempsC
        ) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.SUPER_CAPACITOR; }
        }

        /** 0x32 超级电容器极值数据。固定 18 字节。 */
        record SuperCapacitorExtreme(
                Integer maxVoltageSystemNo,
                Integer maxVoltageCellId,
                Double maxCellVoltageV,
                Integer minVoltageSystemNo,
                Integer minVoltageCellId,
                Double minCellVoltageV,
                Integer maxTempSystemNo,
                Integer maxTempProbeId,
                Integer maxTempC,
                Integer minTempSystemNo,
                Integer minTempProbeId,
                Integer minTempC
        ) implements Gb32960V2025 {
            @Override public InfoBlockType type() { return InfoBlockType.SUPER_CAPACITOR_EXTREME; }
        }
    }

    // ========================================================================
    // 广东燃料电池汽车示范应用城市群综合监管平台规范 v1.0（基于 GB/T 32960.3-2016 帧头）
    // ========================================================================

    /** 广东燃料电池汽车示范应用规范定义的扩展信息体（typeCode 0x30~0x34、0x80）+ 同 peer 的厂商私有 TLV。 */
    sealed interface GuangdongFc extends InfoBlock
            permits GuangdongFc.Stack,
                    GuangdongFc.Auxiliary,
                    GuangdongFc.DcDc,
                    GuangdongFc.AirConditioner,
                    GuangdongFc.VehicleInfo,
                    GuangdongFc.DemoExtension,
                    GuangdongFc.VendorTlv {

        /** 0x30 燃料电池电堆数据（§7.2.3.4 表 13/14）。变长。 */
        record Stack(int stackCount, List<Item> stacks) implements GuangdongFc {
            @Override public InfoBlockType type() { return InfoBlockType.GD_FC_STACK; }

            public record Item(
                    Integer engineWorkState,
                    Integer stackWaterOutletTempC,
                    Double  hydrogenInletPressureKpa,
                    Double  airInletPressureKpa,
                    Integer airInletTempC,
                    Integer maxCellVoltageId,
                    Integer minCellVoltageId,
                    Double  maxCellVoltageV,
                    Double  minCellVoltageV,
                    Double  avgCellVoltageV,
                    Integer cellCount,
                    Integer frameCellStart,
                    Integer frameCellCount,
                    List<Double> frameCellVoltagesV
            ) {}
        }

        /** 0x31 辅助系统数据（§7.2.3.5 表 15/16）。变长。 */
        record Auxiliary(int subSystemCount, List<Subsystem> subsystems) implements GuangdongFc {
            @Override public InfoBlockType type() { return InfoBlockType.GD_FC_AUXILIARY; }

            public record Subsystem(
                    Double airCompressorMotorVoltageV,
                    Integer airCompressorPowerKw,
                    Double hydrogenPumpMotorVoltageV,
                    Integer hydrogenPumpPowerKw,
                    Double waterPumpVoltageV,
                    Double ptcVoltageV,
                    Integer ptcPowerKw,
                    Double lowVoltageBatteryVoltageV
            ) {}
        }

        /** 0x32 DC/DC（燃料电池系统）数据（§7.2.3.6 表 17）。固定 9 字节。 */
        record DcDc(
                Double  inputVoltageV,
                Double  inputCurrentA,
                Double  outputVoltageV,
                Double  outputCurrentA,
                Integer controllerTempC
        ) implements GuangdongFc {
            @Override public InfoBlockType type() { return InfoBlockType.GD_FC_DCDC; }
        }

        /** 0x33 空调数据（§7.2.3.7 表 18）。固定 5 字节。 */
        record AirConditioner(
                Integer status,
                Integer powerKw,
                Double  compressorInputVoltageV
        ) implements GuangdongFc {
            @Override public InfoBlockType type() { return InfoBlockType.GD_FC_AIR_CONDITIONER; }
        }

        /** 0x34 车辆信息数据（§7.2.3.8 表 19）。固定 7 字节。 */
        record VehicleInfo(
                Integer collisionAlarm,
                Integer ambientTempC,
                Double  ambientPressureKpa,
                Double  hydrogenMassKg
        ) implements GuangdongFc {
            @Override public InfoBlockType type() { return InfoBlockType.GD_FC_VEHICLE_INFO; }
        }

        /** 0x80 燃料电池汽车示范应用数据扩展（§7.2.3.14 表 27）。 */
        record DemoExtension(
                Integer stackTempC,
                Double  airCompressorVoltageV,
                Double  airCompressorCurrentA,
                Double  hydrogenPumpVoltageV,
                Double  hydrogenPumpCurrentA
        ) implements GuangdongFc {
            @Override public InfoBlockType type() { return InfoBlockType.GD_FC_DEMO_EXTENSION; }
        }

        /**
         * 厂商私有 TLV 块兜底容器。当对端在广东规范之外又下发了一个未公开的 typeCode
         * （目前线上观察到 {@code 0x83}），但该块明显是 TLV 格式（type(1) + length(2) +
         * value(N)）时，本 record 保留原始字节直到对端提供正式协议文档为止。
         *
         * <p>关键在于对应的 {@code GdFcVendorTlvBlockParser} 严格按 length 字段消费字节，
         * 因此 BodyParser 主循环在该块之后**仍能继续解析其它信息体**，不会被吞光。
         *
         * @param typeCode       触发的 typeCode（保留以便诊断/分类）
         * @param declaredLength TLV 的 length 字段值（payload 字节数）
         * @param payload        原始 payload 字节，长度 = declaredLength
         */
        record VendorTlv(int typeCode, int declaredLength, byte[] payload) implements GuangdongFc {
            @Override public InfoBlockType type() { return InfoBlockType.GD_FC_VENDOR_TLV; }
        }
    }

    // ========================================================================
    // Raw / Unknown
    // ========================================================================

    /**
     * 尚未实现 Parser 的原始信息体（含自定义 0x80~0xFE），保留字节透传到冷存。
     *
     * @param typeCode 触发兜底时的真实信息体类型字节，便于诊断未知段或确认 parser 漂移落点
     * @param type     枚举形态，目前固定 {@link InfoBlockType#RAW}（保留字段为后续真正分类预留）
     * @param bytes    自该未知 type 字节之后到 body 结尾的剩余原始字节
     */
    record Raw(int typeCode, InfoBlockType type, byte[] bytes) implements InfoBlock {}
}
