/*
 * 文 件 名:  HeartbeatReqFrame
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  充电桩心跳包请求帧
 * 修 改 人:  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;

/**
 * 充电桩心跳包请求帧 (0x03)
 * 用于链路状态判断，10秒周期上送，3次未收到心跳包视为网络异常，需要重新登录
 *
 * @author lvwenbin
 * @version [版本号, 2025/12/22]
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class HeartbeatReqFrame extends BaseFrame {
    
    /**
     * 桩编码 (BCD码 7字节)
     */
    private String pileCode;
    
    /**
     * 枪号 (BCD码 1字节)
     */
    private String gunNo;
    
    /**
     * 枪状态 (BIN码 1字节)
     * 0x00：正常, 0x01：故障
     */
    private byte gunStatus;
    
    @Override
    public byte getFrameType() {
        return ProtocolConstants.FRAME_TYPE_HEARTBEAT_REQ;
    }
    
    @Override
    protected void encodeBody(ByteBuf buf) {
        ByteUtils.writeBcd(buf, pileCode, 7);
        ByteUtils.writeBcd(buf, gunNo, 1);
        buf.writeByte(gunStatus);
    }
    
    @Override
    protected void decodeBody(ByteBuf buf) {
        this.pileCode = ByteUtils.readBcd(buf, 7);
        this.gunNo = ByteUtils.readBcd(buf, 1);
        this.gunStatus = buf.readByte();
    }
    
    /**
     * 是否正常状态
     *
     * @return 是否正常
     */
    public boolean isNormal() {
        return gunStatus == 0x00;
    }
    
    /**
     * 获取枪状态描述
     *
     * @return 状态描述
     */
    public String getGunStatusDesc() {
        return isNormal() ? "正常" : "故障";
    }
    
    /**
     * 获取完整枪号 (桩编号+枪号)
     *
     * @return 完整枪号
     */
    public String getFullGunNo() {
        return pileCode + gunNo;
    }
    
    @Override
    public String toString() {
        return String.format("HeartbeatReqFrame[pileCode=%s, gunNo=%s, status=%s]",
            pileCode, gunNo, getGunStatusDesc());
    }
}
