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

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

import java.nio.charset.StandardCharsets;

/**
 * 电池其他数据包
 */
@Getter
@Setter
@ToString
@EqualsAndHashCode(callSuper = true)
public class BatteryOtherData extends RequestData {


    /**
     * 累计充电电量
     * <p>
     *  单位：kwh
     *  偏移量：0
     *  数值范围：0-2E+07
     *  比例：1
     *  data type: unit32
     * </p>
     */
    private int totalChargeEnergy;

    /**
     * 累计放电电量
     * <p>
     *  单位：kwh
     *  偏移量：0
     *  数值范围：0-2E+07
     *  比例：1
     *  data type: unit32
     * </p>
     */
    private int totalDischargeEnergy;


    /**
     * 单次充电电量
     * <p>
     *  单位：kwh
     * 偏移量：0
     * 数值范围：0-6553.5
     * 比例：0.1
     * data type: unit16
     * </p>
     */
    private int singleChargeEnergy;

    /**
     * BMS 允许的脉冲放电电流(瞬时电流)
     * <p>
     *  单位：A
     * 偏移量：0
     * 数值范围：0-6553.5
     * 比例：0.1
     *  data type: unit16
     * </p>
     */
    private int bmsAllowDischargeCurrent;

    /**
     * BMS 允许的脉冲回充电流(瞬时电流)
     * <p>
     *  单位：A
     * 偏移量：0
     * 数值范围：0-6553.5
     * 比例：0.1
     *  data type: unit16
     * </p>
     */
    private int bmsAllowChargeBackCurrent;

    /**
     * BMS 允许的持续回充电流(燃料电池或 PHEV才有)
     * <p>
     *  单位：A
     * 偏移量：0
     * 数值范围：0-6553.5
     * 比例：0.1
     *  data type: unit16
     * </p>
     */
    private int bmsAllowChargeBackCurrent2;

    /**
     * BMS 允许的持续放电电流
     * <p>
     *  单位：A
     * 偏移量：0
     * 数值范围：0-6553.5
     * 比例：0.1
     *  data type: unit16
     * </p>
     */
    private int bmsAllowDischargeCurrent2;

    /**
     * 充电继电器请求
     * <p>
     *  0 "require contactor
     * open" 1 "require
     * contactor close" 2
     * "Reserved" 3
     * "Reserved"
     *  data type: unit8
     * </p>
     */
    private byte chargeRelayRequest;

    /**
     * 加热正继电器请求
     * <p>
     *  0 "require contactor
     * open" 1 "require
     * contactor close" 2
     * "Reserved" 3
     * "Reserved"
     *  data type: unit8
     * </p>
     */
    private byte heatPositiveRelayRequest;

    /**
     * 加热负继电器请求
     * <p>
     *  0 "require contactor
     * open" 1 "require
     * contactor close" 2
     * "Reserved" 3
     * "Reserved"
     *  data type: unit8
     * </p>
     */
    private byte heatNegativeRelayRequest;

    /**
     * 主负继电器请求
     * <p>
     *  0 "require contactor
     * open" 1 "require
     * contactor close" 2
     * "Reserved" 3
     * "Reserved"
     *  data type: unit8
     * </p>
     */
    private byte mainNegativeRelayRequest;

    /**
     * 绝缘禁止请求
     * <p>
     *  0 "forbid insulation
     * detection" 1 "allow
     * insulation detection" 2
     * "Reserved" 3
     * "Reserved"
     *  data type: unit8
     * </p>
     */
    private byte insulationForbiddenRequest;

    /**
     * 主负继电器线圈状态
     * <p>
     *  0 "coil opened" 1 "coil
     * closed" 2 "Reserved" 3
     * "Reserved"
     *  data type: unit8
     * </p>
     */
    private byte mainNegativeRelayCoilStatus;

    /**
     *
     * 备用1
     * <br /> data type: int8
     */
    private byte reserved1;

    /**
     *
     * 备用2
     * <br /> data type: int8
     */
    private byte reserved2;

    /**
     * 电池箱号
     * <p>
     *  单位：
     * 偏移量：0
     * 数值范围：0-255
     * 比例：1
     * data type: uint8
     * </p>
     */
    private short batteryBoxNumber;

