/*
 * 文 件 名:  ChargingHandshakeFrame
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  充电握手帧
 * 修 改 人:  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;

/**
 * 充电握手帧 (0x15)
 * GBT-27930 充电桩与BMS充电握手阶段报文
 *
 * @author lvwenbin
 * @version [版本号, 2025/12/22]
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ChargingHandshakeFrame extends BaseFrame {
    
    /**
     * 交易流水号 (BCD码 16字节)
     */
    private String transactionNo;
    
    /**
     * 桩编号 (BCD码 7字节)
     */
    private String pileCode;
    
    /**
     * 枪号 (BCD码 1字节)
     */
    private String gunNo;
    
    /**
     * BMS通信协议版本号 (BIN 3字节)
     */
    private byte[] bmsProtocolVersion;
    
    /**
     * BMS电池类型 (BIN 1字节)
     * 01H:铅酸电池;02H:氢电池;03H:磷酸铁锂电池;04H:锰酸锂电池;
     * 05H:钴酸锂电池;06H:三元材料电池;07H:聚合物锂离子电池;08H:钛酸锂电池;FFH:其他
     */
    private byte bmsBatteryType;
    
    /**
     * BMS整车动力蓄电池系统额定容量 (BIN 2字节)
     * 0.1 Ah/位，0 Ah偏移量
     */
    private int bmsRatedCapacity;
    
    /**
     * BMS整车动力蓄电池系统额定总电压 (BIN 2字节)
     * 0.1V/位，0V偏移量
     */
    private int bmsRatedVoltage;
    
    /**
     * BMS电池生产厂商名称 (BIN 4字节)
     */
    private byte[] bmsManufacturer;
    
    /**
     * BMS电池组序号 (BIN 4字节)
     */
    private byte[] bmsBatterySerialNo;
    
    /**
     * BMS电池组生产日期年 (BIN 1字节)
     * 1985年偏移量
     */
    private int bmsProductionYear;
    
    /**
     * BMS电池组生产日期月 (BIN 1字节)
     */
    private int bmsProductionMonth;
    
    /**
     * BMS电池组生产日期日 (BIN 1字节)
     */
    private int bmsProductionDay;
    
    /**
     * BMS电池组充电次数 (BIN 3字节)
     */
    private int bmsChargingCount;
    
    /**
     * BMS电池组产权标识 (BIN 1字节)
     * 0：租赁；1：车自有
     */
    private byte bmsOwnership;
    
    /**
     * 预留位 (BIN 1字节)
     */
    private byte reserved;
    
    /**
     * BMS车辆识别码VIN (BIN 17字节)
     */
    private String vin;
    
    /**
     * BMS软件版本号 (BIN 8字节)
     */
    private byte[] bmsSoftwareVersion;
    
    @Override
    public byte getFrameType() {
        return ProtocolConstants.FRAME_TYPE_CHARGING_HANDSHAKE;
    }
    
    @Override
    protected void encodeBody(ByteBuf buf) {
        ByteUtils.writeBcd(buf, transactionNo, 16);
        ByteUtils.writeBcd(buf, pileCode, 7);
        ByteUtils.writeBcd(buf, gunNo, 1);
        buf.writeBytes(bmsProtocolVersion != null ? bmsProtocolVersion : new byte[3]);
        buf.writeByte(bmsBatteryType);
        buf.writeShortLE(bmsRatedCapacity);
        buf.writeShortLE(bmsRatedVoltage);
        buf.writeBytes(bmsManufacturer != null ? bmsManufacturer : new byte[4]);
        buf.writeBytes(bmsBatterySerialNo != null ? bmsBatterySerialNo : new byte[4]);
        buf.writeByte(bmsProductionYear);
        buf.writeByte(bmsProductionMonth);
        buf.writeByte(bmsProductionDay);
        // 充电次数3字节，低位在前
        buf.writeByte(bmsChargingCount & 0xFF);
        buf.writeByte((bmsChargingCount >> 8) & 0xFF);
        buf.writeByte((bmsChargingCount >> 16) & 0xFF);
        buf.writeByte(bmsOwnership);
        buf.writeByte(reserved);
        ByteUtils.writeAscii(buf, vin, 17);
        buf.writeBytes(bmsSoftwareVersion != null ? bmsSoftwareVersion : new byte[8]);
    }
    
    @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.bmsProtocolVersion = new byte[3];
        buf.readBytes(this.bmsProtocolVersion);
        this.bmsBatteryType = buf.readByte();
        this.bmsRatedCapacity = buf.readShortLE() & 0xFFFF;
        this.bmsRatedVoltage = buf.readShortLE() & 0xFFFF;
        this.bmsManufacturer = new byte[4];
        buf.readBytes(this.bmsManufacturer);
        this.bmsBatterySerialNo = new byte[4];
        buf.readBytes(this.bmsBatterySerialNo);
        this.bmsProductionYear = buf.readByte() & 0xFF;
        this.bmsProductionMonth = buf.readByte() & 0xFF;
        this.bmsProductionDay = buf.readByte() & 0xFF;
        // 充电次数3字节，低位在前
        this.bmsChargingCount = (buf.readByte() & 0xFF) 
            | ((buf.readByte() & 0xFF) << 8)
            | ((buf.readByte() & 0xFF) << 16);
        this.bmsOwnership = buf.readByte();
        this.reserved = buf.readByte();
        this.vin = ByteUtils.readAscii(buf, 17);
        this.bmsSoftwareVersion = new byte[8];
        buf.readBytes(this.bmsSoftwareVersion);
    }
    
    /**
     * 获取额定容量(Ah)
     */
    public double getRatedCapacityValue() {
        return bmsRatedCapacity / 10.0;
    }
    
    /**
     * 获取额定电压(V)
     */
    public double getRatedVoltageValue() {
        return bmsRatedVoltage / 10.0;
    }
    
    /**
     * 获取实际生产年份
     */
    public int getActualProductionYear() {
        return bmsProductionYear + 1985;
    }
    
    /**
     * 获取电池类型描述
     */
    public String getBatteryTypeDesc() {
        switch (bmsBatteryType) {
            case 0x01: return "铅酸电池";
            case 0x02: return "氢电池";
            case 0x03: return "磷酸铁锂电池";
            case 0x04: return "锰酸锂电池";
            case 0x05: return "钴酸锂电池";
            case 0x06: return "三元材料电池";
            case 0x07: return "聚合物锂离子电池";
            case 0x08: return "钛酸锂电池";
            default: return "其他";
        }
    }
    
    /**
     * 获取完整枪号
     */
    public String getFullGunNo() {
        return pileCode + gunNo;
    }
    
    @Override
    public String toString() {
        return String.format(
            "ChargingHandshakeFrame[transNo=%s, pile=%s, gun=%s, vin=%s, battery=%s, capacity=%.1fAh, voltage=%.1fV]",
            transactionNo, pileCode, gunNo, vin, getBatteryTypeDesc(),
            getRatedCapacityValue(), getRatedVoltageValue());
    }
}
