package com.pwt.netty.common.charger.client;

import com.pwt.netty.common.charger.RequestData;
import io.netty.buffer.ByteBuf;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * 电池状态数据包
 */
@Getter
@Setter
@ToString
@EqualsAndHashCode(callSuper = true)
public class BatteryStatusData extends RequestData {


    /**
     * 绝缘检测仪工作状态
     * <br/>（0 "Selfcheck" 1"working" 2 "stopwork" 3 "equipmentfailure"）
     * <br/>data type: int8
     * */
    private byte insulationStatus;

    /** 绝缘故障等级
     * <br/>0 "Normal" 1 "Level 1-Light fault" 2 "Level 2-More severe fault" 3 "Level3-Most severe fault"
     * <br/>data type:　int8
     * */
    private byte insulationFaultLevel;

    /**
     * 正极绝缘值
     * <br/>单位：kohm
     * <br/>偏移量：0
     * <br/>数值范围：0-60000
     * <br/>data type: uint16
     * */
    private int positiveInsulation;

    /**
     * 负极绝缘值
     * <br/>单位：kohm
     * <br/>偏移量：0
     * <br/>数值范围：0-60000
     * <br/>data type: uint16
     * */
    private int negativeInsulation;

    /**
     * 备用0
     * <br/>data type: single
     */
    private float reserved0;

    /**
     * 电池包额定容量
     * <br/>单位：Ah
     * <br/>偏移量：0
     * <br/>数值范围：0-6553.5
     * <br/>比例：0.1
     * <br/>data type: uint16
     */
    private int batteryRatedCapacity;

    /**
     * 电池包额定电压
     * <br/>单位：V
     * <br/>偏移量：0
     * <br/>数值范围：0-6553.5
     * <br/>比例：0.1
     * <br/>data type: uint16
     */
    private int batteryRatedVoltage;

    /**
     * 电池包额定总能量
     * <br/>单位：kwh
     * <br/>偏移量：0
     * <br/>数值范围：0-6553.5
     * <br/>比例：0.1
     * <br/>data type: uint16
     */
    private int batteryRatedEnergy;

    /**
     * 电池类型
     * <br/> 1 "铅酸电池 Lead-acid battery" 2 "镍氢电池NI-MH Battery" 3 "磷酸铁锂电池 LEP" 4 "锰酸锂电池" 5 "钴酸锂电池" 6 "三元材料电池 NCM" 7 "聚合物锂离子电池 Polymer li-ion battery" 8 "钛酸锂电池" 9 "超级电容Super-capaciyor" 10 "Reserved" 11 "Reserved" 12 "Reserved" 13 "Reserved" 14 "燃料电池 Fuel battery" 15 "其他车载储能装置"
     * <br/>data type: int8
     */
    private byte batteryType;

    /**
     * 电池冷却方式
     * <br/>0 "Other cooling mode" 1 "Natural cooling" 2 "Fan cooling" 3 "Water cooling"
     * <br/>data type: int8
     */
    private byte batteryCoolingMode;

    /**
     * 电池厂家
     * <br/>1 "CATL" 2 "Li Shen" 3 "MGL" 4 "SAMSUN" 5 "LG" 6 "GUOXUAN HIGH_TECH" 7 "SUNWODA" 8 "Others"
     * <br/>data type: int8
     */
    private byte batteryManufacturer;

    /**
     * 通讯协议版本高位
     * <br/>比例：1
     * <br/>data type: byte
     */
    private byte protocolVersionHigh;

    /**
     * 通讯协议版本低位
     * <br/>比例：1
     * <br/>data type: byte
     */
    private byte protocolVersionLow;

    /**
     * 电池系统中CSC总的数目
     * <br/>单位：
     * <br/>偏移量：0
     * <br/>数值范围：0-255
     * <br/>比例：1
     * <br/>data type: uint8
     */
    private short cscTotalNumber;

    /**
     * PACK中单体电芯的总数目
     * <br/>单位：
     * <br/>偏移量：0
     * <br/>数值范围：0-65535
     * <br/>比例：1
     * <br/>data type: uint16
     */
    private int cellTotalNumber;

    /**
     * PACK 中电芯温度点(探针)的总数目
     * <p>
     * 单位：
     * 偏移量：0
     * 数值范围：0-255
     * 比例：1
     * </p>
     * data type: uint8
     */
    private short cellProbeTotalNumber;

    /**
     * 电池系统高压支路数
     * <p>
     * 单位：
     * 偏移量：0
     * 数值范围：0-5
     * 比例：1
     * </p>
     * data type: uint8
     */
    private short batteryHighVoltageBranchNumber;