    /**
     * 探测器启动灭火弹类型
     * <p>
     *  0 "保留" 1"保留" 2 "
     * 自动：火情 4 级，上
     * 级设备控制启动" 3 "
     * 自动：火情 4 级，探
     * 测器自动检测启动"4"
     * 手动：强制控制，上
     * 级设备启动"5"手动：
     * 强制控制，探测器自
     * 检测启动"6"探测器失
     * 控启动"7"其他启动
     * "255"探测器无灭火器
     * 或子阀门控制时，在
     * 虚拟控制灭火弹，告
     * 知上级设备应备份数
     * 据"
     * data type: uint8
     * </p>
     */
    private short fireExtinguisherType;

    /**
     * 火情级别
     * <p>
     * 0"Normal" 1 "Level 1
     * Fault" 2 "Level 2
     * Fault" 3 "Level 3
     * Fault" 4 "Level 4
     * Fault"
     * </p>
     * <br /> data type: uint8
     */
    private byte fireLevel;

    /**
     * 故障码
     * <p>
     *  0"正常" 1 "灭火器已
     * 启动" 2 "传感器故障"
     * 3 "硬件故障"
     * </p>
     * <br /> data type: uint8
     */
    private byte faultCode;

    /**
     * 子阀打开或关闭命令
     * <p>
     *  1 "子阀打开" 2 "子阀
     * 关闭" 3 "子阀等待开
     * 启"
     * </p>
     * <br /> data type: uint8
     */
    private byte valveCommand;

    /**
     * 灭火故障码
     * <br /> data type: uint8
     */
    private byte extinguisherFaultCode;

    /**
     *
     * 备用3
     * <br /> data type: int8
     */
    private byte reserved3;

    /**
     *
     * 报文RollingCounter
     * <br /> data type: int8
     */
    private byte rollingCounter;

    /**
     * 电池资产归属公司编码
     * <br /> data type: Ascii
     */
    private String ownershipCompanyCode;

    /**
     * 电池运营公司编码
     * <br /> data type: Ascii
     */
    private String operationCompanyCode;

    /**
     * 累计馈电电量
     * <p>
     *     单位：kwh
     * 偏移量：0
     * 数值范围：0-2E+07
     * 比例：0.1
     * </p>
     * <br /> data type: uint32
     */
    private int totalFeedPower;

    /**
     * 支路序号
     * <br /> data type: unit8
     */
    private short branchNumber;


    /**
     * Current of No.1 Branch in this frame (Send 0xFFFF if the voltage value is invailid)
     * <p>
     *  单位：A
     * 偏移量：0
     * 数值范围：0-6553.5
     * 比例：0.1
     * data type: uint16
     * </p>
     */
    private int branch1Current;

    /**
     * Current of No.2 Branch in this frame (Send 0xFFFF if the voltage value is invailid)
     * <p>
     *  单位：A
     * 偏移量：0
     * 数值范围：0-6553.5
     * 比例：0.1
     * data type: uint16
     * </p>
     */
    private int branch2Current;

    /**
     * 累计换电电量
     * <p>
     *  单位：kwh
     * 偏移量：0
     * 数值范围：0-2E+07
     * 比例：0.1
     * </p>
     * <br /> data type: uint32
     */
    private int totalExchangeEnergy;

    /**
     * 备用4
     * <br /> data type: int8
     */
    private byte reserved4;

    /**
     * 备用5
     * <br /> data type: int8
     */
    private byte reserved5;

    /**
     * 备用6
     * <br /> data type: int8
     */
    private byte reserved6;



    /**
     *
     * @param byteBuf
     */


