package ADL200

import "fmt"

// ADL200 单相电表 Modbus 寄存器地址定义
// 参考《ADL200单相电子式电能表使用说明书 V1.2》
var (
	// ===== 电能数据 =====
	H0000 = MeterModusCmd{startAddr: 0x0000, quantity: 2, detail: "组合有功总电能"} // 4字节, 单位0.01kWh
	H0002 = MeterModusCmd{startAddr: 0x0002, quantity: 2, detail: "组合有功尖电能"} // 4字节
	H0004 = MeterModusCmd{startAddr: 0x0004, quantity: 2, detail: "组合有功峰电能"} // 4字节
	H0006 = MeterModusCmd{startAddr: 0x0006, quantity: 2, detail: "组合有功平电能"} // 4字节
	H0008 = MeterModusCmd{startAddr: 0x0008, quantity: 2, detail: "组合有功谷电能"} // 4字节
	H000A = MeterModusCmd{startAddr: 0x000A, quantity: 1, detail: "密码"}      // 2字节

	// ===== 实时数据 =====
	H000B = MeterModusCmd{startAddr: 0x000B, quantity: 1, detail: "电压"}   // 单位: 0.1V
	H000C = MeterModusCmd{startAddr: 0x000C, quantity: 1, detail: "电流"}   // 单位: 0.01A
	H000D = MeterModusCmd{startAddr: 0x000D, quantity: 1, detail: "有功功率"} // 单位: 0.001kW
	H000E = MeterModusCmd{startAddr: 0x000E, quantity: 1, detail: "无功功率"} // 单位: 0.001kvar
	H000F = MeterModusCmd{startAddr: 0x000F, quantity: 1, detail: "视在功率"} // 单位: 0.001kVA
	H0010 = MeterModusCmd{startAddr: 0x0010, quantity: 1, detail: "功率因数"} // 单位: 0.001
	H0011 = MeterModusCmd{startAddr: 0x0011, quantity: 1, detail: "频率"}   // 单位: 0.01Hz

	// ===== 时间设置 =====
	H0012 = MeterModusCmd{startAddr: 0x0012, quantity: 1, cmdType: 1, detail: "年月"} // R/W
	H0013 = MeterModusCmd{startAddr: 0x0013, quantity: 1, cmdType: 1, detail: "日时"} // R/W
	H0014 = MeterModusCmd{startAddr: 0x0014, quantity: 1, cmdType: 1, detail: "分秒"} // R/W

	// ===== 通信设置 =====
	H0015 = MeterModusCmd{startAddr: 0x0015, quantity: 1, cmdType: 1, detail: "高8位地址/低8位波特率"} // R/W
	H0016 = MeterModusCmd{startAddr: 0x0016, quantity: 1, cmdType: 1, detail: "背光时间"}         // R/W

	// ===== 历史电能 (上月) =====
	H0022 = MeterModusCmd{startAddr: 0x0022, quantity: 2, detail: "上1月组合有功总电能"} // 4字节
	H0024 = MeterModusCmd{startAddr: 0x0024, quantity: 2, detail: "上1月组合有功尖电能"}
	H0026 = MeterModusCmd{startAddr: 0x0026, quantity: 2, detail: "上1月组合有功峰电能"}
	H0028 = MeterModusCmd{startAddr: 0x0028, quantity: 2, detail: "上1月组合有功平电能"}
	H002A = MeterModusCmd{startAddr: 0x002A, quantity: 2, detail: "上1月组合有功谷电能"}
	H002C = MeterModusCmd{startAddr: 0x002C, quantity: 2, detail: "上2月组合有功总电能"}
	H002E = MeterModusCmd{startAddr: 0x002E, quantity: 2, detail: "上2月组合有功尖电能"}
	H0030 = MeterModusCmd{startAddr: 0x0030, quantity: 2, detail: "上2月组合有功峰电能"}
	H0032 = MeterModusCmd{startAddr: 0x0032, quantity: 2, detail: "上2月组合有功平电能"}
	H0034 = MeterModusCmd{startAddr: 0x0034, quantity: 2, detail: "上2月组合有功谷电能"}
	H0036 = MeterModusCmd{startAddr: 0x0036, quantity: 2, detail: "上3月组合有功总电能"}
	H0038 = MeterModusCmd{startAddr: 0x0038, quantity: 2, detail: "上3月组合有功尖电能"}
	H003A = MeterModusCmd{startAddr: 0x003A, quantity: 2, detail: "上3月组合有功峰电能"}
	H003C = MeterModusCmd{startAddr: 0x003C, quantity: 2, detail: "上3月组合有功平电能"}
	H003E = MeterModusCmd{startAddr: 0x003E, quantity: 2, detail: "上3月组合有功谷电能"}

	// ===== 状态和配置 =====
	H0045 = MeterModusCmd{startAddr: 0x0045, quantity: 1, cmdType: 1, detail: "状态"}
	// Bit0: 费率类型 0-非复费率, 1-复费率
	// Bit1: 接线方向 0-上进下出, 1-下进上出
	// Bit3: 视在功率 0-PQS, 1-RMS
	H0048 = MeterModusCmd{startAddr: 0x0048, quantity: 1, detail: "校验方式"} // 0000=无校验, 0002=偶校验

	// ===== 表号 =====
	H0049 = MeterModusCmd{startAddr: 0x0049, quantity: 1, cmdType: 1, detail: "表号低"}
	H004A = MeterModusCmd{startAddr: 0x004A, quantity: 1, cmdType: 1, detail: "表号中"}
	H004B = MeterModusCmd{startAddr: 0x004B, quantity: 1, cmdType: 1, detail: "表号高"}

	// ===== 正向有功电能 =====
	H0068 = MeterModusCmd{startAddr: 0x0068, quantity: 2, detail: "正向有功总电能"} // 4字节, 单位0.01kWh
	H006A = MeterModusCmd{startAddr: 0x006A, quantity: 2, detail: "正向有功尖电能"}
	H006C = MeterModusCmd{startAddr: 0x006C, quantity: 2, detail: "正向有功峰电能"}
	H006E = MeterModusCmd{startAddr: 0x006E, quantity: 2, detail: "正向有功平电能"}
	H0070 = MeterModusCmd{startAddr: 0x0070, quantity: 2, detail: "正向有功谷电能"}

	// ===== 反向有功��能 =====
	H0072 = MeterModusCmd{startAddr: 0x0072, quantity: 2, detail: "反向有功总电能"}
	H0074 = MeterModusCmd{startAddr: 0x0074, quantity: 2, detail: "反向有功尖电能"}
	H0076 = MeterModusCmd{startAddr: 0x0076, quantity: 2, detail: "反向有功峰电能"}
	H0078 = MeterModusCmd{startAddr: 0x0078, quantity: 2, detail: "反向有功平电能"}
	H007A = MeterModusCmd{startAddr: 0x007A, quantity: 2, detail: "反向有功谷电能"}

	// ===== 无功电能 =====
	H00B0 = MeterModusCmd{startAddr: 0x00B0, quantity: 2, detail: "当前总无功电能"} // 4字节, 单位0.01kVarh
	H00B2 = MeterModusCmd{startAddr: 0x00B2, quantity: 2, detail: "当前无功尖电能"}
	H00B4 = MeterModusCmd{startAddr: 0x00B4, quantity: 2, detail: "当前无功峰电能"}
	H00B6 = MeterModusCmd{startAddr: 0x00B6, quantity: 2, detail: "当前无功平电能"}
	H00B8 = MeterModusCmd{startAddr: 0x00B8, quantity: 2, detail: "当前无功谷电能"}
	H00BA = MeterModusCmd{startAddr: 0x00BA, quantity: 2, detail: "当前正向总无功电能"}
	H00BC = MeterModusCmd{startAddr: 0x00BC, quantity: 2, detail: "当前正向无功尖电能"}
	H00BE = MeterModusCmd{startAddr: 0x00BE, quantity: 2, detail: "当前正向无功峰电能"}
	H00C0 = MeterModusCmd{startAddr: 0x00C0, quantity: 2, detail: "当前正向无功平电能"}
	H00C2 = MeterModusCmd{startAddr: 0x00C2, quantity: 2, detail: "当前正向无功谷电能"}
	H00C4 = MeterModusCmd{startAddr: 0x00C4, quantity: 2, detail: "当前反向总无功电能"}
	H00C6 = MeterModusCmd{startAddr: 0x00C6, quantity: 2, detail: "当前反向无功尖电能"}
	H00C8 = MeterModusCmd{startAddr: 0x00C8, quantity: 2, detail: "当前反向无功峰电能"}
	H00CA = MeterModusCmd{startAddr: 0x00CA, quantity: 2, detail: "当前反向无功平电能"}
	H00CC = MeterModusCmd{startAddr: 0x00CC, quantity: 2, detail: "当前反向无功谷电能"}
)

