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

import com.pwt.netty.common.charger.RequestData;
import com.pwt.netty.handler.codec.exceptions.ProtocolException;
import com.pwt.netty.util.MessageUtil;
import io.netty.buffer.ByteBuf;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;


@Getter
@Setter
@ToString
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class ChargerChargeStatusData extends RequestData {

    /**
     * 电池编码长度
     */
    public static final int BATTERY_SN_LENGTH = 24;

    /**
     * 充电状态 0：待机；1：充电；2：停止；3：故障
     **/
    private int chargingStatus;

    /**
     * 输出电压
     **/
    private float outputVoltage;

    /**
     * 输出电流
     **/
    private float outputCurrent;

    /**
     * 需求电压
     **/
    private float demandVoltage;

    /**
     * 需求电流
     **/
    private float demandCurrent;

    /**
     * 已充电时间(分钟)
     **/
    private int chargedMinutes;

    /**
     * 当前soc
     **/
    private int SOC;

    /**
     * 整车动力蓄电池当前电池电压
     **/
    private float batteryVoltage;

    /**
     * 电池温度
     **/
    private int batteryTemperature;

    /**
     * 剩余充电时间(分钟)
     **/
    private int remainingChargingTime;

    /**
     * 接插件状态 1：接入；2：未接入
     **/
    private byte connectorStatus;

    /**
     * 电池组编码
     **/
    private String batteryNumber;

    /**
     * 充电次数
     **/
    private int chargingTimes;

    /**
     * 电池包累计行驶总里程 （若无该值填 0）
     **/
    private int totalMileage;

    /**
     * 电池包累计电量 （10kw/h,若无该值填 0）
     **/
    private int totalElectricity;

    /**
     * 充电模式 1：室内充电 2：应急充电
     */
    private byte chargeType;


    @Override
    public void encode(ByteBuf byteBuf) {
        byteBuf.writeByte(chargingStatus);
        byteBuf.writeFloat(outputVoltage);
        byteBuf.writeFloat(outputCurrent);
        byteBuf.writeFloat(demandVoltage);
        byteBuf.writeFloat(demandCurrent);
        byteBuf.writeShort(chargedMinutes);
        byteBuf.writeByte(SOC);
        byteBuf.writeFloat(batteryVoltage);
        byteBuf.writeInt(batteryTemperature);
        byteBuf.writeShort(remainingChargingTime);
        byteBuf.writeByte(connectorStatus);
        byteBuf.writeBytes(getBatteryNumber().getBytes(StandardCharsets.US_ASCII));
        byteBuf.writeShort(chargingTimes);
        byteBuf.writeInt(totalMileage);
        byteBuf.writeShort(totalElectricity);
        byteBuf.writeByte(chargeType);
        byteBuf.writeByte(getEnd());
    }

    @Override
    public void decode(ByteBuf byteBuf) throws ProtocolException, UnsupportedEncodingException {
//        if (byteBuf != null) {
//            log.info("充电机原始报文：{}", MessageUtil.convertByteBufToString(byteBuf));
//        }
        chargingStatus = byteBuf.readUnsignedByte();
        outputVoltage = byteBuf.readFloat();
        outputCurrent = byteBuf.readFloat();
        demandVoltage = byteBuf.readFloat();
        demandCurrent = byteBuf.readFloat();
        chargedMinutes = byteBuf.readUnsignedShort();
        SOC = byteBuf.readUnsignedByte();
        batteryVoltage = byteBuf.readFloat();
        batteryTemperature = byteBuf.readInt();
        remainingChargingTime = byteBuf.readUnsignedShort();
        connectorStatus = byteBuf.readByte();

        // 没有获取到sn时，全为\0,获取到之后，SN会补足长度
        batteryNumber = byteBuf.readCharSequence(BATTERY_SN_LENGTH, StandardCharsets.US_ASCII).toString().replaceAll("(\0|\\s)", "");
        chargingTimes = byteBuf.readUnsignedShort();
        totalMileage = byteBuf.readInt();
        totalElectricity = byteBuf.readUnsignedShort();
        chargeType = byteBuf.readByte();
        byteBuf.skipBytes(1);
    }

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

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

    public String getBatteryNumber() {
        if (batteryNumber == null) {
            return StringUtils.repeat("0", BATTERY_SN_LENGTH);
        }
        return batteryNumber;
    }
}
