/*
 * 文 件 名:  ChargingEndFrame
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  充电结束帧
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/12/22
 */
package com.ruoyi.ems.charging.model.req;

import com.ruoyi.ems.charging.model.BaseFrame;
import com.ruoyi.ems.charging.protocol.ProtocolConstants;
import com.ruoyi.ems.charging.utils.ByteUtils;
import io.netty.buffer.ByteBuf;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 充电结束帧 (0x19)
 * GBT-27930 充电桩与BMS充电结束阶段报文
 *
 * @author lvwenbin
 * @version [版本号, 2025/12/22]
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ChargingEndFrame extends BaseFrame {
    
    /**
     * 交易流水号 (BCD码 16字节)
     */
    private String transactionNo;
    
    /**
     * 桩编号 (BCD码 7字节)
     */
    private String pileCode;
    
    /**
     * 枪号 (BCD码 1字节)
     */
    private String gunNo;
    
    /**
     * BMS中止荷电状态SOC (BIN 1字节)
     * 1%/位，0%偏移量；数据范围：0~100%
     */
    private int bmsFinalSoc;
    
    /**
     * BMS动力蓄电池单体最低电压 (BIN 2字节)
     * 0.01V/位，0V偏移量；数据范围：0~24V
     */
    private int bmsMinCellVoltage;
    
    /**
     * BMS动力蓄电池单体最高电压 (BIN 2字节)
     * 0.01V/位，0V偏移量；数据范围：0~24V
     */
    private int bmsMaxCellVoltage;
    
    /**
     * BMS动力蓄电池最低温度 (BIN 1字节)
     * 1℃/位，-50℃偏移量；数据范围：-50℃~+200℃
     */
    private int bmsMinTemp;
    
    /**
     * BMS动力蓄电池最高温度 (BIN 1字节)
     * 1℃/位，-50℃偏移量；数据范围：-50℃~+200℃
     */
    private int bmsMaxTemp;
    
    /**
     * 电桩累计充电时间 (BIN 2字节)
     * 1min/位，0min偏移量；数据范围：0~600min
     */
    private int totalChargingTime;
    
    /**
     * 电桩输出能量 (BIN 2字节)
     * 0.1kWh/位，0kWh偏移量；数据范围：0~1000kWh
     */
    private int outputEnergy;
    
    /**
     * 电桩充电机编号 (BIN 4字节)
     */
    private long chargerNo;
    
    @Override
    public byte getFrameType() {
        return ProtocolConstants.FRAME_TYPE_CHARGING_END;
    }
    
    @Override
    protected void encodeBody(ByteBuf buf) {
        ByteUtils.writeBcd(buf, transactionNo, 16);
        ByteUtils.writeBcd(buf, pileCode, 7);
        ByteUtils.writeBcd(buf, gunNo, 1);
        buf.writeByte(bmsFinalSoc);
        buf.writeShortLE(bmsMinCellVoltage);
        buf.writeShortLE(bmsMaxCellVoltage);
        buf.writeByte(bmsMinTemp);
        buf.writeByte(bmsMaxTemp);
        buf.writeShortLE(totalChargingTime);
        buf.writeShortLE(outputEnergy);
        buf.writeIntLE((int) chargerNo);
    }
    
    @Override
    protected void decodeBody(ByteBuf buf) {
        this.transactionNo = ByteUtils.readBcd(buf, 16);
        this.pileCode = ByteUtils.readBcd(buf, 7);
        this.gunNo = ByteUtils.readBcd(buf, 1);
        this.bmsFinalSoc = buf.readByte() & 0xFF;
        this.bmsMinCellVoltage = buf.readShortLE() & 0xFFFF;
        this.bmsMaxCellVoltage = buf.readShortLE() & 0xFFFF;
        this.bmsMinTemp = buf.readByte() & 0xFF;
        this.bmsMaxTemp = buf.readByte() & 0xFF;
        this.totalChargingTime = buf.readShortLE() & 0xFFFF;
        this.outputEnergy = buf.readShortLE() & 0xFFFF;
        this.chargerNo = buf.readIntLE() & 0xFFFFFFFFL;
    }
    
    /**
     * 获取最低单体电压(V)
     */
    public double getMinCellVoltageValue() {
        return bmsMinCellVoltage / 100.0;
    }
    
    /**
     * 获取最高单体电压(V)
     */
    public double getMaxCellVoltageValue() {
        return bmsMaxCellVoltage / 100.0;
    }
    
    /**
     * 获取最低温度(℃)
     */
    public int getMinTempValue() {
        return bmsMinTemp - 50;
    }
    
    /**
     * 获取最高温度(℃)
     */
    public int getMaxTempValue() {
        return bmsMaxTemp - 50;
    }
    
    /**
     * 获取输出能量(kWh)
     */
    public double getOutputEnergyValue() {
        return outputEnergy / 10.0;
    }
    
    /**
     * 获取完整枪号
     */
    public String getFullGunNo() {
        return pileCode + gunNo;
    }
    
    @Override
    public String toString() {
        return String.format(
            "ChargingEndFrame[transNo=%s, pile=%s, gun=%s, soc=%d%%, energy=%.1fkWh, time=%dmin]",
            transactionNo, pileCode, gunNo, bmsFinalSoc, getOutputEnergyValue(), totalChargingTime);
    }
}