    @Override
    public void encode(ByteBuf byteBuf)
    {
        byteBuf.writeInt(totalChargeEnergy);
        byteBuf.writeInt(totalDischargeEnergy);
        byteBuf.writeShort(singleChargeEnergy);
        byteBuf.writeShort(bmsAllowDischargeCurrent);
        byteBuf.writeShort(bmsAllowChargeBackCurrent);
        byteBuf.writeShort(bmsAllowChargeBackCurrent2);
        byteBuf.writeShort(bmsAllowDischargeCurrent2);
        byteBuf.writeByte(chargeRelayRequest);
        byteBuf.writeByte(heatPositiveRelayRequest);
        byteBuf.writeByte(heatNegativeRelayRequest);
        byteBuf.writeByte(mainNegativeRelayRequest);
        byteBuf.writeByte(insulationForbiddenRequest);
        byteBuf.writeByte(mainNegativeRelayCoilStatus);
        byteBuf.writeByte(reserved1);
        byteBuf.writeByte(reserved2);
        byteBuf.writeByte(batteryBoxNumber);
        byteBuf.writeByte(fireExtinguisherType);
        byteBuf.writeByte(fireLevel);
        byteBuf.writeByte(faultCode);
        byteBuf.writeByte(valveCommand);
        byteBuf.writeByte(extinguisherFaultCode);
        byteBuf.writeByte(reserved3);
        byteBuf.writeByte(rollingCounter);
        ByteBufUtil.WriteString(byteBuf, ownershipCompanyCode, ChargerConstants.COMPANY_CODE_LENGTH, "0");
        ByteBufUtil.WriteString(byteBuf, operationCompanyCode, ChargerConstants.COMPANY_CODE_LENGTH, "0");
        byteBuf.writeInt(totalFeedPower);
        byteBuf.writeByte(branchNumber);
        byteBuf.writeShort(branch1Current);
        byteBuf.writeShort(branch2Current);
        byteBuf.writeInt(totalExchangeEnergy);
        byteBuf.writeByte(reserved4);
        byteBuf.writeByte(reserved5);
        byteBuf.writeByte(reserved6);
        byteBuf.writeByte(getEnd());
    }

    @Override
    public void decode(ByteBuf byteBuf)
    {
        totalChargeEnergy = byteBuf.readInt();
        if(totalChargeEnergy < 0) {
            totalChargeEnergy = 0;
        }
        totalDischargeEnergy = byteBuf.readInt();
        if(totalDischargeEnergy < 0) {
            totalChargeEnergy = 0;
        }
        singleChargeEnergy = byteBuf.readUnsignedShort();
        bmsAllowDischargeCurrent = byteBuf.readUnsignedShort();
        bmsAllowChargeBackCurrent = byteBuf.readUnsignedShort();
        bmsAllowChargeBackCurrent2 = byteBuf.readUnsignedShort();
        bmsAllowDischargeCurrent2 = byteBuf.readUnsignedShort();
        chargeRelayRequest = byteBuf.readByte();
        heatPositiveRelayRequest = byteBuf.readByte();
        heatNegativeRelayRequest = byteBuf.readByte();
        mainNegativeRelayRequest = byteBuf.readByte();
        insulationForbiddenRequest = byteBuf.readByte();
        mainNegativeRelayCoilStatus = byteBuf.readByte();
        reserved1 = byteBuf.readByte();
        reserved2 = byteBuf.readByte();
        batteryBoxNumber = byteBuf.readUnsignedByte();
        fireExtinguisherType = byteBuf.readUnsignedByte();
        fireLevel = byteBuf.readByte();
        faultCode = byteBuf.readByte();
        valveCommand = byteBuf.readByte();
        extinguisherFaultCode = byteBuf.readByte();
        reserved3 = byteBuf.readByte();
        rollingCounter = byteBuf.readByte();
        ownershipCompanyCode = byteBuf.readCharSequence(ChargerConstants.COMPANY_CODE_LENGTH, StandardCharsets.US_ASCII).toString();
        operationCompanyCode = byteBuf.readCharSequence(ChargerConstants.COMPANY_CODE_LENGTH, StandardCharsets.US_ASCII).toString();
        totalFeedPower = byteBuf.readInt();
        branchNumber = byteBuf.readUnsignedByte();
        branch1Current = byteBuf.readUnsignedShort();
        branch2Current = byteBuf.readUnsignedShort();
        totalExchangeEnergy = byteBuf.readInt();
        reserved4 = byteBuf.readByte();
        reserved5 = byteBuf.readByte();
        reserved6 = byteBuf.readByte();
        byteBuf.skipBytes(1);
    }

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

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