    /**
     * 电池系统单支路电芯数
     * <p>
     * 单位：
     * 偏移量：0
     * 数值范围：0-5
     * 比例：1
     * </p>
     * data type: uint8
     */
    private short batterySingleBranchCellNumber;

    /**
     * 可充电储能系统数目
     * <p>
     * 单位：
     * 偏移量：0
     * 数值范围：0-5
     * 比例：1
     * </p>
     * data type: uint8
     */
    private short batterySystemNumber;

    /**
     * 可充电储能系统序号
     * <p>
     * 单位：
     * 偏移量：0
     * 数值范围：0-5
     * 比例：1
     * </p>
     * data type: uint8
     */
    private short batterySystemSerialNumber;

    /**
     * PACK 可用电压上限
     * <p>
     *     单位：V
     *     偏移量：0
     *     数值范围：0-6553.5
     *     比例：0.1
     * </p>
     * data type: uint16
     */
    private int batteryAvailableVoltageUpperLimit;


    /**
     * PACK 可用电压下限
     * <p>
     *     单位：V
     *     偏移量：0
     *     数值范围：0-6553.5
     *     比例：0.1
     * </p>
     * data type: uint16
     */
    private int batteryAvailableVoltageLowerLimit;

    /**
     * PACK 可用最高SOC
     * <p>
     *     单位：%
     *     偏移量：0
     *     数值范围：0-102
     *     比例：0.4
     * </p>
     * data type: uint8
     */
    private short batteryAvailableSOCUpperLimit;

    /**
     * PACK 可用最低SOC
     * <p>
     *     单位：%
     *     偏移量：0
     *     数值范围：0-102
     *     比例：0.4
     * </p>
     * data type: uint8
     */
    private short batteryAvailableSOCLowerLimit;

    /**
     * PACK 可用温度上限
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * data type: int8
     */
    private byte batteryAvailableTemperatureUpperLimit;

    /**
     * PACK 可用温度下限
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * data type: int8
     */
    private byte batteryAvailableTemperatureLowerLimit;

    /**
     * 单体电压起始帧
     * <br />data type: int16
     */
    private short cellVoltageStartFrame;

    /**
     * 单体电压第1帧
     * <p>
     *     单位：V
     *     偏移量：0
     *     数值范围：0-65.535
     *     比例：0.001
     * </p>
     * <br />data type: uint16
     */
    private int cellVoltageFrame1;

    /**
     * 单体电压第2帧, 不满发0xFFFF
     * <p>
     *     单位：V
     *     偏移量：0
     *     数值范围：0-65.535
     *     比例：0.001
     * </p>
     * <br />data type: uint16
     */
    private int cellVoltageFrame2;

    /**
     * 单体电压第3帧, 不满发0xFFFF
     * <p>
     *     单位：V
     *     偏移量：0
     *     数值范围：0-65.535
     *     比例：0.001
     * </p>
     * <br />data type: uint16
     */
    private int cellVoltageFrame3;

    /**
     * 单体温度起始帧
     * <br />data type: int16
     */
    private short cellTemperatureStartFrame;

    /**
     * 单体温度第1帧
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * <br />data type: int8
     */
    private byte cellTemperatureFrame1;

    /**
     * 单体温度第2帧, 不满发0xFF
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * <br />data type: int8
     */
    private byte cellTemperatureFrame2;

    /**
     * 单体温度第3帧, 不满发0xFF
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * <br />data type: int8
     */
    private byte cellTemperatureFrame3;

    /**
     * 单体温度第4帧, 不满发0xFF
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * <br />data type: int8
     */
    private byte cellTemperatureFrame4;

    /**
     * 单体温度第5帧, 不满发0xFF
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * <br />data type: int8
     */
    private byte cellTemperatureFrame5;

    /**
     * 单体温度第6帧, 不满发0xFF
     * <p>
     *     单位：℃
     *     偏移量：-40
     *     数值范围：-40-215
     *     比例：1
     * </p>
     * <br />data type: int8
     */
    private byte cellTemperatureFrame6;


    /**
     * 最⾼单体动⼒蓄电池电压
     * <p>
     *     单位: v
     *     偏移量：0
     *     数值范围：0~24
     *     比例：0.01
     * </p>
     * <br />data type: uint16
     */
    private int cellMaxVoltage;

    /**
     * 最⾼单体动⼒蓄电池电压所在编号
     * <p>
     *     单位:
     *     偏移量：1
     *     数值范围：1~256
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int cellMaxVoltageNo;

    /**
     * 最低单体动⼒蓄电池电压
     * <p>
     *     单位: v
     *     偏移量：0
     *     数值范围：0~24
     *     比例：0.01
     * </p>
     * <br />data type: uint16
     */
    private int cellMinVoltage;

