package com.lingniu.ingest.eventhistory;

import java.util.List;

/**
 * GB32960 字段字典。
 *
 * <p>字典是前端字段选择器、中文表头、Tooltip、枚举/位图展示的单一来源。
 * 字段 key 必须和 {@link Gb32960DecodedFrameService} 输出的 block data 路径一致；
 * 支持点号路径和数组投影路径，例如 {@code GD_FC_STACK.stacks.frameCellVoltagesV}。
 */
public final class Gb32960FieldDictionary {

    private Gb32960FieldDictionary() {
    }

    public static List<Packet> packets() {
        return PACKETS;
    }

    private static final List<Packet> PACKETS = List.of(
            // 标准 32960 字段优先放前面；广东燃料电池扩展字段放后面，方便前端按常用程度展示。
            packet("VEHICLE", "整车数据", "GB/T 32960 整车运行状态、车速、里程、电压、电流、SOC 等核心字段。",
                    field("vehicleState", "车辆状态", "", "车辆运行、停止等状态编码。",
                            mappings(
                                    mapping("01", "1", "启动", "车辆处于可行驶启动状态。"),
                                    mapping("02", "2", "熄火", "车辆处于熄火状态。"),
                                    mapping("03", "3", "其他", "车辆处于其他状态。"),
                                    mapping("FE", "254", "异常", "协议异常值。"),
                                    mapping("FF", "255", "无效", "协议无效值。"))),
                    field("chargingState", "充电状态", "", "车辆充电状态编码。",
                            mappings(
                                    mapping("01", "1", "停车充电", "车辆停车充电。"),
                                    mapping("02", "2", "行驶充电", "车辆行驶充电。"),
                                    mapping("03", "3", "未充电", "车辆未充电。"),
                                    mapping("04", "4", "充电完成", "车辆充电完成。"),
                                    mapping("FE", "254", "异常", "协议异常值。"),
                                    mapping("FF", "255", "无效", "协议无效值。"))),
                    field("runningMode", "运行模式", "", "纯电、混动、燃料电池等运行模式编码。",
                            mappings(
                                    mapping("01", "1", "纯电", "纯电驱动模式。"),
                                    mapping("02", "2", "混合动力", "混合动力驱动模式。"),
                                    mapping("03", "3", "燃料电池", "燃料电池驱动模式。"),
                                    mapping("FE", "254", "异常", "协议异常值。"),
                                    mapping("FF", "255", "无效", "协议无效值。"))),
                    field("speedKmh", "车速", "km/h", "车辆当前速度。"),
                    field("totalMileageKm", "累计里程", "km", "车辆累计行驶里程。"),
                    field("totalVoltageV", "总电压", "V", "动力系统总电压。"),
                    field("totalCurrentA", "总电流", "A", "动力系统总电流。"),
                    field("socPercent", "SOC", "%", "动力电池荷电状态。"),
                    field("dcDcStatus", "DC/DC 状态", "", "DC/DC 工作状态编码。",
                            mappings(
                                    mapping("01", "1", "工作", "DC/DC 处于工作状态。"),
                                    mapping("02", "2", "断开", "DC/DC 处于断开状态。"),
                                    mapping("FE", "254", "异常", "协议异常值。"),
                                    mapping("FF", "255", "无效", "协议无效值。"))),
                    field("gearRaw", "挡位原始值", "", "挡位、驱动力和制动力组合原始编码。"),
                    field("insulationResistanceKohm", "绝缘电阻", "kOhm", "高压系统绝缘电阻。"),
                    field("acceleratorPedal", "加速踏板行程", "%", "2016 版字段，加速踏板开度。"),
                    field("brakePedal", "制动踏板状态", "%", "2016 版字段，制动踏板状态或开度。")),
            packet("DRIVE_MOTOR", "驱动电机数据", "GB/T 32960 驱动电机控制器和电机运行状态。",
                    field("motors.serialNo", "驱动电机序号", "", "电机编号。"),
                    field("motors.state", "驱动电机状态", "", "电机工作状态编码。",
                            mappings(
                                    mapping("01", "1", "耗电", "驱动电机耗电。"),
                                    mapping("02", "2", "发电", "驱动电机发电。"),
                                    mapping("03", "3", "关闭", "驱动电机关闭。"),
                                    mapping("04", "4", "准备", "驱动电机准备。"),
                                    mapping("FE", "254", "异常", "协议异常值。"),
                                    mapping("FF", "255", "无效", "协议无效值。"))),
                    field("motors.controllerTempC", "控制器温度", "C", "驱动电机控制器温度。"),
                    field("motors.rpm", "转速", "rpm", "驱动电机转速。"),
                    field("motors.torqueNm", "转矩", "N.m", "驱动电机输出转矩。"),
                    field("motors.motorTempC", "电机温度", "C", "驱动电机温度。"),
                    field("motors.controllerInputVoltageV", "控制器输入电压", "V", "电机控制器直流母线输入电压。"),
                    field("motors.controllerDcCurrentA", "控制器直流母线电流", "A", "电机控制器直流母线电流。")),
            packet("FUEL_CELL_V2016", "燃料电池数据（2016）", "GB/T 32960.3-2016 燃料电池电压、电流、氢耗、温度、浓度、压力等字段。",
                    field("fcVoltageV", "燃料电池电压", "V", "燃料电池系统输出电压。"),
                    field("fcCurrentA", "燃料电池电流", "A", "燃料电池系统输出电流。"),
                    field("hydrogenConsumptionKgPer100km", "氢耗", "kg/100km", "燃料电池氢气消耗率。"),
                    field("probeTempC", "探针温度", "C", "燃料电池温度探针列表。"),
                    field("maxHydrogenSystemTempC", "氢系统最高温度", "C", "氢系统最高温度。"),
                    field("maxHydrogenConcentrationPercent", "最高氢浓度", "%", "氢气浓度最高值。"),
                    field("maxHydrogenPressureMpa", "最高氢压力", "MPa", "氢系统最高压力。"),
                    field("hvDcDcStatus", "高压 DC/DC 状态", "", "燃料电池高压 DC/DC 状态。")),
            packet("POSITION_V2016", "车辆位置数据（2016）", "GB/T 32960.3-2016 定位状态和经纬度。",
                    field("statusFlag", "定位状态标志", "", "定位有效性及经纬度方向标志。",
                            mappings(
                                    mapping("bit0=0", "bit0=0", "有效定位", "定位状态有效。"),
                                    mapping("bit0=1", "bit0=1", "无效定位", "定位状态无效。"),
                                    mapping("bit1=0", "bit1=0", "北纬", "纬度方向为北纬。"),
                                    mapping("bit1=1", "bit1=1", "南纬", "纬度方向为南纬。"),
                                    mapping("bit2=0", "bit2=0", "东经", "经度方向为东经。"),
                                    mapping("bit2=1", "bit2=1", "西经", "经度方向为西经。"))),
                    field("longitude", "经度", "deg", "车辆经度。"),
                    field("latitude", "纬度", "deg", "车辆纬度。")),
            packet("POSITION_V2025", "车辆位置数据（2025）", "GB/T 32960.3-2025 定位状态、坐标系和经纬度。",
                    field("statusFlag", "定位状态标志", "", "定位有效性及经纬度方向标志。",
                            mappings(
                                    mapping("bit0=0", "bit0=0", "有效定位", "定位状态有效。"),
                                    mapping("bit0=1", "bit0=1", "无效定位", "定位状态无效。"),
                                    mapping("bit1=0", "bit1=0", "北纬", "纬度方向为北纬。"),
                                    mapping("bit1=1", "bit1=1", "南纬", "纬度方向为南纬。"),
                                    mapping("bit2=0", "bit2=0", "东经", "经度方向为东经。"),
                                    mapping("bit2=1", "bit2=1", "西经", "经度方向为西经。"))),
                    field("coordSystem", "坐标系", "", "2025 版新增坐标系编码。",
                            mappings(
                                    mapping("01", "1", "WGS84", "WGS84 坐标系。"),
                                    mapping("02", "2", "GCJ-02", "GCJ-02 坐标系。"),
                                    mapping("03", "3", "其他", "其他坐标系。"))),
                    field("longitude", "经度", "deg", "车辆经度。"),
                    field("latitude", "纬度", "deg", "车辆纬度。")),
            packet("ALARM_V2016", "报警数据（2016）", "GB/T 32960.3-2016 最高报警等级、通用报警位和故障码列表。",
                    field("maxLevel", "最高报警等级", "", "当前最高报警等级。",
                            mappings(
                                    mapping("00", "0", "无故障", "当前无报警故障。"),
                                    mapping("01", "1", "一级故障", "一级报警故障。"),
                                    mapping("02", "2", "二级故障", "二级报警故障。"),
                                    mapping("03", "3", "三级故障", "三级报警故障。"))),
                    field("generalAlarmFlag", "通用报警标志", "", "通用报警位图。"),
                    field("batteryFaults", "可充电储能装置故障码", "", "动力电池相关故障码列表。"),
                    field("motorFaults", "驱动电机故障码", "", "驱动电机相关故障码列表。"),
                    field("engineFaults", "发动机故障码", "", "发动机相关故障码列表。"),
                    field("otherFaults", "其他故障码", "", "其他故障码列表。")),
            packet("GD_FC_STACK", "广东燃料电池电堆数据", "广东燃料电池汽车数据接入规范扩展，描述电堆状态、压力、温度和单体电压分段。",
                    field("stackCount", "电堆数量", "", "本包包含的电堆数量。"),
                    field("stacks.engineWorkState", "发动机工作状态", "", "燃料电池发动机工作状态。"),
                    field("stacks.stackWaterOutletTempC", "电堆出水温度", "C", "电堆冷却水出口温度。"),
                    field("stacks.hydrogenInletPressureKpa", "氢气入口压力", "kPa", "电堆氢气入口压力。"),
                    field("stacks.airInletPressureKpa", "空气入口压力", "kPa", "电堆空气入口压力。"),
                    field("stacks.airInletTempC", "空气入口温度", "C", "电堆空气入口温度。"),
                    field("stacks.maxCellVoltageV", "单体最高电压", "V", "本电堆单体最高电压。"),
                    field("stacks.minCellVoltageV", "单体最低电压", "V", "本电堆单体最低电压。"),
                    field("stacks.avgCellVoltageV", "单体平均电压", "V", "本电堆单体平均电压。"),
                    field("stacks.cellCount", "单体总数", "", "电堆单体总数量。"),
                    field("stacks.frameCellStart", "本帧单体起始序号", "", "当前分段电压起始单体序号。"),
                    field("stacks.frameCellCount", "本帧单体数量", "", "当前分段包含的单体数量。"),
                    field("stacks.frameCellVoltagesV", "本帧单体电压列表", "V", "当前分段的单体电压数组。"),
                    field("stacks.frameCellComplete", "单体电压是否完整", "", "snapshot 合并后是否已覆盖全部单体。"),
                    field("stacks.frameCellMissingCount", "缺失单体数量", "", "snapshot 合并后仍缺失的单体数量。")),
            packet("GD_FC_DCDC", "广东燃料电池 DC/DC 数据", "广东燃料电池汽车数据接入规范扩展，描述 DC/DC 输入输出和控制器温度。",
                    field("inputVoltageV", "输入电压", "V", "DC/DC 输入电压。"),
                    field("inputCurrentA", "输入电流", "A", "DC/DC 输入电流。"),
                    field("outputVoltageV", "输出电压", "V", "DC/DC 输出电压。"),
                    field("outputCurrentA", "输出电流", "A", "DC/DC 输出电流。"),
                    field("controllerTempC", "控制器温度", "C", "DC/DC 控制器温度。")),
            packet("GD_FC_AIR_CONDITIONER", "广东燃料电池空调数据", "广东燃料电池汽车数据接入规范扩展，描述空调状态、功率和压缩机输入电压。",
                    field("status", "空调状态", "", "空调工作状态。",
                            mappings(
                                    mapping("00", "0", "关闭", "空调关闭。"),
                                    mapping("01", "1", "启动", "空调启动。"),
                                    mapping("FE", "254", "异常", "协议异常值。"),
                                    mapping("FF", "255", "无效", "协议无效值。"))),
                    field("powerKw", "空调功率", "kW", "空调消耗功率。"),
                    field("compressorInputVoltageV", "压缩机输入电压", "V", "空调压缩机输入电压。")),
            packet("GD_FC_VEHICLE_INFO", "广东燃料电池车辆信息数据", "广东燃料电池汽车数据接入规范扩展，描述碰撞报警、环境温度压力和车载氢量。",
                    field("collisionAlarm", "碰撞报警", "", "碰撞报警状态。",
                            mappings(
                                    mapping("00", "0", "无碰撞报警", "当前无碰撞报警。"),
                                    mapping("01", "1", "有碰撞报警", "当前有碰撞报警。"),
                                    mapping("FE", "254", "异常", "协议异常值。"),
                                    mapping("FF", "255", "无效", "协议无效值。"))),
                    field("ambientTempC", "环境温度", "C", "车辆环境温度。"),
                    field("ambientPressureKpa", "环境压力", "kPa", "车辆环境压力。"),
                    field("hydrogenMassKg", "车载氢量", "kg", "当前车载氢气质量。"))
    );

