/*
 * 文 件 名:  RemoteStopRespFrame
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  远程停止充电应答帧 (充电桩上报 0x35)
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/01/07
 */
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;

/**
 * 远程停止充电应答帧 (充电桩上报)
 * 帧类型: 0x35
 *
 * 消息体格式:
 * - 桩编号: 7字节 BCD码
 * - 枪号: 1字节 BCD码
 * - 停止结果: 1字节 (0x00=失败, 0x01=成功)
 * - 失败原因: 1字节
 *
 * @author lvwenbin
 * @version [版本号, 2025/01/07]
 */
public class RemoteStopRespFrame extends BaseFrame {

    /**
     * 停止结果: 成功
     */
    public static final byte RESULT_SUCCESS = 0x01;

    /**
     * 停止结果: 失败
     */
    public static final byte RESULT_FAIL = 0x00;

    /**
     * 失败原因: 无
     */
    public static final byte FAIL_REASON_NONE = 0x00;

    /**
     * 失败原因: 设备编号不匹配
     */
    public static final byte FAIL_REASON_DEVICE_MISMATCH = 0x01;

    /**
     * 失败原因: 枪未在充电
     */
    public static final byte FAIL_REASON_NOT_CHARGING = 0x02;

    /**
     * 失败原因: 其他
     */
    public static final byte FAIL_REASON_OTHER = (byte) 0xFF;

    /**
     * 桩编号 (7字节BCD码, 14位数字)
     */
    private String pileCode;

    /**
     * 枪号 (1字节BCD码, 2位数字)
     */
    private String gunNo;

    /**
     * 停止结果 (0x00=失败, 0x01=成功)
     */
    private byte stopResult;

    /**
     * 失败原因
     */
    private byte failReason;

    @Override
    public byte getFrameType() {
        return ProtocolConstants.FRAME_TYPE_REMOTE_STOP_RESP;
    }

    @Override
    protected void encodeBody(ByteBuf buf) {
        // 桩编号 7字节
        buf.writeBytes(ByteUtils.strToBcd(pileCode, 7));
        // 枪号 1字节
        buf.writeBytes(ByteUtils.strToBcd(gunNo, 1));
        // 停止结果 1字节
        buf.writeByte(stopResult);
        // 失败原因 1字节
        buf.writeByte(failReason);
    }

    @Override
    protected void decodeBody(ByteBuf buf) {
        // 桩编号 7字节
        byte[] pileCodeBytes = new byte[7];
        buf.readBytes(pileCodeBytes);
        this.pileCode = ByteUtils.bcdToStr(pileCodeBytes);

        // 枪号 1字节
        byte[] gunNoBytes = new byte[1];
        buf.readBytes(gunNoBytes);
        this.gunNo = ByteUtils.bcdToStr(gunNoBytes);

        // 停止结果 1字节
        this.stopResult = buf.readByte();

        // 失败原因 1字节
        this.failReason = buf.readByte();
    }

    /**
     * 是否成功
     */
    public boolean isSuccess() {
        return stopResult == RESULT_SUCCESS;
    }

    /**
     * 获取完整枪号 (桩编码 + 枪号)
     * @return 完整枪号，如 "3212830100010101"
     */
    public String getFullGunNo() {
        return pileCode + gunNo;
    }

    /**
     * 获取失败原因描述
     * @return 失败原因描述文字
     */
    public String getFailReasonDesc() {
        switch (failReason) {
            case FAIL_REASON_NONE:
                return "无";
            case FAIL_REASON_DEVICE_MISMATCH:
                return "设备编号不匹配";
            case FAIL_REASON_NOT_CHARGING:
                return "枪未在充电";
            case FAIL_REASON_OTHER:
                return "其他原因";
            default:
                return "未知原因(0x" + String.format("%02X", failReason) + ")";
        }
    }

    // Getters and Setters
    public String getPileCode() {
        return pileCode;
    }

    public void setPileCode(String pileCode) {
        this.pileCode = pileCode;
    }

    public String getGunNo() {
        return gunNo;
    }

    public void setGunNo(String gunNo) {
        this.gunNo = gunNo;
    }

    public byte getStopResult() {
        return stopResult;
    }

    public void setStopResult(byte stopResult) {
        this.stopResult = stopResult;
    }

    public byte getFailReason() {
        return failReason;
    }

    public void setFailReason(byte failReason) {
        this.failReason = failReason;
    }

    @Override
    public String toString() {
        return String.format("RemoteStopRespFrame[pileCode=%s, gunNo=%s, result=%s, failReason=0x%02X, seq=%d]",
            pileCode, gunNo, isSuccess() ? "成功" : "失败", failReason, getSequenceNo());
    }
}