    /**
     * 最低单体动⼒蓄电池电压所在编号
     * <p>
     *     单位:
     *     偏移量：1
     *     数值范围：1~256
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int cellMinVoltageNo;

    /**
     * 最高动力蓄电池温度
     * <p>
     *     单位: ℃
     *     偏移量：-50
     *     数值范围：-50~200
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int maxBatteryTemperature;

    /**
     * 最高温度检测点编号
     * <p>
     *     单位:
     *     偏移量：1
     *     数值范围：1~128
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int maxTemperatureCheckPointNo;

    /**
     * 最低动力蓄电池温度
     * <p>
     *     单位: ℃
     *     偏移量：-50
     *     数值范围：-50~200
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int minBatteryTemperature;

    /**
     * 最低温度检测点编号
     * <p>
     *     单位:
     *     偏移量：1
     *     数值范围：1~128
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int minTemperatureCheckPointNo;

    /**
     * 电池组生产日期：年
     * <p>
     *     单位:
     *     偏移量：1985
     *     数值范围：1985~2235
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int batteryProductionYear;

    /**
     * 电池组生产日期：月
     * <p>
     *     单位:
     *     偏移量：0
     *     数值范围：1~12
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int batteryProductionMonth;

    /**
     * 电池组生产日期：日
     * <p>
     *     单位:
     *     偏移量：0
     *     数值范围：1~31
     *     比例：1
     * </p>
     * <br />data type: uint8
     */
    private int batteryProductionDay;


    /**
     * 备用1
     * <br/>data type: int32
     */
    private int reserved1;

    @Override
    public void encode(ByteBuf byteBuf)
    {
        byteBuf.writeByte(insulationStatus);
        byteBuf.writeByte(insulationFaultLevel);
        byteBuf.writeShort(positiveInsulation);
        byteBuf.writeShort(negativeInsulation);
        byteBuf.writeFloat(reserved0);
        byteBuf.writeShort(batteryRatedCapacity);
        byteBuf.writeShort(batteryRatedVoltage);
        byteBuf.writeShort(batteryRatedEnergy);
        byteBuf.writeByte(batteryType);
        byteBuf.writeByte(batteryCoolingMode);
        byteBuf.writeByte(batteryManufacturer);
        byteBuf.writeByte(protocolVersionHigh);
        byteBuf.writeByte(protocolVersionLow);
        byteBuf.writeByte(cscTotalNumber);
        byteBuf.writeShort(cellTotalNumber);
        byteBuf.writeByte(cellProbeTotalNumber);
        byteBuf.writeByte(batteryHighVoltageBranchNumber);
        byteBuf.writeByte(batterySingleBranchCellNumber);
        byteBuf.writeByte(batterySystemNumber);
        byteBuf.writeByte(batterySystemSerialNumber);
        byteBuf.writeShort(batteryAvailableVoltageUpperLimit);
        byteBuf.writeShort(batteryAvailableVoltageLowerLimit);
        byteBuf.writeByte(batteryAvailableSOCUpperLimit);
        byteBuf.writeByte(batteryAvailableSOCLowerLimit);
        byteBuf.writeByte(batteryAvailableTemperatureUpperLimit);
        byteBuf.writeByte(batteryAvailableTemperatureLowerLimit);
        byteBuf.writeShort(cellVoltageStartFrame);
        byteBuf.writeShort(cellVoltageFrame1);
        byteBuf.writeShort(cellVoltageFrame2);
        byteBuf.writeShort(cellVoltageFrame3);
        byteBuf.writeShort(cellTemperatureStartFrame);
        byteBuf.writeByte(cellTemperatureFrame1);
        byteBuf.writeByte(cellTemperatureFrame2);
        byteBuf.writeByte(cellTemperatureFrame3);
        byteBuf.writeByte(cellTemperatureFrame4);
        byteBuf.writeByte(cellTemperatureFrame5);
        byteBuf.writeByte(cellTemperatureFrame6);
        byteBuf.writeShort(cellMaxVoltage);
        byteBuf.writeByte(cellMaxVoltageNo);
        byteBuf.writeShort(cellMinVoltage);
        byteBuf.writeByte(cellMinVoltageNo);
        byteBuf.writeByte(maxBatteryTemperature);
        byteBuf.writeByte(maxTemperatureCheckPointNo);
        byteBuf.writeByte(minBatteryTemperature);
        byteBuf.writeByte(minTemperatureCheckPointNo);
        byteBuf.writeByte(batteryProductionYear);
        byteBuf.writeByte(batteryProductionMonth);
        byteBuf.writeByte(batteryProductionDay);

        byteBuf.writeInt(reserved1);
        byteBuf.writeByte(getEnd());
    }