    private static Packet packet(String code, String nameZh, String description, Field... fields) {
        return new Packet(code, nameZh, description, List.of(fields));
    }

    private static Field field(String key, String nameZh, String unit, String description) {
        return field(key, nameZh, unit, description, List.of());
    }

    private static Field field(String key, String nameZh, String unit, String description,
                               List<ValueMapping> valueMappings) {
        return new Field(key, nameZh, unit, description, valueMappings);
    }

    private static List<ValueMapping> mappings(ValueMapping... mappings) {
        return List.of(mappings);
    }

    private static ValueMapping mapping(String code, String value, String nameZh, String description) {
        return new ValueMapping(code, value, nameZh, description);
    }

    /**
     * 一个数据包/信息体类型的字段集合，例如 VEHICLE 或 GD_FC_DCDC。
     */
    public record Packet(String code, String nameZh, String description, List<Field> fields) {
    }

    /**
     * 可查询字段定义。key 是接口查询参数使用的英文路径，nameZh/unit/description 用于前端展示。
     */
    public record Field(String key, String nameZh, String unit, String description,
                        List<ValueMapping> valueMappings) {
    }

    /**
     * 协议枚举值或位图值的展示映射。code 保留原始协议表示，value 是解析后的业务值。
     */
    public record ValueMapping(String code, String value, String nameZh, String description) {
    }
}