// MeterModusCmd Modbus 寄存器命令结构体
type MeterModusCmd struct {
	startAddr uint16 // 起始地址
	quantity  uint16 // 寄存器数量
	cmdType   int    // 0: 只读, 1: 可读写
	detail    string // 描述信息
}

// SetStartAddr 设置起始地址
func (mcc *MeterModusCmd) SetStartAddr(s uint16) {
	mcc.startAddr = s
}

// GetStartAddr 获取起始地址
func (mcc *MeterModusCmd) GetStartAddr() uint16 {
	return mcc.startAddr
}

// SetQuantity 设置寄存器数量
func (mcc *MeterModusCmd) SetQuantity(q uint16) {
	mcc.quantity = q
}

// GetQuantity 获取寄存器数量
func (mcc *MeterModusCmd) GetQuantity() uint16 {
	return mcc.quantity
}

// SetCmdType 设置命令类型
func (mcc *MeterModusCmd) SetCmdType(t int) {
	mcc.cmdType = t
}

// GetCmdType 获取命令类型
func (mcc *MeterModusCmd) GetCmdType() int {
	return mcc.cmdType
}

// Read 读取寄存器数据
func (mmc *MeterModusCmd) Read(commUid string, addr byte) ([]uint16, error) {
	return readCmd(commUid, addr, mmc.startAddr, mmc.quantity, "读取"+mmc.detail)
}

// Write 写入寄存器数据
func (mmc *MeterModusCmd) Write(commUid string, addr byte, data []uint16) error {
	if mmc.cmdType == 0 {
		return nil
	}
	return writeCmd(commUid, addr, mmc.startAddr, data, "写入"+mmc.detail)
}

// GetHistoricalMonthAddress 获取历史月份电能的起始地址
// month: 1-3 (上1月到上3月)
func GetHistoricalMonthAddress(month int) (*MeterModusCmd, error) {
	if month < 1 || month > 3 {
		return nil, fmt.Errorf("invalid month value: %d (valid range 1-3)", month)
	}
	// 上1月: 0x0022, 上2月: 0x002C, 上3月: 0x0036
	address := 0x0022 + uint16((month-1)*10)
	MMC := &MeterModusCmd{startAddr: address, quantity: 10, detail: fmt.Sprintf("上%d月组合有功电能", month)}
	return MMC, nil
}