    @Override
    public void decode(ByteBuf byteBuf)
    {

        insulationStatus = byteBuf.readByte();
        insulationFaultLevel = byteBuf.readByte();
        positiveInsulation = byteBuf.readUnsignedShort();
        negativeInsulation = byteBuf.readUnsignedShort();
        reserved0 = byteBuf.readFloat();
        batteryRatedCapacity = byteBuf.readUnsignedShort();
        batteryRatedVoltage = byteBuf.readUnsignedShort();
        batteryRatedEnergy = byteBuf.readUnsignedShort();
        batteryType = byteBuf.readByte();
        batteryCoolingMode = byteBuf.readByte();
        batteryManufacturer = byteBuf.readByte();
        protocolVersionHigh = byteBuf.readByte();
        protocolVersionLow = byteBuf.readByte();
        cscTotalNumber = byteBuf.readUnsignedByte();
        cellTotalNumber = byteBuf.readUnsignedShort();
        cellProbeTotalNumber = byteBuf.readUnsignedByte();
        batteryHighVoltageBranchNumber = byteBuf.readUnsignedByte();
        batterySingleBranchCellNumber = byteBuf.readUnsignedByte();
        batterySystemNumber = byteBuf.readUnsignedByte();
        batterySystemSerialNumber = byteBuf.readUnsignedByte();
        batteryAvailableVoltageUpperLimit = byteBuf.readUnsignedShort();
        batteryAvailableVoltageLowerLimit = byteBuf.readUnsignedShort();
        batteryAvailableSOCUpperLimit = byteBuf.readUnsignedByte();
        batteryAvailableSOCLowerLimit = byteBuf.readUnsignedByte();
        batteryAvailableTemperatureUpperLimit = byteBuf.readByte();
        batteryAvailableTemperatureLowerLimit = byteBuf.readByte();
        cellVoltageStartFrame = byteBuf.readShort();
        cellVoltageFrame1 = byteBuf.readUnsignedShort();
        cellVoltageFrame2 = byteBuf.readUnsignedShort();
        cellVoltageFrame3 = byteBuf.readUnsignedShort();
        cellTemperatureStartFrame = byteBuf.readShort();
        cellTemperatureFrame1 = byteBuf.readByte();
        cellTemperatureFrame2 = byteBuf.readByte();
        cellTemperatureFrame3 = byteBuf.readByte();
        cellTemperatureFrame4 = byteBuf.readByte();
        cellTemperatureFrame5 = byteBuf.readByte();
        cellTemperatureFrame6 = byteBuf.readByte();

        cellMaxVoltage = byteBuf.readUnsignedShort();
        cellMaxVoltageNo = byteBuf.readUnsignedByte();
        cellMinVoltage = byteBuf.readUnsignedShort();
        cellMinVoltageNo = byteBuf.readUnsignedByte();
        maxBatteryTemperature = byteBuf.readUnsignedByte();
        maxTemperatureCheckPointNo = byteBuf.readUnsignedByte();
        minBatteryTemperature = byteBuf.readUnsignedByte();
        minTemperatureCheckPointNo = byteBuf.readUnsignedByte();
        batteryProductionYear = byteBuf.readUnsignedByte();
        batteryProductionMonth = byteBuf.readUnsignedByte();
        batteryProductionDay = byteBuf.readUnsignedByte();

        reserved1 = byteBuf.readInt();
        // skip end flag
        byteBuf.skipBytes(1);
    }

    @Override
    public int getProtocolLength() {
        return 71;
    }

    @Override
    public byte getEnd() {
        return 0x16;
    }

    public String getBatteryTypeStr() {
        switch (this.batteryType) {
            case 1:
                return "铅酸电池" ;
            case 2:
                return "镍氢电池" ;
            case 3:
                return "磷酸铁锂电池" ;
            case 4:
                return "锰酸锂电池" ;
            case 5:
                return "钴酸锂电池" ;
            case 6:
                return "三元材料电池" ;
            case 7:
                return "聚合物锂离子电池" ;
            case 8:
                return "钛酸锂电池" ;
            case 9:
                return "超级电容"  ;
            case 14:
                return "燃料电池" ;
            case 15:
                return "其他车载储能装置";
            default:
                return "未知";
        }
    }

    public String getBatteryFactory() {
        switch (this.batteryManufacturer) {
            case 1:
                return "CATL" ;
            case 2:
                return "Li Shen" ;
            case 3:
                return "MGL" ;
            case 4:
                return "SAMSUN" ;
            case 5:
                return "LG";
            case 6:
                return "GUOXUAN HIGH_TECH" ;
            case 7:
                return "SUNWODA" ;
            case 8:
                return "Others";
            default:
                return "Unknown";
        }
    }
}
